feat(mobile): UI-01 upload center, capture and auxiliary pages

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-21 17:20:43 +08:00
parent f6929ae18f
commit 1f67b7c818
26 changed files with 2144 additions and 771 deletions
@@ -95,25 +95,31 @@ void main() {
return task;
}
group('QueueStateFilter.states 分组', () {
group('QueueStateFilter.states 分组(UI-01 §4.4 四组 chips)', () {
test('all → 空集(不过滤)', () {
expect(QueueStateFilter.all.states, isEmpty);
});
test('failed 组 = 准备失败 + 上传失败(不含等待网络)', () {
expect(QueueStateFilter.failed.states, {
test('needsAttention 组 = 准备失败 + 上传失败(不含等待网络)', () {
expect(QueueStateFilter.needsAttention.states, {
UploadTaskState.preparationFailed,
UploadTaskState.retryableFailed,
});
});
test('uploading 组 = 上传中 + 确认中;completed 组不含 cancelled', () {
expect(QueueStateFilter.uploading.states, {
test('inProgress 组 = 准备/排队/上传/确认 + 等待网络(自动恢复归活任务)',
() {
expect(QueueStateFilter.inProgress.states, {
UploadTaskState.preparing,
UploadTaskState.queued,
UploadTaskState.uploading,
UploadTaskState.uploadedConfirming,
UploadTaskState.waitingNetwork,
});
expect(QueueStateFilter.completed.states,
{UploadTaskState.completed});
});
test('completed 组 = 仅 completed(cancelled 只在「全部」可见)', () {
expect(QueueStateFilter.completed.states, {UploadTaskState.completed});
});
});
@@ -152,7 +158,7 @@ void main() {
expect(filter.matches(other, now: now), isFalse);
});
test('状态维度:failed 组命中组内两态、排除组外', () async {
test('状态维度:needsAttention 组命中组内两态、排除组外', () async {
final prep = await seedTask(
state: UploadTaskState.preparationFailed,
createdAt: now,
@@ -166,7 +172,7 @@ void main() {
createdAt: now,
);
final filter = const QueueFilter(
state: QueueStateFilter.failed,
state: QueueStateFilter.needsAttention,
);
expect(filter.matches(prep, now: now), isTrue);
@@ -225,7 +231,7 @@ void main() {
);
const filter = QueueFilter(
albumId: 'alb-1',
state: QueueStateFilter.failed,
state: QueueStateFilter.needsAttention,
time: QueueTimeFilter.last30Days,
);
@@ -261,5 +267,26 @@ void main() {
expect(pendingCountOf(counts), 15);
expect(failedCountOf(counts), 13);
});
test('摘要行计数(UI-01 §4.4:按任务数,不与字节进度混口径)', () {
final counts = <UploadTaskState, int>{
for (final s in UploadTaskState.values) s: 0,
}
..[UploadTaskState.preparing] = 1
..[UploadTaskState.queued] = 2
..[UploadTaskState.uploading] = 3
..[UploadTaskState.uploadedConfirming] = 4
..[UploadTaskState.waitingNetwork] = 5
..[UploadTaskState.preparationFailed] = 6
..[UploadTaskState.retryableFailed] = 7
..[UploadTaskState.completed] = 8
..[UploadTaskState.cancelled] = 9;
// 已完成 = 终态 completed(不含取消)。
expect(completedSummaryOf(counts), 8);
// 上传中 = 传输 + 确认。
expect(uploadingSummaryOf(counts), 7);
// 等待中 = 准备 + 排队 + 等待网络。
expect(waitingSummaryOf(counts), 8);
});
});
}