fix(player): 评论成功提示改黑色浮层并去除输入弹窗遮罩

This commit is contained in:
Zhou Weidong committed 2026-10-21 13:59:04 +08:00
1 parent c3e6e02e47
commit 5d459dd08a
3 files changed
+274 -200

No files matched your search

@@ -155,130 +155,160 @@ class _CommentComposerSheetState extends State<CommentComposerSheet>
final canPost = signedIn && hasContent && !widget.controller.submitting;
final multiline = _input.text.contains('\n');
return AnimatedPadding(
duration: const Duration(milliseconds: 200),
curve: Curves.easeOut,
padding: EdgeInsets.only(bottom: keyboardHeight),
child: SizedBox(
key: const Key('comment-composer-sheet'),
width: double.infinity,
child: Material(
color: AppColors.card,
clipBehavior: Clip.antiAlias,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
return Stack(
fit: StackFit.expand,
children: [
Positioned.fill(
child: GestureDetector(
key: const Key('comment-composer-dismiss-layer'),
behavior: HitTestBehavior.opaque,
onTap: () {
_inputFocus.unfocus();
_closeSheet();
},
),
child: SafeArea(
top: false,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
child: TextFieldTapRegion(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (widget.replyTo != null)
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
l10n.replyingTo(
widget.replyTo!.nickname.isEmpty
? l10n.anonymousUser
: widget.replyTo!.nickname,
),
style: const TextStyle(
color: AppColors.muted,
fontSize: 12,
),
),
),
Container(
decoration: BoxDecoration(
color: AppColors.commentInput,
borderRadius: BorderRadius.circular(_inputRadius),
),
child: TextField(
key: const Key('comment-composer-input'),
autofocus: true,
controller: _input,
focusNode: _inputFocus,
readOnly: !signedIn,
canRequestFocus: signedIn,
minLines: 1,
maxLines: 4,
maxLength: _maxCommentLength,
textAlignVertical: multiline
? TextAlignVertical.top
: TextAlignVertical.center,
style: TextStyle(
color: AppColors.cream,
fontSize: 15,
height: multiline ? 1.4 : null,
),
cursorColor: AppColors.blue,
decoration: InputDecoration(
hintText: signedIn
? l10n.writeComment
: l10n.commentLoginHint,
hintStyle: const TextStyle(
color: AppColors.muted,
fontSize: 14,
),
counterText: '',
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
onTap: signedIn ? null : _authenticate,
onTapOutside: (_) {
_inputFocus.unfocus();
_closeSheet();
},
),
),
const SizedBox(height: 12),
Align(
alignment: Alignment.centerRight,
child: SizedBox(
height: _postButtonHeight,
child: TextButton(
key: const Key('comment-composer-post'),
onPressed: canPost ? _submit : null,
style: TextButton.styleFrom(
minimumSize: const Size(0, _postButtonHeight),
padding: const EdgeInsets.symmetric(horizontal: 16),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
backgroundColor: hasContent
? AppColors.blue.withValues(alpha: 0.12)
: AppColors.raised,
foregroundColor: AppColors.blue,
disabledForegroundColor: AppColors.muted,
disabledBackgroundColor: AppColors.raised,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
Align(
alignment: Alignment.bottomCenter,
child: AnimatedPadding(
duration: const Duration(milliseconds: 200),
curve: Curves.easeOut,
padding: EdgeInsets.only(bottom: keyboardHeight),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: SizedBox(
key: const Key('comment-composer-sheet'),
width: double.infinity,
child: Material(
color: AppColors.card,
clipBehavior: Clip.antiAlias,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
),
child: SafeArea(
top: false,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
child: TextFieldTapRegion(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (widget.replyTo != null)
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
l10n.replyingTo(
widget.replyTo!.nickname.isEmpty
? l10n.anonymousUser
: widget.replyTo!.nickname,
),
style: const TextStyle(
color: AppColors.muted,
fontSize: 12,
),
),
),
Container(
decoration: BoxDecoration(
color: AppColors.commentInput,
borderRadius: BorderRadius.circular(
_inputRadius,
),
),
child: TextField(
key: const Key('comment-composer-input'),
autofocus: true,
controller: _input,
focusNode: _inputFocus,
readOnly: !signedIn,
canRequestFocus: signedIn,
minLines: 1,
maxLines: 4,
maxLength: _maxCommentLength,
textAlignVertical: multiline
? TextAlignVertical.top
: TextAlignVertical.center,
style: TextStyle(
color: AppColors.cream,
fontSize: 15,
height: multiline ? 1.4 : null,
),
cursorColor: AppColors.blue,
decoration: InputDecoration(
hintText: signedIn
? l10n.writeComment
: l10n.commentLoginHint,
hintStyle: const TextStyle(
color: AppColors.muted,
fontSize: 14,
),
counterText: '',
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
onTap: signedIn ? null : _authenticate,
onTapOutside: (_) {
_inputFocus.unfocus();
_closeSheet();
},
),
),
),
child: Text(
l10n.postComment,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
const SizedBox(height: 12),
Align(
alignment: Alignment.centerRight,
child: SizedBox(
height: _postButtonHeight,
child: TextButton(
key: const Key('comment-composer-post'),
onPressed: canPost ? _submit : null,
style: TextButton.styleFrom(
minimumSize: const Size(
0,
_postButtonHeight,
),
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
tapTargetSize:
MaterialTapTargetSize.shrinkWrap,
backgroundColor: hasContent
? AppColors.blue.withValues(alpha: 0.12)
: AppColors.raised,
foregroundColor: AppColors.blue,
disabledForegroundColor: AppColors.muted,
disabledBackgroundColor: AppColors.raised,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
l10n.postComment,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
],
),
),
),
],
),
),
),
),
),
),
),
],
);
}
}
@@ -41,7 +41,8 @@ class DramaCommentsSheet extends StatefulWidget {
class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
late final CommentRepository _comments;
late final CommentController _controller;
final _messengerKey = GlobalKey<ScaffoldMessengerState>();
OverlayEntry? _successOverlay;
Timer? _successOverlayTimer;
int? _serverCount;
int _countRequest = 0;
@@ -60,6 +61,8 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
@override
void dispose() {
_successOverlayTimer?.cancel();
_successOverlay?.remove();
_controller.dispose();
super.dispose();
}
@@ -88,6 +91,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
isScrollControlled: true,
isDismissible: true,
backgroundColor: Colors.transparent,
barrierColor: Colors.transparent,
showDragHandle: false,
builder: (_) =>
CommentComposerSheet(controller: _controller, replyTo: replyTo),
@@ -103,32 +107,19 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
}
void _showPostSuccess() {
final messenger = _messengerKey.currentState;
if (messenger == null) return;
_successOverlayTimer?.cancel();
_successOverlay?.remove();
final l10n = AppLocalizations.of(context)!;
messenger
..hideCurrentSnackBar()
..showSnackBar(
SnackBar(
key: const Key('comment-post-success-snackbar'),
content: Text(
l10n.commentPostSuccess,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
behavior: SnackBarBehavior.floating,
duration: const Duration(milliseconds: 1500),
backgroundColor: AppColors.ink,
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.fromLTRB(16, 0, 16, _sheetHeight(context) + 12),
),
);
final entry = OverlayEntry(
builder: (_) =>
_CommentPostSuccessOverlay(message: l10n.commentPostSuccess),
);
_successOverlay = entry;
Overlay.of(context, rootOverlay: true).insert(entry);
_successOverlayTimer = Timer(const Duration(milliseconds: 1200), () {
if (entry.mounted) entry.remove();
if (identical(_successOverlay, entry)) _successOverlay = null;
});
}
double _sheetHeight(BuildContext context) {
@@ -142,60 +133,51 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
@override
Widget build(BuildContext context) {
final sheetHeight = _sheetHeight(context);
return ScaffoldMessenger(
key: _messengerKey,
child: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
body: Stack(
fit: StackFit.expand,
children: [
Positioned.fill(
child: GestureDetector(
key: const Key('player-comments-dismiss-layer'),
behavior: HitTestBehavior.opaque,
onTap: _handleDismissLayerTap,
),
),
Align(
alignment: Alignment.bottomCenter,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: KeyedSubtree(
key: const Key('player-comments-sheet'),
child: SizedBox(
key: const Key('comment-sheet-constraints'),
height: sheetHeight,
child: Container(
decoration: const BoxDecoration(
color: AppColors.card,
borderRadius: BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
),
),
child: SafeArea(
top: false,
child: ListenableBuilder(
listenable: _controller,
builder: (context, _) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
child: _content(context),
);
},
),
),
return Stack(
fit: StackFit.expand,
children: [
Positioned.fill(
child: GestureDetector(
key: const Key('player-comments-dismiss-layer'),
behavior: HitTestBehavior.opaque,
onTap: _handleDismissLayerTap,
),
),
Align(
alignment: Alignment.bottomCenter,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: KeyedSubtree(
key: const Key('player-comments-sheet'),
child: SizedBox(
key: const Key('comment-sheet-constraints'),
height: sheetHeight,
child: Container(
decoration: const BoxDecoration(
color: AppColors.card,
borderRadius: BorderRadius.vertical(
top: Radius.circular(_sheetRadius),
),
),
child: SafeArea(
top: false,
child: ListenableBuilder(
listenable: _controller,
builder: (context, _) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: _content(context),
);
},
),
),
),
),
),
],
),
),
),
],
);
}
@@ -372,6 +354,44 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
}
}
class _CommentPostSuccessOverlay extends StatelessWidget {
const _CommentPostSuccessOverlay({required this.message});
final String message;
@override
Widget build(BuildContext context) {
return Positioned.fill(
child: IgnorePointer(
child: SafeArea(
child: Align(
alignment: const Alignment(0, 0.55),
child: Semantics(
liveRegion: true,
child: Container(
key: const Key('comment-post-success-snackbar'),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.82),
borderRadius: BorderRadius.circular(8),
),
child: Text(
message,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white, fontSize: 14),
),
),
),
),
),
),
);
}
}
class _CommentThread extends StatelessWidget {
const _CommentThread({
required this.comment,