diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 131a8d5..46df55a 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -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); /// 正文颜色。 diff --git a/lib/pages/player/widgets/comment_tile.dart b/lib/pages/player/widgets/comment_tile.dart index 9409a3c..3c567f4 100644 --- a/lib/pages/player/widgets/comment_tile.dart +++ b/lib/pages/player/widgets/comment_tile.dart @@ -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, ), ); diff --git a/lib/pages/player/widgets/drama_comments_sheet.dart b/lib/pages/player/widgets/drama_comments_sheet.dart index 9bb397c..e93892b 100644 --- a/lib/pages/player/widgets/drama_comments_sheet.dart +++ b/lib/pages/player/widgets/drama_comments_sheet.dart @@ -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 { 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 { 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 { 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 { ); 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 { 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), + ), ], ); } diff --git a/test/comment/drama_comments_sheet_test.dart b/test/comment/drama_comments_sheet_test.dart index 7fab8df..305c646 100644 --- a/test/comment/drama_comments_sheet_test.dart +++ b/test/comment/drama_comments_sheet_test.dart @@ -129,7 +129,7 @@ void main() { expect(tester.widget(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( 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(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(find.byKey(const Key('comment-input'))) + .decoration + ?.fillColor, + AppColors.commentInput, + ); }); testWidgets('should_show_review_badge_and_server_replaced_content', (