diff --git a/assets/translation.json b/assets/translation.json index 869eec3..633c4e7 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -337,7 +337,8 @@ "Ascending": "升序", "Descending": "降序", "Last Reading: Chapter @ep Page @page": "上次阅读: 第 @ep 章 第 @page 页", - "Last Reading: Page @page": "上次阅读: 第 @page 页" + "Last Reading: Page @page": "上次阅读: 第 @page 页", + "Replies": "回复" }, "zh_TW": { "Home": "首頁", @@ -677,6 +678,7 @@ "Ascending": "升序", "Descending": "降序", "Last Reading: Chapter @ep Page @page": "上次閱讀: 第 @ep 章 第 @page 頁", - "Last Reading: Page @page": "上次閱讀: 第 @page 頁" + "Last Reading: Page @page": "上次閱讀: 第 @page 頁", + "Replies": "回覆" } } \ No newline at end of file diff --git a/lib/pages/comic_details_page/comments_page.dart b/lib/pages/comic_details_page/comments_page.dart index a540dd4..de2589b 100644 --- a/lib/pages/comic_details_page/comments_page.dart +++ b/lib/pages/comic_details_page/comments_page.dart @@ -1,14 +1,18 @@ part of 'comic_page.dart'; class CommentsPage extends StatefulWidget { - const CommentsPage( - {super.key, required this.data, required this.source, this.replyId}); + const CommentsPage({ + super.key, + required this.data, + required this.source, + this.replyComment, + }); final ComicDetails data; final ComicSource source; - final String? replyId; + final Comment? replyComment; @override State createState() => _CommentsPageState(); @@ -25,7 +29,7 @@ class _CommentsPageState extends State { void firstLoad() async { var res = await widget.source.commentsLoader!( - widget.data.comicId, widget.data.subId, 1, widget.replyId); + widget.data.comicId, widget.data.subId, 1, widget.replyComment?.id); if (res.error) { setState(() { _error = res.errorMessage; @@ -42,7 +46,11 @@ class _CommentsPageState extends State { void loadMore() async { var res = await widget.source.commentsLoader!( - widget.data.comicId, widget.data.subId, _page + 1, widget.replyId); + widget.data.comicId, + widget.data.subId, + _page + 1, + widget.replyComment?.id, + ); if (res.error) { context.showMessage(message: res.errorMessage ?? "Unknown Error"); } else { @@ -94,8 +102,44 @@ class _CommentsPageState extends State { child: ListView.builder( primary: false, padding: EdgeInsets.zero, - itemCount: _comments!.length + 1, + itemCount: _comments!.length + 2, itemBuilder: (context, index) { + if (index == 0) { + if (widget.replyComment != null) { + return Column( + children: [ + _CommentTile( + comment: widget.replyComment!, + source: widget.source, + comic: widget.data, + showAvatar: showAvatar, + showActions: false, + ), + const SizedBox(height: 8), + Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: context.colorScheme.outlineVariant, + width: 0.6, + ), + ), + ), + child: Text( + "Replies".tl, + style: ts.s18, + ), + ), + ], + ); + } else { + return const SizedBox(); + } + } + index--; + if (index == _comments!.length) { if (_page < (maxPage ?? _page + 1)) { loadMore(); @@ -130,6 +174,12 @@ class _CommentsPageState extends State { padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, + border: Border( + top: BorderSide( + color: context.colorScheme.outlineVariant, + width: 0.6, + ), + ), ), child: Material( color: context.colorScheme.surfaceContainer, @@ -149,7 +199,7 @@ class _CommentsPageState extends State { ), if (sending) const Padding( - padding: EdgeInsets.all(8.5), + padding: EdgeInsets.all(8), child: SizedBox( width: 24, height: 24, @@ -171,7 +221,7 @@ class _CommentsPageState extends State { widget.data.comicId, widget.data.subId, controller.text, - widget.replyId); + widget.replyComment?.id); if (!b.error) { controller.text = ""; setState(() { @@ -194,7 +244,7 @@ class _CommentsPageState extends State { ), ) ], - ).paddingVertical(2).paddingLeft(16).paddingRight(4), + ).paddingLeft(16).paddingRight(4), ), ); } @@ -206,6 +256,7 @@ class _CommentTile extends StatefulWidget { required this.source, required this.comic, required this.showAvatar, + this.showActions = true, }); final Comment comment; @@ -216,6 +267,8 @@ class _CommentTile extends StatefulWidget { final bool showAvatar; + final bool showActions; + @override State<_CommentTile> createState() => _CommentTileState(); } @@ -232,24 +285,17 @@ class _CommentTileState extends State<_CommentTile> { @override Widget build(BuildContext context) { return Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).colorScheme.outlineVariant, - width: 0.6, - ), - ), - ), + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (widget.showAvatar) Container( - width: 40, - height: 40, + width: 36, + height: 36, clipBehavior: Clip.antiAlias, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.circular(18), color: Theme.of(context).colorScheme.secondaryContainer), child: widget.comment.avatar == null ? null @@ -259,7 +305,7 @@ class _CommentTileState extends State<_CommentTile> { sourceKey: widget.source.key, ), ), - ).paddingRight(12), + ).paddingRight(8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -277,11 +323,14 @@ class _CommentTileState extends State<_CommentTile> { ), ) ], - ).paddingAll(16), + ), ); } Widget buildActions() { + if (!widget.showActions) { + return const SizedBox(); + } if (widget.comment.score == null && widget.comment.replyCount == null) { return const SizedBox(); } @@ -320,7 +369,7 @@ class _CommentTileState extends State<_CommentTile> { CommentsPage( data: widget.comic, source: widget.source, - replyId: widget.comment.id, + replyComment: widget.comment, ), showBarrier: false, ); @@ -665,7 +714,17 @@ class _RichCommentContentState extends State { attributes[attrSplits[0]] = attrSplits[1].replaceAll('"', ''); } } - const acceptedTags = ['img', 'a', 'b', 'i', 'u', 's', 'br', 'span', 'strong']; + const acceptedTags = [ + 'img', + 'a', + 'b', + 'i', + 'u', + 's', + 'br', + 'span', + 'strong' + ]; if (acceptedTags.contains(tagName)) { writeBuffer(); if (tagName == 'img') {