feat(app): 服务端历史行首缩略图 + 上传中心空态引导至服务端历史
- UploadSessionPhoto 解析可选 preview;历史行首有 thumb 渲染 PhotoThumbnail (SizedBox 定寸——Row 内裸 AspectRatio 无界约束),缺省回退中性占位 - 上传中心整体空态加「仅本机存储」说明 + 「查看服务端历史」tonal 按钮 (与右上 History 同路由);「需关注」空态保持专属文案不加引导 - l10n 增 queueEmptyDeviceHint / queueViewServerHistory Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -279,6 +279,28 @@ void main() {
|
||||
reason: 'History 入口 push /server-history(与本机队列数据源区分)');
|
||||
});
|
||||
|
||||
testWidgets('空态引导:本机 0 条记录 → 服务端历史说明 + 跳转按钮', (
|
||||
tester,
|
||||
) async {
|
||||
// setUp 每次新内存库:不种任务即整体队列空态(重装后场景)。
|
||||
await pumpQueue(tester);
|
||||
|
||||
expect(find.text('No upload tasks'), findsOneWidget);
|
||||
// 本机存储口径说明 + 服务端历史引导(EmptyState subtitle + tonal 按钮)。
|
||||
expect(
|
||||
find.text(
|
||||
'Upload records live on this device only and are cleared on reinstall',
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(find.text('View server history'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('View server history'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('SERVER_HISTORY_MARK'), findsOneWidget,
|
||||
reason: '空态引导与右上 History 同路由');
|
||||
});
|
||||
|
||||
testWidgets('摘要卡:范围标注(时间·本设备)+ 四组任务数(突出已完成)',
|
||||
(tester) async {
|
||||
await seed('done1.jpg', state: UploadTaskState.completed);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/// 服务端上传历史页 widget 测试(UI-03 页面 16;A19 语义)。
|
||||
///
|
||||
/// 覆盖:标题/副标题(跨设备口径)与 A19 数据源区分横幅、行内容
|
||||
/// (clientTaskId 短码/KB/状态徽章/时间 · 设备来源安全回退)、相册与
|
||||
/// (clientTaskId 短码/KB/状态徽章/时间 · 设备来源安全回退)、行首缩略图
|
||||
/// (有 preview 渲染 PhotoThumbnail;无 preview 回退中性占位)、相册与
|
||||
/// 日期客户端筛选、下拉刷新、游标加载更多、加载更多失败页脚重试、
|
||||
/// 首屏错误重试。
|
||||
library;
|
||||
@@ -15,6 +16,7 @@ import 'package:photo_live/core/device_id.dart';
|
||||
import 'package:photo_live/core/session_store.dart';
|
||||
import 'package:photo_live/l10n/app_localizations.dart';
|
||||
import 'package:photo_live/pages/server_history_page.dart';
|
||||
import 'package:photo_live/ui/components/photo_thumbnail.dart';
|
||||
|
||||
import '../helpers/fakes.dart';
|
||||
|
||||
@@ -43,6 +45,7 @@ Map<String, dynamic> sessionJson({
|
||||
String photoId = 'pho-0001',
|
||||
String processingState = 'ready',
|
||||
String? sourceDeviceId = _kOwnDevice,
|
||||
Map<String, dynamic>? preview,
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'uploadId': uploadId,
|
||||
@@ -57,6 +60,7 @@ Map<String, dynamic> sessionJson({
|
||||
'photoId': photoId,
|
||||
'processingState': processingState,
|
||||
'visibility': 'published',
|
||||
'preview': ?preview,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -182,6 +186,41 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('行首缩略图:有 preview 渲染 PhotoThumbnail;无 preview 回退中性占位', (
|
||||
tester,
|
||||
) async {
|
||||
final adapter = adapterOf((o) {
|
||||
if (o.method == 'GET' && o.path == '/v1/uploads') {
|
||||
return (
|
||||
200,
|
||||
cursorPageBody([
|
||||
// 已处理照片(变体齐备)→ 服务端下发 preview。
|
||||
sessionJson(
|
||||
clientTaskId: 'withthumb000000000000000000000001',
|
||||
preview: photoPreviewJson(
|
||||
thumbUrl: 'http://test.local/thumb-1.jpg',
|
||||
),
|
||||
),
|
||||
// 未处理会话 → 无 preview 字段(App 回退占位图标)。
|
||||
sessionJson(
|
||||
uploadId: 'upl-0002',
|
||||
clientTaskId: 'nopreview000000000000000000000002',
|
||||
state: 'pending',
|
||||
processingState: 'processing',
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
throw StateError('unexpected ${o.method} ${o.path}');
|
||||
});
|
||||
|
||||
await pumpPage(tester, clientOf(adapter));
|
||||
|
||||
// 有 preview:行首是缩略图组件;无 preview:中性占位图标仍在。
|
||||
expect(find.byType(PhotoThumbnail), findsOneWidget);
|
||||
expect(find.byIcon(Icons.cloud_done_outlined), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('相册筛选(候选来自相册列表;客户端过滤已加载记录)',
|
||||
(tester) async {
|
||||
final adapter = adapterOf(
|
||||
|
||||
Reference in New Issue
Block a user