fix(app): 海报下载反馈改弹层内呈现——SnackBar 被模态弹层遮挡不可见
根因:保存成功/失败的 SnackBar 弹在弹层底下的页面 Scaffold 上,被模态 bottom sheet + 遮罩整层盖住,用户永远看不到(保存本身大概率成功)。 - 成功:下载按钮翻成功态(✓+已保存到相册,kColorSuccess)2.5s 自动复原 - 失败:按钮下方弹层内红字留置可重试(对齐隐藏照片弹层面板内提示模式) - 删除被遮挡的 SnackBar 路径;复原 Timer 于 dispose 取消 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
/// 主操作写剪贴板 + 已复制提示、Open in browser 次操作经注入替身启动器
|
||||
/// 打开并退出页面、未公开相册显示「该链接目前无法公开浏览」琥珀提示
|
||||
/// (公开相册不显示)、海报弹层内「中文/English」切换(默认跟 App 语言,
|
||||
/// 提示文案/相册标题/二维码 lang 随切换,弹层 chrome 仍跟 App 语言)。
|
||||
/// 提示文案/相册标题/二维码 lang 随切换,弹层 chrome 仍跟 App 语言)、
|
||||
/// 下载海报反馈在弹层内可见(成功=按钮翻成功态自动复原;失败=弹层内
|
||||
/// 红字可重试;SnackBar 在模态弹层下不可见,不得作为反馈通道)。
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -26,12 +28,15 @@ void main() {
|
||||
WidgetTester tester, {
|
||||
bool publicEnabled = true,
|
||||
UrlLauncher? launcher,
|
||||
PosterSaver? saver,
|
||||
}) async {
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
if (launcher != null)
|
||||
urlLauncherProvider.overrideWith((ref) => launcher),
|
||||
if (saver != null)
|
||||
posterSaverProvider.overrideWith((ref) => saver),
|
||||
],
|
||||
child: MaterialApp(
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
@@ -121,6 +126,72 @@ void main() {
|
||||
expect(find.text('Download poster image'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('下载海报成功:按钮翻成功态并自动复原,全程无 SnackBar', (
|
||||
tester,
|
||||
) async {
|
||||
await pumpPage(tester, saver: (_) async {});
|
||||
await tester.tap(find.text('Generate QR poster'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.ensureVisible(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// 反馈必须在弹层内可见(SnackBar 被模态弹层遮挡,禁用)。
|
||||
expect(find.byType(SnackBar), findsNothing);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(BottomSheet),
|
||||
matching: find.text('Poster saved to gallery'),
|
||||
),
|
||||
findsOneWidget,
|
||||
reason: '成功反馈显示在下载按钮上(弹层内)',
|
||||
);
|
||||
|
||||
// 约 2.5s 后自动复原,可再次下载(配合语言切换存第二张)。
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Poster saved to gallery'), findsNothing);
|
||||
expect(find.text('Download poster image'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('下载海报失败:弹层内红字提示且可重试', (tester) async {
|
||||
var calls = 0;
|
||||
await pumpPage(
|
||||
tester,
|
||||
saver: (_) async {
|
||||
calls++;
|
||||
throw StateError('save failed');
|
||||
},
|
||||
);
|
||||
await tester.tap(find.text('Generate QR poster'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.ensureVisible(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(SnackBar), findsNothing);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(BottomSheet),
|
||||
matching: find.text('Failed to save poster'),
|
||||
),
|
||||
findsOneWidget,
|
||||
reason: '失败反馈在弹层内(对齐隐藏照片弹层的面板内提示模式)',
|
||||
);
|
||||
// 按钮复位可重试。
|
||||
expect(find.text('Download poster image'), findsOneWidget);
|
||||
|
||||
await tester.ensureVisible(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Download poster image'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(calls, 2, reason: '失败后可重试');
|
||||
});
|
||||
|
||||
testWidgets('Copy link(主操作)→ 剪贴板收到带 lang 的 URL + 已复制提示',
|
||||
(tester) async {
|
||||
final clipboardCalls = <MethodCall>[];
|
||||
|
||||
Reference in New Issue
Block a user