feat(mobile): UI-01 theme system, shared components and navigation

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-21 14:55:29 +08:00
parent 8f4ad11bd5
commit c94b9e5e58
27 changed files with 2067 additions and 555 deletions
@@ -8,7 +8,6 @@ library;
import '../../core/error_codes.dart';
import '../../core/error_l10n.dart';
import '../../l10n/app_localizations.dart';
import '../albums/models.dart';
import 'preparer.dart';
import 'task_state.dart';
import 'upload_engine.dart';
@@ -16,16 +15,16 @@ import 'upload_engine.dart';
extension AppLocalizationsUploadX on AppLocalizations {
/// 任务状态标签(chip/文案)。
String labelForTaskState(UploadTaskState state) => switch (state) {
UploadTaskState.preparing => taskStatePreparing,
UploadTaskState.preparationFailed => taskStatePreparationFailed,
UploadTaskState.queued => taskStateQueued,
UploadTaskState.uploading => taskStateUploading,
UploadTaskState.uploadedConfirming => taskStateUploadedConfirming,
UploadTaskState.completed => taskStateCompleted,
UploadTaskState.waitingNetwork => taskStateWaitingNetwork,
UploadTaskState.retryableFailed => taskStateRetryableFailed,
UploadTaskState.cancelled => taskStateCancelled,
};
UploadTaskState.preparing => taskStatePreparing,
UploadTaskState.preparationFailed => taskStatePreparationFailed,
UploadTaskState.queued => taskStateQueued,
UploadTaskState.uploading => taskStateUploading,
UploadTaskState.uploadedConfirming => taskStateUploadedConfirming,
UploadTaskState.completed => taskStateCompleted,
UploadTaskState.waitingNetwork => taskStateWaitingNetwork,
UploadTaskState.retryableFailed => taskStateRetryableFailed,
UploadTaskState.cancelled => taskStateCancelled,
};
/// 任务 lastError → 展示文案(上传域伪码 + 契约码;未映射回退
/// error_l10n 的通用解析)。
@@ -52,24 +51,3 @@ extension AppLocalizationsUploadX on AppLocalizations {
}
}
}
/// 相册展示标题解析:当前 locale → 相册默认语言 → 首条 → 相册 ID。
///
/// locale 匹配按语言前缀(App locale `zh`/`en` vs 契约 `zh-CN`/`en`)。
String albumDisplayTitle(AlbumSummary album, String localeName) {
final lang = localeName.split('-').first.toLowerCase();
AlbumTranslation? match;
for (final t in album.translations) {
if (t.locale.toLowerCase() == localeName.toLowerCase() ||
t.locale.toLowerCase().split('-').first == lang) {
match = t;
break;
}
}
if (match != null) return match.title;
for (final t in album.translations) {
if (t.locale == album.defaultLocale) return t.title;
}
if (album.translations.isNotEmpty) return album.translations.first.title;
return album.id;
}