Skip to content

Commit

Permalink
feat(notification): Support batch rate type notice
Browse files Browse the repository at this point in the history
  • Loading branch information
realth000 committed Feb 20, 2024
1 parent 5d4195c commit 1d5ed2b
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
* 楼层右下角菜单 -> 编辑。
* 一些附加选项可能需要文本编辑器支持,目前可能不完全支持。
* 暂不支持设置阅读权限和售价。
- 新增解析批量评分类型的提醒。
- 在通知页内显示已有x条相同通知被忽略。
- 支持筛选积分变更历史。
- 帖子内按页数显示分组。
Expand Down
46 changes: 46 additions & 0 deletions lib/features/notification/models/notice.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ enum NoticeType {
/// Another user rated current user's thread or post.
rate,

/// Another user rated current user's thread or post using batch task.
///
/// Usually the plugin is "Project Minerva" but do not reply on it.
batchRate,

/// Another mentioned current user in a post.
mention,

Expand Down Expand Up @@ -41,6 +46,7 @@ class Notice extends Equatable {
required this.noticeType,
required this.score,
required this.quotedMessage,
required this.taskId,
});

/// User avatar.
Expand Down Expand Up @@ -92,6 +98,11 @@ class Notice extends Equatable {
/// Comment when scoring.
final String? quotedMessage;

/// Task id of batch operation.
///
/// Only useful when NoticeType is batchRate.
final String? taskId;

/// Build a [Notice] from html node [element] :
/// div#ct > div.mn > div.bm.bw0 > div.xld.xlda > div.nts > div.cl
///
Expand All @@ -107,6 +118,7 @@ class Notice extends Equatable {

String? score;
String? quotedMessage;
String? taskId;

// score:
// <dd class="ntc_body" style="">
Expand All @@ -129,6 +141,12 @@ class Notice extends Equatable {
// 您也可以直接回复:
// <a class="lit" href="...mode=post&action=reply&tid=xxx&repquote=xxx"></a>
// </dd>
//
// batchRate:
// <dd class="ntc_body" style="">
// 您在主题 <a href="" target="_blank"> $ThreadTitle</a> 的帖子被 <a href="$UserSpace" target="_blank">$Username</a> 评分 $rate<br>
// <b>执行者:</b><a href="$UserSpace" target="_blank">$Username</a><br><b>理由:</b>$Reason<br><b>任务ID:</b>TaskID
// </dd>
final quoteNode = element.querySelector('dd.ntc_body > div.quote');
final mentionNode = element.querySelector('dd.ntc_body > blockquote');
final litNode = element.querySelector('dd.ntc_body > a.lit');
Expand All @@ -144,6 +162,13 @@ class Notice extends Equatable {
noticeType = NoticeType.invite;
} else if (element.querySelectorAll('dd.ntc_body > a').length == 1) {
noticeType = NoticeType.newFriend;
} else if (element
.querySelectorAll('dd.ntc_body > b')
.lastOrNull
?.innerText
.contains('任务ID') ??
false) {
noticeType = NoticeType.batchRate;
} else {
noticeType = NoticeType.reply;
}
Expand Down Expand Up @@ -176,6 +201,19 @@ class Notice extends Equatable {
} else if (noticeType == NoticeType.newFriend) {
username = a1Node?.firstEndDeepText();
userSpaceUrl = a1Node?.attributes['href'];
} else if (noticeType == NoticeType.batchRate) {
noticeThreadTitle = a1Node?.firstEndDeepText();
redirectUrl = a1Node?.firstHref()?.prependHost();
// Here we should use `:last-of-type` but dart html package does not
// support it, and we also dont want to use `querySelectorAll.lastOrNull`.
//
// Assume the user node is always the 5th child.
final a3Node = element.querySelector('dd.ntc_body > a:nth-child(5)');
userSpaceUrl = a3Node?.firstHref();
username = a3Node?.firstEndDeepText();
final n = element.querySelector('dd.ntc_body');
score = n?.nodes.elementAtOrNull(4)?.text?.trim().replaceFirst('评分 ', '');
taskId = n?.nodes.lastOrNull?.text?.trim();
} else {
noticeThreadTitle = a1Node?.firstEndDeepText();
redirectUrl = a1Node?.firstHref()?.prependHost();
Expand Down Expand Up @@ -205,6 +243,12 @@ class Notice extends Equatable {
debug('failed to parse new friend notice: $username, $userSpaceUrl');
return null;
}
} else if (noticeType == NoticeType.batchRate) {
if (username == null || userSpaceUrl == null || taskId == null) {
debug('failed to parse batch rate notice: '
'$username, $userSpaceUrl, $taskId');
return null;
}
} else if (username == null ||
userSpaceUrl == null ||
noticeTime == null ||
Expand All @@ -230,6 +274,7 @@ class Notice extends Equatable {
noticeType: noticeType,
score: score,
quotedMessage: quotedMessage,
taskId: taskId,
);
}

Expand All @@ -247,5 +292,6 @@ class Notice extends Equatable {
noticeType,
score,
quotedMessage,
taskId,
];
}
3 changes: 2 additions & 1 deletion lib/features/notification/view/notification_detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class _NoticeDetailPage extends State<NoticeDetailPage> {
NoticeType.rate => context.t.noticePage.noticeDetailPage.titleRate,
NoticeType.mention => context.t.noticePage.noticeDetailPage.titleMention,
NoticeType.invite ||
NoticeType.newFriend =>
NoticeType.newFriend ||
NoticeType.batchRate =>
'', // No detail page for invites, impossible.
};
return MultiBlocProvider(
Expand Down
3 changes: 2 additions & 1 deletion lib/i18n/strings.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@
"mentionBody": "mentioned you in thread",
"inviteBody": "invite you to participate in the topic $threadTitle",
"newFriendBody": "became your friend",
"ignoredSameNotice": "$count more same notice ignored"
"ignoredSameNotice": "$count more same notice ignored",
"taskID": "Task ID: $taskId"
},
"messageTab": {
"title": "Messages"
Expand Down
3 changes: 2 additions & 1 deletion lib/i18n/strings_zh-CN.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@
"mentionBody": "在帖子中提到了你",
"inviteBody": "邀请您参与话题 $threadTitle",
"newFriendBody": "和您成为了好友",
"ignoredSameNotice": "还有 $count 个相同通知被忽略"
"ignoredSameNotice": "还有 $count 个相同通知被忽略",
"taskID": "任务ID:$taskId"
},
"messageTab": {
"title": "消息"
Expand Down
3 changes: 2 additions & 1 deletion lib/i18n/strings_zh-TW.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@
"mentionBody": "在話題中提到了你",
"inviteBody": "邀請您參與話題 $threadTitle",
"newFriendBody": "和您成為好友了",
"ignoredSameNotice": "還有 $count 個相同通知被忽略"
"ignoredSameNotice": "還有 $count 個相同通知被忽略",
"taskID": "任務ID:$taskId"
},
"messageTab": {
"title": "訊息"
Expand Down
12 changes: 9 additions & 3 deletions lib/widgets/card/notice_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class NoticeCard extends StatelessWidget {

@override
Widget build(BuildContext context) {
final ignoreHintStyle = Theme.of(context)
final outlineStyle = Theme.of(context)
.textTheme
.labelMedium
?.copyWith(color: Theme.of(context).colorScheme.outline);
Expand All @@ -44,7 +44,7 @@ class NoticeCard extends StatelessWidget {
context.t.noticePage.noticeTab
.replyBody(threadTitle: notice.noticeThreadTitle ?? '-'),
),
NoticeType.rate => Column(
NoticeType.rate || NoticeType.batchRate => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
Expand All @@ -61,6 +61,12 @@ class NoticeCard extends StatelessWidget {
child: Text(notice.quotedMessage!),
),
),
if (notice.taskId != null) sizedBoxW5H5,
if (notice.taskId != null)
Text(
context.t.noticePage.noticeTab.taskID(taskId: notice.taskId!),
style: outlineStyle,
),
],
),
NoticeType.mention => Column(
Expand Down Expand Up @@ -137,7 +143,7 @@ class NoticeCard extends StatelessWidget {
Text(
context.t.noticePage.noticeTab
.ignoredSameNotice(count: notice.ignoreCount!),
style: ignoreHintStyle,
style: outlineStyle,
),
].insertBetween(sizedBoxW5H5),
),
Expand Down

0 comments on commit 1d5ed2b

Please sign in to comment.