fix(flutter): 重做评论面板视觉

This commit is contained in:
Zhou Weidong committed 2026-10-20 12:11:44 +08:00
1 parent ced1ec3d9e
commit 9493ad23bb
4 files changed
+89 -28

No files matched your search

+3
View File
@@ -55,6 +55,9 @@ abstract final class AppColors {
static const raised = Color(0xFFFFF1E5);
static const quick = Color(0xFFFFF0E1);
static const input = Color(0xFFFFF4EA);
/// 评论输入框底色。
static const commentInput = Color(0xFFF5EFE8);
static const goldCard = Color(0xFFFFF4DF);
/// 正文颜色。
+30 -10
View File
@@ -51,12 +51,12 @@ class CommentTile extends StatelessWidget {
: comment.nickname;
return Padding(
key: Key('comment-item-${comment.id}'),
padding: const EdgeInsets.symmetric(vertical: 8),
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_avatar(),
const SizedBox(width: 12),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -67,8 +67,9 @@ class CommentTile extends StatelessWidget {
child: Text(
name,
style: const TextStyle(
color: AppColors.muted,
fontSize: 12,
color: AppColors.cream,
fontSize: 13,
fontWeight: FontWeight.w700,
),
),
),
@@ -77,7 +78,7 @@ class CommentTile extends StatelessWidget {
formatLocalizedDateTime(context, comment.createdAt!),
style: const TextStyle(
color: AppColors.subtle,
fontSize: 10,
fontSize: 11,
),
),
const SizedBox(width: 4),
@@ -109,8 +110,8 @@ class CommentTile extends StatelessWidget {
comment.content,
style: const TextStyle(
color: AppColors.cream,
fontSize: 13,
height: 1.2,
fontSize: 14,
height: 1.4,
),
),
if (comment.isPending)
@@ -129,6 +130,12 @@ class CommentTile extends StatelessWidget {
children: [
TextButton.icon(
key: Key('comment-like-${comment.id}'),
style: TextButton.styleFrom(
foregroundColor: AppColors.muted,
padding: const EdgeInsets.symmetric(horizontal: 4),
minimumSize: const Size(0, 28),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: controller.likingComment(comment.id)
? null
: () => handlers.onLike(comment),
@@ -138,11 +145,24 @@ class CommentTile extends StatelessWidget {
: Icons.favorite_border_rounded,
size: 16,
),
label: Text('${comment.likeCount}'),
label: Text(
'${comment.likeCount}',
style: const TextStyle(fontSize: 11),
),
),
if (!isReply)
TextButton(
key: Key('comment-reply-${comment.id}'),
style: TextButton.styleFrom(
foregroundColor: AppColors.blue,
textStyle: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
),
padding: const EdgeInsets.symmetric(horizontal: 4),
minimumSize: const Size(0, 28),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () => handlers.onReply(comment),
child: Text(l10n.reply),
),
@@ -157,14 +177,14 @@ class CommentTile extends StatelessWidget {
}
Widget _avatar() {
final size = isReply ? 22.0 : 28.0;
final size = isReply ? 24.0 : 32.0;
if (comment.avatarUrl.isEmpty) {
return CircleAvatar(
radius: size / 2,
backgroundColor: AppColors.raised,
child: Icon(
Icons.person_rounded,
size: isReply ? 13 : 16,
size: isReply ? 14 : 18,
color: AppColors.cream,
),
);
@@ -22,9 +22,9 @@ import 'comment_tile.dart';
const double _minSheetHeight = 280;
const double _maxSheetHeight = 520;
const int _maxCommentLength = 300;
const double _composerRadius = 20;
const double _composerHeight = 40;
const double _sendButtonSize = 32;
const double _composerRadius = 22;
const double _composerHeight = 44;
const double _sendButtonSize = 36;
const double _sheetRadius = 20;
/// 服务端评论底部弹窗:匿名列表、游标翻页、回复、点赞和本人删除。
@@ -195,6 +195,18 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
key: const Key('player-comments-drag-handle'),
width: 36,
height: 4,
decoration: BoxDecoration(
color: AppColors.border,
borderRadius: BorderRadius.circular(999),
),
),
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
@@ -203,8 +215,8 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
key: count == null ? null : const Key('comment-count-label'),
style: const TextStyle(
color: AppColors.onSurface,
fontSize: 18,
fontWeight: FontWeight.w800,
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
@@ -212,7 +224,8 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
key: const Key('player-comments-close'),
tooltip: l10n.close,
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.close_rounded),
visualDensity: VisualDensity.compact,
icon: const Icon(Icons.close_rounded, size: 20),
),
],
),
@@ -326,11 +339,11 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
);
return InputDecoration(
hintText: hint,
hintStyle: const TextStyle(color: AppColors.muted, fontSize: 13),
hintStyle: const TextStyle(color: AppColors.muted, fontSize: 14),
counterText: '',
filled: true,
fillColor: AppColors.raised,
contentPadding: const EdgeInsets.symmetric(horizontal: 12),
fillColor: AppColors.commentInput,
contentPadding: const EdgeInsets.symmetric(horizontal: 14),
isDense: true,
border: clear,
enabledBorder: clear,
@@ -349,7 +362,8 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
focusNode: _inputFocus,
maxLength: _maxCommentLength,
maxLines: 1,
style: const TextStyle(color: AppColors.cream, fontSize: 13),
textAlignVertical: TextAlignVertical.center,
style: const TextStyle(color: AppColors.cream, fontSize: 14),
cursorColor: AppColors.blue,
decoration: _composerDecoration(l10n.writeComment),
onSubmitted: (_) => _post(),
@@ -402,10 +416,20 @@ class _CommentThread extends StatelessWidget {
),
if (comment.replyCount > 0 || replies.isNotEmpty)
Padding(
padding: const EdgeInsets.only(left: 44, bottom: 8),
padding: const EdgeInsets.only(left: 42, bottom: 4),
child: TextButton(
key: Key('comment-replies-${comment.id}'),
onPressed: () => _toggleReplies(context),
style: TextButton.styleFrom(
foregroundColor: AppColors.blue,
textStyle: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
),
padding: const EdgeInsets.symmetric(horizontal: 4),
minimumSize: const Size(0, 28),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Text(
expanded
? AppLocalizations.of(context)!.hideReplies
@@ -440,7 +464,10 @@ class _CommentThread extends StatelessWidget {
],
),
),
const Divider(height: 1, color: AppColors.outlineVariantDark),
const Padding(
padding: EdgeInsets.only(left: 42),
child: Divider(height: 1, color: AppColors.border),
),
],
);
}
+17 -6
View File
@@ -129,7 +129,7 @@ void main() {
expect(tester.widget<TextField>(input).focusNode?.hasFocus, isFalse);
});
testWidgets('should_use_compact_comment_sizes', (tester) async {
testWidgets('should_use_polished_comment_sizes', (tester) async {
final repository = FakeCommentRepository(
pages: [
CommentPage(
@@ -142,19 +142,30 @@ void main() {
expect(
tester.getSize(find.byKey(const Key('comment-post'))),
const Size(32, 32),
const Size(36, 36),
);
expect(tester.getSize(find.byKey(const Key('comment-input'))).height, 44);
expect(
find.byKey(const Key('player-comments-drag-handle')),
findsOneWidget,
);
expect(tester.getSize(find.byKey(const Key('comment-input'))).height, 40);
final avatar = tester.widget<CircleAvatar>(
find.descendant(
of: find.byKey(const Key('comment-item-10')),
matching: find.byType(CircleAvatar),
),
);
expect(avatar.radius, 14);
expect(avatar.radius, 16);
final body = tester.widget<Text>(find.text('Great episode'));
expect(body.style?.fontSize, 13);
expect(body.style?.height, 1.2);
expect(body.style?.fontSize, 14);
expect(body.style?.height, 1.4);
expect(
tester
.widget<TextField>(find.byKey(const Key('comment-input')))
.decoration
?.fillColor,
AppColors.commentInput,
);
});
testWidgets('should_show_review_badge_and_server_replaced_content', (