Improve the UI of comments page.

This commit is contained in:
2025-02-15 11:20:53 +08:00
parent 94098eea77
commit 0c7bc78541
2 changed files with 87 additions and 26 deletions

View File

@@ -337,7 +337,8 @@
"Ascending": "升序", "Ascending": "升序",
"Descending": "降序", "Descending": "降序",
"Last Reading: Chapter @ep Page @page": "上次阅读: 第 @ep 章 第 @page 页", "Last Reading: Chapter @ep Page @page": "上次阅读: 第 @ep 章 第 @page 页",
"Last Reading: Page @page": "上次阅读: 第 @page 页" "Last Reading: Page @page": "上次阅读: 第 @page 页",
"Replies": "回复"
}, },
"zh_TW": { "zh_TW": {
"Home": "首頁", "Home": "首頁",
@@ -677,6 +678,7 @@
"Ascending": "升序", "Ascending": "升序",
"Descending": "降序", "Descending": "降序",
"Last Reading: Chapter @ep Page @page": "上次閱讀: 第 @ep 章 第 @page 頁", "Last Reading: Chapter @ep Page @page": "上次閱讀: 第 @ep 章 第 @page 頁",
"Last Reading: Page @page": "上次閱讀: 第 @page 頁" "Last Reading: Page @page": "上次閱讀: 第 @page 頁",
"Replies": "回覆"
} }
} }

View File

@@ -1,14 +1,18 @@
part of 'comic_page.dart'; part of 'comic_page.dart';
class CommentsPage extends StatefulWidget { class CommentsPage extends StatefulWidget {
const CommentsPage( const CommentsPage({
{super.key, required this.data, required this.source, this.replyId}); super.key,
required this.data,
required this.source,
this.replyComment,
});
final ComicDetails data; final ComicDetails data;
final ComicSource source; final ComicSource source;
final String? replyId; final Comment? replyComment;
@override @override
State<CommentsPage> createState() => _CommentsPageState(); State<CommentsPage> createState() => _CommentsPageState();
@@ -25,7 +29,7 @@ class _CommentsPageState extends State<CommentsPage> {
void firstLoad() async { void firstLoad() async {
var res = await widget.source.commentsLoader!( 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) { if (res.error) {
setState(() { setState(() {
_error = res.errorMessage; _error = res.errorMessage;
@@ -42,7 +46,11 @@ class _CommentsPageState extends State<CommentsPage> {
void loadMore() async { void loadMore() async {
var res = await widget.source.commentsLoader!( 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) { if (res.error) {
context.showMessage(message: res.errorMessage ?? "Unknown Error"); context.showMessage(message: res.errorMessage ?? "Unknown Error");
} else { } else {
@@ -94,8 +102,44 @@ class _CommentsPageState extends State<CommentsPage> {
child: ListView.builder( child: ListView.builder(
primary: false, primary: false,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: _comments!.length + 1, itemCount: _comments!.length + 2,
itemBuilder: (context, index) { 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 (index == _comments!.length) {
if (_page < (maxPage ?? _page + 1)) { if (_page < (maxPage ?? _page + 1)) {
loadMore(); loadMore();
@@ -130,6 +174,12 @@ class _CommentsPageState extends State<CommentsPage> {
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
border: Border(
top: BorderSide(
color: context.colorScheme.outlineVariant,
width: 0.6,
),
),
), ),
child: Material( child: Material(
color: context.colorScheme.surfaceContainer, color: context.colorScheme.surfaceContainer,
@@ -149,7 +199,7 @@ class _CommentsPageState extends State<CommentsPage> {
), ),
if (sending) if (sending)
const Padding( const Padding(
padding: EdgeInsets.all(8.5), padding: EdgeInsets.all(8),
child: SizedBox( child: SizedBox(
width: 24, width: 24,
height: 24, height: 24,
@@ -171,7 +221,7 @@ class _CommentsPageState extends State<CommentsPage> {
widget.data.comicId, widget.data.comicId,
widget.data.subId, widget.data.subId,
controller.text, controller.text,
widget.replyId); widget.replyComment?.id);
if (!b.error) { if (!b.error) {
controller.text = ""; controller.text = "";
setState(() { setState(() {
@@ -194,7 +244,7 @@ class _CommentsPageState extends State<CommentsPage> {
), ),
) )
], ],
).paddingVertical(2).paddingLeft(16).paddingRight(4), ).paddingLeft(16).paddingRight(4),
), ),
); );
} }
@@ -206,6 +256,7 @@ class _CommentTile extends StatefulWidget {
required this.source, required this.source,
required this.comic, required this.comic,
required this.showAvatar, required this.showAvatar,
this.showActions = true,
}); });
final Comment comment; final Comment comment;
@@ -216,6 +267,8 @@ class _CommentTile extends StatefulWidget {
final bool showAvatar; final bool showAvatar;
final bool showActions;
@override @override
State<_CommentTile> createState() => _CommentTileState(); State<_CommentTile> createState() => _CommentTileState();
} }
@@ -232,24 +285,17 @@ class _CommentTileState extends State<_CommentTile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: BoxDecoration( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
border: Border(
bottom: BorderSide(
color: Theme.of(context).colorScheme.outlineVariant,
width: 0.6,
),
),
),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.showAvatar) if (widget.showAvatar)
Container( Container(
width: 40, width: 36,
height: 40, height: 36,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(18),
color: Theme.of(context).colorScheme.secondaryContainer), color: Theme.of(context).colorScheme.secondaryContainer),
child: widget.comment.avatar == null child: widget.comment.avatar == null
? null ? null
@@ -259,7 +305,7 @@ class _CommentTileState extends State<_CommentTile> {
sourceKey: widget.source.key, sourceKey: widget.source.key,
), ),
), ),
).paddingRight(12), ).paddingRight(8),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -277,11 +323,14 @@ class _CommentTileState extends State<_CommentTile> {
), ),
) )
], ],
).paddingAll(16), ),
); );
} }
Widget buildActions() { Widget buildActions() {
if (!widget.showActions) {
return const SizedBox();
}
if (widget.comment.score == null && widget.comment.replyCount == null) { if (widget.comment.score == null && widget.comment.replyCount == null) {
return const SizedBox(); return const SizedBox();
} }
@@ -320,7 +369,7 @@ class _CommentTileState extends State<_CommentTile> {
CommentsPage( CommentsPage(
data: widget.comic, data: widget.comic,
source: widget.source, source: widget.source,
replyId: widget.comment.id, replyComment: widget.comment,
), ),
showBarrier: false, showBarrier: false,
); );
@@ -665,7 +714,17 @@ class _RichCommentContentState extends State<RichCommentContent> {
attributes[attrSplits[0]] = attrSplits[1].replaceAll('"', ''); 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)) { if (acceptedTags.contains(tagName)) {
writeBuffer(); writeBuffer();
if (tagName == 'img') { if (tagName == 'img') {