diff --git a/lib/i18n/strings.i18n.json b/lib/i18n/strings.i18n.json index af6d915d..0e7795fb 100644 --- a/lib/i18n/strings.i18n.json +++ b/lib/i18n/strings.i18n.json @@ -160,8 +160,10 @@ "messageTab": { "title": "Messages" }, - "replyPage": { - "title": "Reply" + "noticeDetailPage": { + "titleReply": "Reply", + "titleRate": "Rate info", + "titleMention": "Reply mention" } }, "searchPage": { diff --git a/lib/i18n/strings_zh-CN.i18n.json b/lib/i18n/strings_zh-CN.i18n.json index a17c7f53..9dd123c3 100644 --- a/lib/i18n/strings_zh-CN.i18n.json +++ b/lib/i18n/strings_zh-CN.i18n.json @@ -160,8 +160,10 @@ "messageTab": { "title": "消息" }, - "replyPage": { - "title": "回复" + "noticeDetailPage": { + "titleReply": "回复", + "titleRate": "评分详情", + "titleMention": "回复提及" } }, "searchPage": { diff --git a/lib/i18n/strings_zh-TW.i18n.json b/lib/i18n/strings_zh-TW.i18n.json index e4609d11..e11d368e 100644 --- a/lib/i18n/strings_zh-TW.i18n.json +++ b/lib/i18n/strings_zh-TW.i18n.json @@ -160,8 +160,10 @@ "messageTab": { "title": "訊息" }, - "replyPage": { - "title": "回覆" + "noticeDetailPage": { + "titleReply": "回覆", + "titleRate": "評分詳情", + "titleMention": "回覆提及" } }, "searchPage": { diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 1412403b..8d9756a4 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -2,14 +2,16 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:tsdm_client/constants/url.dart'; +import 'package:tsdm_client/extensions/string.dart'; +import 'package:tsdm_client/models/notice.dart'; import 'package:tsdm_client/providers/auth_provider.dart'; import 'package:tsdm_client/routes/screen_paths.dart'; import 'package:tsdm_client/screens/forum/forum_page.dart'; import 'package:tsdm_client/screens/homepage/homepage.dart'; import 'package:tsdm_client/screens/login/login_page.dart'; import 'package:tsdm_client/screens/need_login/need_login_page.dart'; +import 'package:tsdm_client/screens/notice/notice_detail_page.dart'; import 'package:tsdm_client/screens/notice/notice_page.dart'; -import 'package:tsdm_client/screens/notice/reply_page.dart'; import 'package:tsdm_client/screens/profile/profile_page.dart'; import 'package:tsdm_client/screens/root/root.dart'; import 'package:tsdm_client/screens/search/search_page.dart'; @@ -142,7 +144,10 @@ GoRouter router(RouterRef ref) { parentNavigatorKey: _rootRouteKey, builder: (state) { final target = state.pathParameters['target']!; - return ReplyPage(url: target); + final noticeTypeIndex = + state.uri.queryParameters['noticeType']!.parseToInt()!; + return NoticeDetailPage( + url: target, noticeType: NoticeType.values[noticeTypeIndex]); }, ), AppRoute( diff --git a/lib/screens/notice/reply_page.dart b/lib/screens/notice/notice_detail_page.dart similarity index 82% rename from lib/screens/notice/reply_page.dart rename to lib/screens/notice/notice_detail_page.dart index 8e8e6a62..33b8213e 100644 --- a/lib/screens/notice/reply_page.dart +++ b/lib/screens/notice/notice_detail_page.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:tsdm_client/constants/url.dart'; import 'package:tsdm_client/generated/i18n/strings.g.dart'; +import 'package:tsdm_client/models/notice.dart'; import 'package:tsdm_client/models/post.dart'; import 'package:tsdm_client/models/reply_parameters.dart'; import 'package:tsdm_client/providers/net_client_provider.dart'; @@ -15,16 +16,23 @@ import 'package:tsdm_client/widgets/reply_bar.dart'; import 'package:universal_html/html.dart' as uh; import 'package:universal_html/parsing.dart'; -class ReplyPage extends ConsumerStatefulWidget { - const ReplyPage({required this.url, super.key}); +/// Show details for a single notice, also provides interaction: +/// * Reply to the notice if notice type is [NoticeType.reply] or [NoticeType.mention]. +class NoticeDetailPage extends ConsumerStatefulWidget { + const NoticeDetailPage({ + required this.url, + required this.noticeType, + super.key, + }); + final NoticeType noticeType; final String url; @override - ConsumerState createState() => _ReplyPageState(); + ConsumerState createState() => _NoticeDetailPage(); } -class _ReplyPageState extends ConsumerState { +class _NoticeDetailPage extends ConsumerState { final _replyBarController = ReplyBarController(); ReplyParameters? _parseParameters(uh.Document document, String tid) { @@ -113,6 +121,13 @@ class _ReplyPageState extends ConsumerState { } final postData = Post.fromPostNode(postNode); + // Only show post date (hide reply bar) if notice is rate type. + if (widget.noticeType == NoticeType.rate) { + return SingleChildScrollView( + child: PostCard(postData), + ); + } + // Parse thread id. final tidRe = RegExp(r'ptid=(?\d+)'); final tidMatch = tidRe.firstMatch(widget.url); @@ -150,10 +165,13 @@ class _ReplyPageState extends ConsumerState { @override Widget build(BuildContext context) { + final title = switch (widget.noticeType) { + NoticeType.reply => context.t.noticePage.noticeDetailPage.titleReply, + NoticeType.rate => context.t.noticePage.noticeDetailPage.titleRate, + NoticeType.mention => context.t.noticePage.noticeDetailPage.titleMention, + }; return Scaffold( - appBar: AppBar( - title: Text(context.t.noticePage.replyPage.title), - ), + appBar: AppBar(title: Text(title)), body: FutureBuilder( future: _fetchData(context), builder: (context, snapshot) { diff --git a/lib/widgets/notice_card.dart b/lib/widgets/notice_card.dart index fa6eac5f..a695306c 100644 --- a/lib/widgets/notice_card.dart +++ b/lib/widgets/notice_card.dart @@ -78,6 +78,9 @@ class NoticeCard extends ConsumerWidget { await context.pushNamed(ScreenPaths.reply, pathParameters: { 'target': notice.redirectUrl!, + }, + queryParameters: { + 'noticeType': '${notice.noticeType.index}', }); } : null,