diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0a5ee1..e20d73b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - 帖子:发帖和编辑时可设置阅读权限。 - 帖子:我的帖子页面中显示更多帖子信息。 - 帖子:我的帖子页面中修改帖子卡片布局。 +- 帖子:支持解析新人报道分区的帖子中的新人报道表格。 - 消息:现在来源于帖子中的消息会直接跳转到帖子的相应楼层,而不经过消息详情页。 - app:支持设置和使用代理。 - 默认关闭,可在设置 -> 高级 -> 启用代理中打开。 diff --git a/lib/i18n/strings.i18n.json b/lib/i18n/strings.i18n.json index 53b9f908..2d46fec7 100644 --- a/lib/i18n/strings.i18n.json +++ b/lib/i18n/strings.i18n.json @@ -616,5 +616,10 @@ "title": "Legacy data deleted", "detail": "Seems this app have just upgraded from version older than 1.0, user login data and preferences are deleted because they are not usable any more.\nYou may need to login and set preferences once more. Sorry for inconvenience." } + }, + "html": { + "newcomerReportCard": { + "title": "Detail Info" + } } } diff --git a/lib/i18n/strings_zh-CN.i18n.json b/lib/i18n/strings_zh-CN.i18n.json index 393493e7..ddde0a30 100644 --- a/lib/i18n/strings_zh-CN.i18n.json +++ b/lib/i18n/strings_zh-CN.i18n.json @@ -616,5 +616,10 @@ "title": "旧数据已清除", "detail": "此应用似乎刚从低于1.0的版本升级上来,用户登录数据和设置偏好已不可使用,现已清除。\n您可能需要再登录一次并重新设置偏好,抱歉给您带来不便。" } + }, + "html": { + "newcomerReportCard": { + "title": "详细信息" + } } } diff --git a/lib/i18n/strings_zh-TW.i18n.json b/lib/i18n/strings_zh-TW.i18n.json index 25b44c9f..024bdf91 100644 --- a/lib/i18n/strings_zh-TW.i18n.json +++ b/lib/i18n/strings_zh-TW.i18n.json @@ -616,5 +616,10 @@ "title": "舊資料已清除", "detail": "此應用程式似乎剛從低於1.0的版本升級上來,使用者登入資料和設定偏好已不可用,現已清除。\n您可能需要再登入一次並重新設定偏好,抱歉給您帶來不便。" } + }, + "html": { + "newcomerReportCard": { + "title": "詳細資料" + } } } diff --git a/lib/utils/html/html_muncher.dart b/lib/utils/html/html_muncher.dart index 8a96e3f0..817dfca1 100644 --- a/lib/utils/html/html_muncher.dart +++ b/lib/utils/html/html_muncher.dart @@ -7,6 +7,7 @@ import 'package:tsdm_client/shared/models/models.dart'; import 'package:tsdm_client/utils/html/adaptive_color.dart'; import 'package:tsdm_client/utils/html/css_parser.dart'; import 'package:tsdm_client/utils/html/netease_card.dart'; +import 'package:tsdm_client/utils/html/newcomer_report_card.dart'; import 'package:tsdm_client/utils/html/types.dart'; import 'package:tsdm_client/utils/logger.dart'; import 'package:tsdm_client/utils/show_bottom_sheet.dart'; @@ -317,6 +318,8 @@ final class _Muncher with LoggerMixin { 'pre' => _buildPre(node), 'details' => _buildDetails(node), 'iframe' => _buildIframe(node), + 'table' when node.classes.contains('cgtl') => + _buildNewcomerReport(node), 'ignore_js_op' || 'table' || 'tbody' || @@ -1009,6 +1012,43 @@ final class _Muncher with LoggerMixin { return null; } + List? _buildNewcomerReport(uh.Element element) { + // + // + // + // + // + // + // + // + // ... + // + // + //
报到详细信息
昵称: USER_NICKNAME
+ final data = element + .querySelectorAll('tbody > tr') + .map( + (e) => ( + e.querySelector('th')?.innerText.trim(), + e.querySelector('td')?.innerText.trim() + ), + ) + .whereType<(String, String)>() + .map( + (e) => NewcomerReportInfo( + title: e.$1, + data: e.$2, + ), + ) + .toList(); + + return [ + WidgetSpan( + child: NewcomerReportCard(data), + ), + ]; + } + /* Setup Functions */ /// Try parse color from [element]. diff --git a/lib/utils/html/newcomer_report_card.dart b/lib/utils/html/newcomer_report_card.dart new file mode 100644 index 00000000..109ec22b --- /dev/null +++ b/lib/utils/html/newcomer_report_card.dart @@ -0,0 +1,107 @@ +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:tsdm_client/constants/layout.dart'; +import 'package:tsdm_client/i18n/strings.g.dart'; + +/// Table info in newcomer report table. +/// +/// Each info occupies a row in table. +class NewcomerReportInfo { + /// Constructor. + NewcomerReportInfo({ + required this.title, + required this.data, + }); + + /// Info title. + final String title; + + /// Info data, may be empty string. + final String data; +} + +/// Card for newcomer report table in thread. +/// +/// Only used in newcomer subreddit. +class NewcomerReportCard extends StatelessWidget { + /// Constructor. + const NewcomerReportCard(this.data, {super.key}); + + /// Data in table. + final List data; + + @override + Widget build(BuildContext context) { + return Card( + margin: EdgeInsets.zero, + child: Padding( + padding: edgeInsetsL12T12R12B12, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.article_outlined, + color: Theme.of(context).colorScheme.primary, + ), + sizedBoxW4H4, + Text( + context.t.html.newcomerReportCard.title, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: Theme.of(context).colorScheme.primary, + ), + ), + ], + ), + sizedBoxW8H8, + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Table( + defaultColumnWidth: const IntrinsicColumnWidth(), + columnWidths: const { + 0: FixedColumnWidth(100), + }, + defaultVerticalAlignment: TableCellVerticalAlignment.middle, + children: data + .mapIndexed( + (idx, e) => TableRow( + decoration: BoxDecoration( + color: idx.isOdd + ? Theme.of(context) + .colorScheme + .surfaceContainerHigh + : null, + ), + children: [ + TableCell( + child: Text( + e.title, + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith( + color: + Theme.of(context).colorScheme.secondary, + ), + ), + ), + TableCell( + child: Text( + e.data, + style: Theme.of(context).textTheme.bodyMedium, + ), + ), + ], + ), + ) + .toList(), + ), + ), + ], + ), + ), + ); + } +}