feat(mobile): UI-01 theme system, shared components and navigation
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -145,17 +145,14 @@ class FakeAdapter implements HttpClientAdapter {
|
||||
Map<String, dynamic> loginOkBody({
|
||||
String token = 'tok-new',
|
||||
String expiresAt = '2026-09-20T12:00:00Z',
|
||||
}) => <String, dynamic>{
|
||||
'sessionToken': token,
|
||||
'expiresAt': expiresAt,
|
||||
};
|
||||
}) => <String, dynamic>{'sessionToken': token, 'expiresAt': expiresAt};
|
||||
|
||||
/// 常用响应体:契约 Error 形状。
|
||||
Map<String, dynamic> errorBody(String code) => <String, dynamic>{
|
||||
'code': code,
|
||||
'message': 'stub message',
|
||||
'requestId': 'req-stub',
|
||||
};
|
||||
'code': code,
|
||||
'message': 'stub message',
|
||||
'requestId': 'req-stub',
|
||||
};
|
||||
|
||||
// ── 相册域 fixtures(P3 计划 Task 4;形状对齐 openapi.yaml schemas)──
|
||||
|
||||
@@ -175,44 +172,45 @@ Map<String, dynamic> albumJson({
|
||||
bool originalDownloadEnabled = false,
|
||||
List<Map<String, dynamic>>? translations,
|
||||
List<Map<String, dynamic>> categories = const <Map<String, dynamic>>[],
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'id': id,
|
||||
'publicToken': publicToken,
|
||||
'ownerId': ownerId,
|
||||
'status': status,
|
||||
'defaultLocale': defaultLocale,
|
||||
'timezone': timezone,
|
||||
'startAt': startAt,
|
||||
'endAt': endAt,
|
||||
'uploadEnabled': uploadEnabled,
|
||||
'publicEnabled': publicEnabled,
|
||||
'downloadEnabled': downloadEnabled,
|
||||
'originalDownloadEnabled': originalDownloadEnabled,
|
||||
'watermarkVersion': 0,
|
||||
'translations': translations ??
|
||||
<Map<String, dynamic>>[
|
||||
<String, dynamic>{
|
||||
'locale': 'zh-CN',
|
||||
'title': '开幕晚宴',
|
||||
'description': null,
|
||||
'venue': '大宴会厅',
|
||||
'address': null,
|
||||
},
|
||||
<String, dynamic>{
|
||||
'locale': 'en',
|
||||
'title': 'Opening Gala',
|
||||
'description': null,
|
||||
'venue': null,
|
||||
'address': null,
|
||||
},
|
||||
],
|
||||
'categories': categories,
|
||||
'createdAt': '2026-09-01T00:00:00Z',
|
||||
'updatedAt': '2026-09-01T00:00:00Z',
|
||||
'statsSyncedAt': null,
|
||||
'cover': null,
|
||||
};
|
||||
Map<String, dynamic>? cover,
|
||||
}) => <String, dynamic>{
|
||||
'id': id,
|
||||
'publicToken': publicToken,
|
||||
'ownerId': ownerId,
|
||||
'status': status,
|
||||
'defaultLocale': defaultLocale,
|
||||
'timezone': timezone,
|
||||
'startAt': startAt,
|
||||
'endAt': endAt,
|
||||
'uploadEnabled': uploadEnabled,
|
||||
'publicEnabled': publicEnabled,
|
||||
'downloadEnabled': downloadEnabled,
|
||||
'originalDownloadEnabled': originalDownloadEnabled,
|
||||
'watermarkVersion': 0,
|
||||
'translations':
|
||||
translations ??
|
||||
<Map<String, dynamic>>[
|
||||
<String, dynamic>{
|
||||
'locale': 'zh-CN',
|
||||
'title': '开幕晚宴',
|
||||
'description': null,
|
||||
'venue': '大宴会厅',
|
||||
'address': null,
|
||||
},
|
||||
<String, dynamic>{
|
||||
'locale': 'en',
|
||||
'title': 'Opening Gala',
|
||||
'description': null,
|
||||
'venue': null,
|
||||
'address': null,
|
||||
},
|
||||
],
|
||||
'categories': categories,
|
||||
'createdAt': '2026-09-01T00:00:00Z',
|
||||
'updatedAt': '2026-09-01T00:00:00Z',
|
||||
'statsSyncedAt': null,
|
||||
'cover': cover,
|
||||
};
|
||||
|
||||
/// 契约 `Category` 响应体。
|
||||
Map<String, dynamic> categoryJson({
|
||||
@@ -220,17 +218,17 @@ Map<String, dynamic> categoryJson({
|
||||
String albumId = 'alb-1',
|
||||
int sortOrder = 0,
|
||||
List<Map<String, dynamic>>? translations,
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'id': id,
|
||||
'albumId': albumId,
|
||||
'sortOrder': sortOrder,
|
||||
'translations': translations ??
|
||||
<Map<String, dynamic>>[
|
||||
<String, dynamic>{'locale': 'zh-CN', 'name': '仪式'},
|
||||
<String, dynamic>{'locale': 'en', 'name': 'Ceremony'},
|
||||
],
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'id': id,
|
||||
'albumId': albumId,
|
||||
'sortOrder': sortOrder,
|
||||
'translations':
|
||||
translations ??
|
||||
<Map<String, dynamic>>[
|
||||
<String, dynamic>{'locale': 'zh-CN', 'name': '仪式'},
|
||||
<String, dynamic>{'locale': 'en', 'name': 'Ceremony'},
|
||||
],
|
||||
};
|
||||
|
||||
/// 契约 `Member` 响应体。
|
||||
Map<String, dynamic> memberJson({
|
||||
@@ -238,26 +236,24 @@ Map<String, dynamic> memberJson({
|
||||
String account = 'staff02',
|
||||
String displayName = 'Staff Two',
|
||||
String role = 'collaborator',
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'userId': userId,
|
||||
'account': account,
|
||||
'displayName': displayName,
|
||||
'role': role,
|
||||
'status': 'active',
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'userId': userId,
|
||||
'account': account,
|
||||
'displayName': displayName,
|
||||
'role': role,
|
||||
'status': 'active',
|
||||
};
|
||||
|
||||
/// 契约 `AdminUserLookupItem` 响应体。
|
||||
Map<String, dynamic> lookupUserJson({
|
||||
String id = 'u-9',
|
||||
String account = 'staff09',
|
||||
String displayName = 'Staff Nine',
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'id': id,
|
||||
'account': account,
|
||||
'displayName': displayName,
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'id': id,
|
||||
'account': account,
|
||||
'displayName': displayName,
|
||||
};
|
||||
|
||||
/// 契约 `AdminPhoto` 响应体。
|
||||
Map<String, dynamic> adminPhotoJson({
|
||||
@@ -266,36 +262,34 @@ Map<String, dynamic> adminPhotoJson({
|
||||
String visibility = 'published',
|
||||
String processingState = 'ready',
|
||||
int bytes = 123456,
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'photoId': photoId,
|
||||
'albumId': albumId,
|
||||
'categoryId': null,
|
||||
'uploaderId': 'u-2',
|
||||
'visibility': visibility,
|
||||
'processingState': processingState,
|
||||
'bytes': bytes,
|
||||
'width': 4000,
|
||||
'height': 3000,
|
||||
'shotAt': null,
|
||||
'uploadedAt': '2026-09-18T07:00:00Z',
|
||||
'publishedAt': '2026-09-18T07:05:00Z',
|
||||
'likeCount': 0,
|
||||
'uploader': <String, dynamic>{
|
||||
'userId': 'u-2',
|
||||
'account': 'staff02',
|
||||
'displayName': 'Staff Two',
|
||||
},
|
||||
'preview': null,
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'photoId': photoId,
|
||||
'albumId': albumId,
|
||||
'categoryId': null,
|
||||
'uploaderId': 'u-2',
|
||||
'visibility': visibility,
|
||||
'processingState': processingState,
|
||||
'bytes': bytes,
|
||||
'width': 4000,
|
||||
'height': 3000,
|
||||
'shotAt': null,
|
||||
'uploadedAt': '2026-09-18T07:00:00Z',
|
||||
'publishedAt': '2026-09-18T07:05:00Z',
|
||||
'likeCount': 0,
|
||||
'uploader': <String, dynamic>{
|
||||
'userId': 'u-2',
|
||||
'account': 'staff02',
|
||||
'displayName': 'Staff Two',
|
||||
},
|
||||
'preview': null,
|
||||
};
|
||||
|
||||
/// 契约游标分页响应体(hasMore 与 nextCursor 成对)。
|
||||
Map<String, dynamic> cursorPageBody(
|
||||
List<Map<String, dynamic>> items, {
|
||||
String? nextCursor,
|
||||
}) =>
|
||||
<String, dynamic>{
|
||||
'items': items,
|
||||
'nextCursor': nextCursor,
|
||||
'hasMore': nextCursor != null,
|
||||
};
|
||||
}) => <String, dynamic>{
|
||||
'items': items,
|
||||
'nextCursor': nextCursor,
|
||||
'hasMore': nextCursor != null,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user