fix(player): 评论面板按参考图重做
This commit is contained in:
1 parent
bdd3a53632
commit
7862e0be09
3 files changed
+273
-244
No files matched your search
@@ -3,7 +3,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/data/models/comment.dart';
|
||||
import '../../../core/data/services/comment_controller.dart';
|
||||
import '../../../core/formatting/localized_date_time.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
@@ -17,13 +16,11 @@ const String _reportAction = 'report';
|
||||
class CommentInteractionHandlers {
|
||||
const CommentInteractionHandlers({
|
||||
required this.onReply,
|
||||
required this.onLike,
|
||||
required this.onDelete,
|
||||
required this.onReport,
|
||||
});
|
||||
|
||||
final ValueChanged<DramaComment> onReply;
|
||||
final Future<void> Function(DramaComment) onLike;
|
||||
final Future<void> Function(DramaComment) onDelete;
|
||||
final Future<void> Function(DramaComment) onReport;
|
||||
}
|
||||
@@ -33,13 +30,11 @@ class CommentTile extends StatelessWidget {
|
||||
const CommentTile({
|
||||
super.key,
|
||||
required this.comment,
|
||||
required this.controller,
|
||||
required this.handlers,
|
||||
this.isReply = false,
|
||||
});
|
||||
|
||||
final DramaComment comment;
|
||||
final CommentController controller;
|
||||
final CommentInteractionHandlers handlers;
|
||||
final bool isReply;
|
||||
|
||||
@@ -51,66 +46,68 @@ class CommentTile extends StatelessWidget {
|
||||
: comment.nickname;
|
||||
return Padding(
|
||||
key: Key('comment-item-${comment.id}'),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 14),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_avatar(),
|
||||
const SizedBox(width: 10),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
color: AppColors.cream,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.muted,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (comment.createdAt != null)
|
||||
Text(
|
||||
formatLocalizedDateTime(context, comment.createdAt!),
|
||||
style: const TextStyle(
|
||||
SizedBox.square(
|
||||
dimension: 28,
|
||||
child: PopupMenuButton<String>(
|
||||
key: Key('comment-menu-${comment.id}'),
|
||||
tooltip: l10n.more,
|
||||
padding: EdgeInsets.zero,
|
||||
iconSize: 18,
|
||||
icon: const Icon(
|
||||
Icons.more_horiz_rounded,
|
||||
color: AppColors.subtle,
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
PopupMenuButton<String>(
|
||||
key: Key('comment-menu-${comment.id}'),
|
||||
tooltip: l10n.more,
|
||||
onSelected: (value) {
|
||||
if (value == _deleteAction) {
|
||||
handlers.onDelete(comment);
|
||||
} else if (value == _reportAction) {
|
||||
handlers.onReport(comment);
|
||||
}
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
if (comment.mine)
|
||||
onSelected: (value) {
|
||||
if (value == _deleteAction) {
|
||||
handlers.onDelete(comment);
|
||||
} else if (value == _reportAction) {
|
||||
handlers.onReport(comment);
|
||||
}
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
if (comment.mine)
|
||||
PopupMenuItem(
|
||||
value: _deleteAction,
|
||||
child: Text(l10n.deleteComment),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _deleteAction,
|
||||
child: Text(l10n.deleteComment),
|
||||
value: _reportAction,
|
||||
child: Text(l10n.reportComment),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _reportAction,
|
||||
child: Text(l10n.reportComment),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
comment.content,
|
||||
style: const TextStyle(
|
||||
color: AppColors.cream,
|
||||
fontSize: 14,
|
||||
fontSize: 16,
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
@@ -126,48 +123,11 @@ class CommentTile extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
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),
|
||||
icon: Icon(
|
||||
comment.liked
|
||||
? Icons.favorite_rounded
|
||||
: Icons.favorite_border_rounded,
|
||||
size: 16,
|
||||
),
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (comment.createdAt != null || !isReply)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 6),
|
||||
child: _metadata(context, l10n),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -177,14 +137,14 @@ class CommentTile extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _avatar() {
|
||||
final size = isReply ? 24.0 : 32.0;
|
||||
final size = isReply ? 28.0 : 40.0;
|
||||
if (comment.avatarUrl.isEmpty) {
|
||||
return CircleAvatar(
|
||||
radius: size / 2,
|
||||
backgroundColor: AppColors.raised,
|
||||
child: Icon(
|
||||
Icons.person_rounded,
|
||||
size: isReply ? 14 : 18,
|
||||
size: isReply ? 16 : 22,
|
||||
color: AppColors.cream,
|
||||
),
|
||||
);
|
||||
@@ -197,4 +157,40 @@ class CommentTile extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _metadata(BuildContext context, AppLocalizations l10n) {
|
||||
final createdAt = comment.createdAt;
|
||||
return Row(
|
||||
children: [
|
||||
if (createdAt != null)
|
||||
Text(
|
||||
formatLocalizedDateTime(context, createdAt),
|
||||
style: const TextStyle(color: AppColors.subtle, fontSize: 12),
|
||||
),
|
||||
if (createdAt != null && !isReply) ...[
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'·',
|
||||
style: TextStyle(color: AppColors.muted, fontSize: 12),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
if (!isReply)
|
||||
TextButton(
|
||||
key: Key('comment-reply-${comment.id}'),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColors.muted,
|
||||
padding: EdgeInsets.zero,
|
||||
minimumSize: const Size(0, 24),
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
onPressed: () => handlers.onReply(comment),
|
||||
child: Text(
|
||||
l10n.reply,
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user