mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
Improve the UI of comments page.
This commit is contained in:
@@ -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": "回覆"
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -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') {
|
||||||
|
Reference in New Issue
Block a user