merge: 合并 K86.15 评论发布成功提示
This commit is contained in:
commit
c3e6e02e47
10 files changed
+138
-47
No files matched your search
@@ -211,6 +211,7 @@
|
||||
"writeComment": "Write a comment",
|
||||
"commentLoginHint": "Sign in to comment",
|
||||
"postComment": "Post",
|
||||
"commentPostSuccess": "Comment posted",
|
||||
"loadMore": "Load more",
|
||||
"commentsLoadFailed": "Comments could not be loaded.",
|
||||
"commentPostFailed": "Could not post your comment.",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"writeComment": "Tulis komentar",
|
||||
"commentLoginHint": "Masuk untuk berkomentar",
|
||||
"postComment": "Kirim",
|
||||
"commentPostSuccess": "Komentar terkirim",
|
||||
"loadMore": "Muat lebih banyak",
|
||||
"commentsLoadFailed": "Komentar tidak dapat dimuat.",
|
||||
"commentPostFailed": "Komentar tidak dapat dikirim.",
|
||||
|
||||
@@ -946,6 +946,12 @@ abstract class AppLocalizations {
|
||||
/// **'Post'**
|
||||
String get postComment;
|
||||
|
||||
/// No description provided for @commentPostSuccess.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Comment posted'**
|
||||
String get commentPostSuccess;
|
||||
|
||||
/// No description provided for @loadMore.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -462,6 +462,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get postComment => 'Post';
|
||||
|
||||
@override
|
||||
String get commentPostSuccess => 'Comment posted';
|
||||
|
||||
@override
|
||||
String get loadMore => 'Load more';
|
||||
|
||||
|
||||
@@ -463,6 +463,9 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
@override
|
||||
String get postComment => 'Kirim';
|
||||
|
||||
@override
|
||||
String get commentPostSuccess => 'Komentar terkirim';
|
||||
|
||||
@override
|
||||
String get loadMore => 'Muat lebih banyak';
|
||||
|
||||
|
||||
@@ -457,6 +457,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get postComment => '发布';
|
||||
|
||||
@override
|
||||
String get commentPostSuccess => '发表成功';
|
||||
|
||||
@override
|
||||
String get loadMore => '加载更多';
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"writeComment": "写评论",
|
||||
"commentLoginHint": "登录后参与评论",
|
||||
"postComment": "发布",
|
||||
"commentPostSuccess": "发表成功",
|
||||
"loadMore": "加载更多",
|
||||
"commentsLoadFailed": "评论加载失败,请重试。",
|
||||
"commentPostFailed": "评论发布失败,请重试。",
|
||||
|
||||
@@ -129,6 +129,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet>
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (result.isSuccess) {
|
||||
_input.clear();
|
||||
_closing = true;
|
||||
Navigator.pop(context, true);
|
||||
return;
|
||||
|
||||
@@ -41,6 +41,7 @@ class DramaCommentsSheet extends StatefulWidget {
|
||||
class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
late final CommentRepository _comments;
|
||||
late final CommentController _controller;
|
||||
final _messengerKey = GlobalKey<ScaffoldMessengerState>();
|
||||
int? _serverCount;
|
||||
int _countRequest = 0;
|
||||
|
||||
@@ -91,65 +92,110 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
builder: (_) =>
|
||||
CommentComposerSheet(controller: _controller, replyTo: replyTo),
|
||||
);
|
||||
if (published == true && mounted) await _refreshCount();
|
||||
if (published == true && mounted) {
|
||||
_showPostSuccess();
|
||||
await _refreshCount();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDismissLayerTap() {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
void _showPostSuccess() {
|
||||
final messenger = _messengerKey.currentState;
|
||||
if (messenger == null) return;
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
double _sheetHeight(BuildContext context) {
|
||||
final screenHeight = MediaQuery.sizeOf(context).height;
|
||||
final topSafeArea = MediaQuery.paddingOf(context).top;
|
||||
final halfHeight = (screenHeight * 0.5).roundToDouble();
|
||||
final maxHeight = math.max(0.0, screenHeight - topSafeArea);
|
||||
final sheetHeight = math.min(halfHeight, maxHeight);
|
||||
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),
|
||||
);
|
||||
},
|
||||
return math.min(halfHeight, maxHeight);
|
||||
}
|
||||
|
||||
@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),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,11 @@ void main() {
|
||||
publishError: const ApiException(400, '评论包含敏感词'),
|
||||
);
|
||||
|
||||
await _pumpSheet(tester, repository: repository);
|
||||
await _pumpSheet(
|
||||
tester,
|
||||
repository: repository,
|
||||
locale: const Locale('zh'),
|
||||
);
|
||||
await tester.tap(find.byKey(const Key('comment-input-placeholder')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(
|
||||
@@ -250,6 +254,7 @@ void main() {
|
||||
find.byKey(const Key('comment-composer-input')),
|
||||
);
|
||||
expect(field.controller?.text, 'blocked text');
|
||||
expect(find.text('发表成功'), findsNothing);
|
||||
// 发送失败时保留输入与焦点,用户可以直接改完再发。
|
||||
expect(field.focusNode?.hasFocus, isTrue);
|
||||
},
|
||||
@@ -263,7 +268,11 @@ void main() {
|
||||
countResult: 1,
|
||||
);
|
||||
|
||||
await _pumpSheet(tester, repository: repository);
|
||||
await _pumpSheet(
|
||||
tester,
|
||||
repository: repository,
|
||||
locale: const Locale('zh'),
|
||||
);
|
||||
final input = find.byKey(const Key('comment-composer-input'));
|
||||
tester.view.viewInsets = const FakeViewPadding(bottom: 180);
|
||||
await tester.tap(find.byKey(const Key('comment-input-placeholder')));
|
||||
@@ -278,9 +287,25 @@ void main() {
|
||||
isNotNull,
|
||||
);
|
||||
await tester.tap(find.byKey(const Key('comment-composer-post')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(find.byKey(const Key('comment-composer-sheet')), findsNothing);
|
||||
final successSnackBar = find.byKey(
|
||||
const Key('comment-post-success-snackbar'),
|
||||
);
|
||||
expect(successSnackBar, findsOneWidget);
|
||||
expect(find.text('发表成功'), findsOneWidget);
|
||||
final snackBar = tester.widget<SnackBar>(successSnackBar);
|
||||
expect(snackBar.action, isNull);
|
||||
expect(snackBar.behavior, SnackBarBehavior.floating);
|
||||
expect(snackBar.duration, const Duration(milliseconds: 1500));
|
||||
expect(
|
||||
tester.getRect(find.text('发表成功')).bottom,
|
||||
lessThanOrEqualTo(
|
||||
tester.getRect(find.byKey(const Key('player-comments-sheet'))).top,
|
||||
),
|
||||
);
|
||||
expect(find.byKey(const Key('comment-list')), findsOneWidget);
|
||||
expect(find.byKey(const Key('comment-count-label')), findsOneWidget);
|
||||
expect(find.byKey(const Key('comment-input-placeholder')), findsOneWidget);
|
||||
@@ -669,6 +694,7 @@ Future<AuthController> _pumpSheet(
|
||||
WidgetTester tester, {
|
||||
required FakeCommentRepository repository,
|
||||
FakeHaptics? haptics,
|
||||
Locale locale = const Locale('en'),
|
||||
}) async {
|
||||
final auth = await _auth();
|
||||
await tester.pumpWidget(
|
||||
@@ -682,7 +708,7 @@ Future<AuthController> _pumpSheet(
|
||||
Provider<Haptics>.value(value: haptics ?? FakeHaptics()),
|
||||
],
|
||||
child: MaterialApp(
|
||||
locale: const Locale('en'),
|
||||
locale: locale,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
initialRoute: '/comments',
|
||||
|
||||
Reference in new issue
Block a user