From 6d8a3a85a6ceeda755060dc3b7c0d3a43294edda Mon Sep 17 00:00:00 2001 From: empty Date: Sat, 3 Jan 2026 22:19:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=20HomeView=20?= =?UTF-8?q?=E5=9B=BD=E9=99=85=E5=8C=96=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 LanguageManager 支持应用内语言切换 - 新增 Localizable.xcstrings 包含 78 个翻译键 - 修复 HomeView 硬编码文本,改用 String(localized:) - 支持简体中文、繁体中文、英文三种语言 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../to-live-photo/LanguageManager.swift | 88 + .../to-live-photo/Localizable.xcstrings | 1880 +++++++++++++++++ .../to-live-photo/Views/HomeView.swift | 26 +- 3 files changed, 1981 insertions(+), 13 deletions(-) create mode 100644 to-live-photo/to-live-photo/LanguageManager.swift create mode 100644 to-live-photo/to-live-photo/Localizable.xcstrings diff --git a/to-live-photo/to-live-photo/LanguageManager.swift b/to-live-photo/to-live-photo/LanguageManager.swift new file mode 100644 index 0000000..483793a --- /dev/null +++ b/to-live-photo/to-live-photo/LanguageManager.swift @@ -0,0 +1,88 @@ +import SwiftUI + +/// 语言管理器:支持应用内动态切换语言 +@Observable +final class LanguageManager { + + /// 支持的语言 + enum Language: String, CaseIterable, Identifiable { + case system = "system" + case zhHans = "zh-Hans" + case zhHant = "zh-Hant" + case en = "en" + + var id: String { rawValue } + + var displayName: String { + switch self { + case .system: return "跟随系统" + case .zhHans: return "简体中文" + case .zhHant: return "繁體中文" + case .en: return "English" + } + } + + var locale: Locale? { + switch self { + case .system: return nil + case .zhHans: return Locale(identifier: "zh-Hans") + case .zhHant: return Locale(identifier: "zh-Hant") + case .en: return Locale(identifier: "en") + } + } + } + + /// 单例 + static let shared = LanguageManager() + + /// 当前选择的语言 + var current: Language { + didSet { + UserDefaults.standard.set(current.rawValue, forKey: "app_language") + applyLanguage() + } + } + + /// 可用语言列表 + var availableLanguages: [Language] { + Language.allCases + } + + private init() { + let savedLanguage = UserDefaults.standard.string(forKey: "app_language") ?? "system" + self.current = Language(rawValue: savedLanguage) ?? .system + applyLanguage() + } + + /// 应用语言设置 + private func applyLanguage() { + if current == .system { + UserDefaults.standard.removeObject(forKey: "AppleLanguages") + } else { + UserDefaults.standard.set([current.rawValue], forKey: "AppleLanguages") + } + UserDefaults.standard.synchronize() + } + + /// 获取本地化字符串 + func localizedString(_ key: String) -> String { + if current == .system { + return String(localized: String.LocalizationValue(key)) + } + + guard let path = Bundle.main.path(forResource: current.rawValue, ofType: "lproj"), + let bundle = Bundle(path: path) else { + return String(localized: String.LocalizationValue(key)) + } + + return NSLocalizedString(key, bundle: bundle, comment: "") + } +} + +// MARK: - 便捷扩展 +extension String { + /// 本地化字符串 + var localized: String { + LanguageManager.shared.localizedString(self) + } +} diff --git a/to-live-photo/to-live-photo/Localizable.xcstrings b/to-live-photo/to-live-photo/Localizable.xcstrings new file mode 100644 index 0000000..aa6f02d --- /dev/null +++ b/to-live-photo/to-live-photo/Localizable.xcstrings @@ -0,0 +1,1880 @@ +{ + "sourceLanguage" : "zh-Hans", + "strings" : { + "home.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo Maker" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo 制作器" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo 製作器" + } + } + } + }, + "home.selectVideo" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select Video" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择视频" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇影片" + } + } + } + }, + "home.recentWorks" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recent Works" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最近作品" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "最近作品" + } + } + } + }, + "home.subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select video to create dynamic wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择视频,一键转换为动态壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇影片,一鍵轉換為動態桌布" + } + } + } + }, + "home.loading" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Loading video..." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在加载视频..." + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在載入影片..." + } + } + } + }, + "home.quickStart" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quick Start" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "快速上手" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "快速上手" + } + } + } + }, + "home.quickStart.step1" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tap \"Select Video\" above to import" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "点击上方「选择视频」导入素材" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "點擊上方「選擇影片」匯入素材" + } + } + } + }, + "home.quickStart.step2" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Adjust ratio and duration, select cover" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "调整比例和时长,选择封面帧" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "調整比例和時長,選擇封面幀" + } + } + } + }, + "home.quickStart.step3" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable AI enhancement (optional)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "开启 AI 增强提升画质(可选)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開啟 AI 增強提升畫質(可選)" + } + } + } + }, + "home.quickStart.step4" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generate and follow guide to set wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "生成后按引导设置为壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "產生後按指引設定為桌布" + } + } + } + }, + "home.emptyHint" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Your completed works will appear here" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成后的作品会显示在这里" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成後的作品會顯示在這裡" + } + } + } + }, + "home.worksCount" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld items" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld 个" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "%lld 個" + } + } + } + }, + "home.loadFailed" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unable to load video" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "无法加载视频" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "無法載入影片" + } + } + } + }, + "editor.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "编辑" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "編輯" + } + } + } + }, + "editor.duration" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Duration" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "时长" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "時長" + } + } + } + }, + "editor.aspectRatio" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aspect Ratio" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "画面比例" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "畫面比例" + } + } + } + }, + "editor.coverFrame" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cover Frame" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "封面帧" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "封面幀" + } + } + } + }, + "editor.aiEnhance" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI Super Resolution" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI 超分辨率" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI 超解析度" + } + } + } + }, + "editor.aiEnhance.subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Use AI to enhance cover quality" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用 AI 提升封面画质" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用 AI 提升封面畫質" + } + } + } + }, + "editor.aiEnhance.resolution" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Resolution increased by ~2x" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "分辨率提升约 2 倍" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "解析度提升約 2 倍" + } + } + } + }, + "editor.aiEnhance.time" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Processing time: ~2-3 seconds" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "处理时间:约 2-3 秒" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "處理時間:約 2-3 秒" + } + } + } + }, + "editor.aiEnhance.local" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Local AI processing, no network needed" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "本地 AI 处理,无需网络" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "本機 AI 處理,無需網路" + } + } + } + }, + "editor.aiEnhance.notSupported" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI enhancement not supported on this device" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "当前设备不支持 AI 增强" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "目前設備不支援 AI 增強" + } + } + } + }, + "editor.aiEnhance.downloading" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Downloading AI model..." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在下载 AI 模型..." + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在下載 AI 模型..." + } + } + } + }, + "editor.aiEnhance.downloadHint" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "First use requires AI model download (~64MB)" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "首次使用需下载 AI 模型(约 64MB)" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "首次使用需下載 AI 模型(約 64MB)" + } + } + } + }, + "editor.compatibilityMode" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wallpaper Mode" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "壁纸兼容模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "桌布相容模式" + } + } + } + }, + "editor.compatibilityMode.subtitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Optimized for lock screen wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "针对锁屏动态壁纸优化" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "針對鎖定畫面動態桌布優化" + } + } + } + }, + "editor.generate" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generate Live Photo" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "生成 Live Photo" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "產生 Live Photo" + } + } + } + }, + "processing.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Processing" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "处理中" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "處理中" + } + } + } + }, + "processing.generating" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generating Live Photo..." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在生成 Live Photo..." + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "正在產生 Live Photo..." + } + } + } + }, + "result.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Complete" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成" + } + } + } + }, + "result.success" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo saved to album!" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo 已保存到相册!" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "Live Photo 已儲存到相簿!" + } + } + } + }, + "result.setWallpaper" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set as Wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设为壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "設為桌布" + } + } + } + }, + "result.createAnother" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Create Another" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "再做一个" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "再做一個" + } + } + } + }, + "settings.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Settings" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "設定" + } + } + } + }, + "settings.language" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "语言" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "語言" + } + } + } + }, + "settings.appLanguage" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "应用语言" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "應用程式語言" + } + } + } + }, + "settings.languageChangeHint" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Restart app for changes to take effect" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "重启应用后生效" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "重新啟動應用程式後生效" + } + } + } + }, + "settings.photoPermission" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Photo Library Permission" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "相册权限" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "相簿權限" + } + } + } + }, + "settings.authorized" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authorized" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "已授权" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "已授權" + } + } + } + }, + "settings.limited" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Limited" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "部分授权" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "部分授權" + } + } + } + }, + "settings.denied" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Denied" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "未授权" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "未授權" + } + } + } + }, + "settings.storage" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Storage" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "存储" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "儲存空間" + } + } + } + }, + "settings.cacheSize" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cache Size" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "缓存大小" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "快取大小" + } + } + } + }, + "settings.clearCache" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear Cache" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "清理缓存" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除快取" + } + } + } + }, + "settings.clearRecentWorks" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clear Recent Works" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "清空最近作品记录" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除最近作品記錄" + } + } + } + }, + "settings.storageFooter" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clearing cache won't affect Live Photos saved to album" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "清理缓存不会影响已保存到相册的 Live Photo" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除快取不會影響已儲存到相簿的 Live Photo" + } + } + } + }, + "settings.feedback" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Feedback" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "反馈" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "反饋" + } + } + } + }, + "settings.exportDiagnostics" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Export Diagnostics" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "导出诊断报告" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "匯出診斷報告" + } + } + } + }, + "settings.feedbackFooter" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diagnostics contain only logs and parameters, no media content" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "诊断报告仅包含日志和参数,不含媒体内容" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "診斷報告僅包含日誌和參數,不含媒體內容" + } + } + } + }, + "settings.about" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "About" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "关于" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "關於" + } + } + } + }, + "settings.version" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "版本" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "版本" + } + } + } + }, + "settings.privacyPolicy" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Privacy Policy" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐私政策" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "隱私權政策" + } + } + } + }, + "settings.termsOfService" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Terms of Service" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用条款" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "使用條款" + } + } + } + }, + "onboarding.selectVideo.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select Video" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择视频" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇影片" + } + } + } + }, + "onboarding.selectVideo.description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select your favorite video clip from album\nSupports various formats and resolutions" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "从相册选择你喜欢的视频片段\n支持各种格式和分辨率" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "從相簿選擇你喜歡的影片片段\n支援各種格式和解析度" + } + } + } + }, + "onboarding.edit.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Edit & Adjust" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "编辑调整" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "編輯調整" + } + } + } + }, + "onboarding.edit.description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Choose aspect ratio, adjust duration\nPick the best cover frame" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择比例模板、调整时长\n挑选最佳封面帧" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇比例模板、調整時長\n挑選最佳封面幀" + } + } + } + }, + "onboarding.aiEnhance.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI Enhancement" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI 增强" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "AI 增強" + } + } + } + }, + "onboarding.aiEnhance.description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable AI super resolution\nEnhance cover quality for clearer wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "开启 AI 超分辨率\n提升封面画质,让壁纸更清晰" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開啟 AI 超解析度\n提升封面畫質,讓桌布更清晰" + } + } + } + }, + "onboarding.generate.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generate Wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "生成壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "產生桌布" + } + } + } + }, + "onboarding.generate.description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Generate Live Photo with one tap\nFollow guide to set as dynamic lock screen wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "一键生成 Live Photo\n按引导设置为动态锁屏壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "一鍵產生 Live Photo\n按指引設定為動態鎖定畫面桌布" + } + } + } + }, + "onboarding.next" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Next" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "下一步" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "下一步" + } + } + } + }, + "onboarding.getStarted" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Get Started" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "开始使用" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開始使用" + } + } + } + }, + "onboarding.skip" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skip" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "跳过" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "略過" + } + } + } + }, + "common.cancel" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancel" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "取消" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "取消" + } + } + } + }, + "common.confirm" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirm" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "确认" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "確認" + } + } + } + }, + "common.delete" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "删除" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "刪除" + } + } + } + }, + "common.done" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Done" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "完成" + } + } + } + }, + "common.error" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "错误" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "錯誤" + } + } + } + }, + "common.retry" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Retry" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "重试" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "重試" + } + } + } + }, + "common.calculating" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Calculating..." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "计算中..." + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "計算中..." + } + } + } + }, + "wallpaperGuide.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set as Wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设为壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "設為桌布" + } + } + } + }, + "wallpaperGuide.step1" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Photos app and find the Live Photo" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "打开相册,找到刚才生成的 Live Photo" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開啟相簿,找到剛剛產生的 Live Photo" + } + } + } + }, + "wallpaperGuide.step2" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tap Share button → Use as Wallpaper" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "点击分享按钮 → 用作壁纸" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "點擊分享按鈕 → 用作桌布" + } + } + } + }, + "wallpaperGuide.step3" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Select 'Lock Screen' and confirm settings" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择「锁定屏幕」,确认设置" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇「鎖定畫面」,確認設定" + } + } + } + }, + "wallpaperGuide.tip" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Long press lock screen to see the animation!" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "长按锁屏即可看到动态效果!" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "長按鎖定畫面即可看到動態效果!" + } + } + } + }, + "wallpaperGuide.openPhotos" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Open Photos" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "打开相册" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "開啟相簿" + } + } + } + }, + "settings.permission" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Permissions" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "权限" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "權限" } } + } + }, + "settings.permissionFooter" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Photo library permission is required to save Live Photo" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "需要相册权限才能保存 Live Photo" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "需要相簿權限才能儲存 Live Photo" } } + } + }, + "settings.goToSettings" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Go to Settings" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "前往设置授权" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "前往設定授權" } } + } + }, + "settings.notDetermined" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Not Determined" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "未确定" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "未確定" } } + } + }, + "settings.contactUs" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Contact Us" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "反馈问题" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "反饋問題" } } + } + }, + "settings.rateApp" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Rate on App Store" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "App Store 评分" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "App Store 評分" } } + } + }, + "settings.clear" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Clear" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "清理" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "清除" } } + } + }, + "settings.clearCacheConfirm" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Are you sure you want to clear all cache files?" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "确定要清理所有缓存文件吗?" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "確定要清除所有快取檔案嗎?" } } + } + }, + "settings.clearRecordsTitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Clear Records" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "清空记录" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "清除記錄" } } + } + }, + "settings.clearRecordsConfirm" : { + "extractionState" : "manual", + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Are you sure you want to clear recent works? This won't delete Live Photos in album." } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "确定要清空最近作品记录吗?这不会删除相册中的 Live Photo。" } }, + "zh-Hant" : { "stringUnit" : { "state" : "translated", "value" : "確定要清除最近作品記錄嗎?這不會刪除相簿中的 Live Photo。" } } + } + } + }, + "version" : "1.0" +} diff --git a/to-live-photo/to-live-photo/Views/HomeView.swift b/to-live-photo/to-live-photo/Views/HomeView.swift index c00f633..9b0ad7c 100644 --- a/to-live-photo/to-live-photo/Views/HomeView.swift +++ b/to-live-photo/to-live-photo/Views/HomeView.swift @@ -71,11 +71,11 @@ struct HomeView: View { } VStack(spacing: DesignTokens.Spacing.sm) { - Text("Live Photo 制作") + Text(String(localized: "home.title")) .font(.system(size: DesignTokens.FontSize.xxl, weight: .bold)) .foregroundColor(.textPrimary) - Text("选择视频,一键转换为动态壁纸") + Text(String(localized: "home.subtitle")) .font(.system(size: DesignTokens.FontSize.base)) .foregroundColor(.textSecondary) .multilineTextAlignment(.center) @@ -90,7 +90,7 @@ struct HomeView: View { HStack(spacing: DesignTokens.Spacing.sm) { Image(systemName: "video.badge.plus") .font(.system(size: 18, weight: .semibold)) - Text("选择视频") + Text(String(localized: "home.selectVideo")) .font(.system(size: DesignTokens.FontSize.base, weight: .semibold)) } .foregroundColor(.white) @@ -111,7 +111,7 @@ struct HomeView: View { HStack(spacing: DesignTokens.Spacing.sm) { ProgressView() .tint(.accentPurple) - Text("正在加载视频...") + Text(String(localized: "home.loading")) .font(.system(size: DesignTokens.FontSize.sm)) .foregroundColor(.textSecondary) } @@ -149,7 +149,7 @@ struct HomeView: View { .foregroundColor(.accentOrange) } - Text("快速上手") + Text(String(localized: "home.quickStart")) .font(.system(size: DesignTokens.FontSize.lg, weight: .semibold)) .foregroundColor(.textPrimary) @@ -157,15 +157,15 @@ struct HomeView: View { } VStack(alignment: .leading, spacing: DesignTokens.Spacing.md) { - QuickStartStep(number: 1, text: "点击上方「选择视频」导入素材", color: .accentPurple) - QuickStartStep(number: 2, text: "调整比例和时长,选择封面帧", color: .accentCyan) - QuickStartStep(number: 3, text: "开启 AI 增强提升画质(可选)", color: .accentPink) - QuickStartStep(number: 4, text: "生成后按引导设置为壁纸", color: .accentGreen) + QuickStartStep(number: 1, text: String(localized: "home.quickStart.step1"), color: .accentPurple) + QuickStartStep(number: 2, text: String(localized: "home.quickStart.step2"), color: .accentCyan) + QuickStartStep(number: 3, text: String(localized: "home.quickStart.step3"), color: .accentPink) + QuickStartStep(number: 4, text: String(localized: "home.quickStart.step4"), color: .accentGreen) } HStack { Spacer() - Text("完成后的作品会显示在这里") + Text(String(localized: "home.emptyHint")) .font(.system(size: DesignTokens.FontSize.xs)) .foregroundColor(.textMuted) Spacer() @@ -190,13 +190,13 @@ struct HomeView: View { .foregroundColor(.accentCyan) } - Text("最近作品") + Text(String(localized: "home.recentWorks")) .font(.system(size: DesignTokens.FontSize.lg, weight: .semibold)) .foregroundColor(.textPrimary) Spacer() - Text("\(recentWorks.recentWorks.count) 个") + Text(String(localized: "home.worksCount \(recentWorks.recentWorks.count)")) .font(.system(size: DesignTokens.FontSize.sm)) .foregroundColor(.textMuted) } @@ -224,7 +224,7 @@ struct HomeView: View { do { guard let movie = try await item.loadTransferable(type: VideoTransferable.self) else { - errorMessage = "无法加载视频" + errorMessage = String(localized: "home.loadFailed") isLoading = false return }