|
| 1 | +using System.Collections.Generic; |
| 2 | +using System.ComponentModel; |
| 3 | +using System.Runtime.CompilerServices; |
| 4 | + |
| 5 | +namespace GeneralUpdate.Tools.Services; |
| 6 | + |
| 7 | +/// <summary> |
| 8 | +/// Simple dictionary-based localization. Supports zh-CN and en-US. |
| 9 | +/// Usage: LocalizationService.Instance["Patch.Title"] |
| 10 | +/// </summary> |
| 11 | +public class LocalizationService : INotifyPropertyChanged |
| 12 | +{ |
| 13 | + public static LocalizationService Instance { get; } = new(); |
| 14 | + |
| 15 | + private string _locale = "zh-CN"; |
| 16 | + |
| 17 | + public string Locale |
| 18 | + { |
| 19 | + get => _locale; |
| 20 | + set { if (_locale != value) { _locale = value; OnPropertyChanged(); OnPropertyChanged("Item"); } } |
| 21 | + } |
| 22 | + |
| 23 | + public string this[string key] |
| 24 | + { |
| 25 | + get |
| 26 | + { |
| 27 | + if (_strings.TryGetValue(_locale, out var langDict) && langDict.TryGetValue(key, out var val)) |
| 28 | + return val; |
| 29 | + // Fallback to zh-CN |
| 30 | + if (_locale != "zh-CN" && _strings.TryGetValue("zh-CN", out var fallback) && fallback.TryGetValue(key, out var fb)) |
| 31 | + return fb; |
| 32 | + return key; |
| 33 | + } |
| 34 | + } |
| 35 | + |
| 36 | + private readonly Dictionary<string, Dictionary<string, string>> _strings = new() |
| 37 | + { |
| 38 | + ["zh-CN"] = new() |
| 39 | + { |
| 40 | + ["App.Title"] = "GeneralUpdate Tools", |
| 41 | + ["Nav.Patch"] = "补丁包", |
| 42 | + ["Nav.Extension"] = "扩展包", |
| 43 | + ["Nav.OSS"] = "OSS配置", |
| 44 | + ["Patch.Title"] = "补丁包生成", |
| 45 | + ["Patch.CorePaths"] = "核心路径", |
| 46 | + ["Patch.OldDir"] = "旧版本目录", |
| 47 | + ["Patch.NewDir"] = "新版本目录", |
| 48 | + ["Patch.Select"] = "选择", |
| 49 | + ["Patch.OldPlaceholder"] = "选择旧版本应用目录...", |
| 50 | + ["Patch.NewPlaceholder"] = "选择新版本发布目录...", |
| 51 | + ["Patch.PackageInfo"] = "包信息", |
| 52 | + ["Patch.PackageName"] = "包名", |
| 53 | + ["Patch.Version"] = "版本", |
| 54 | + ["Patch.OutputDir"] = "输出目录", |
| 55 | + ["Patch.OutputPlaceholder"] = "桌面 (默认)", |
| 56 | + ["Patch.Build"] = "开始构建", |
| 57 | + ["Patch.Ready"] = "就绪", |
| 58 | + ["Patch.ValidateDirs"] = "请选择新旧版本目录", |
| 59 | + ["Patch.Building"] = "正在生成差分补丁...", |
| 60 | + ["Patch.Comparing"] = "对比目录差异 + 生成 BSDiff40 补丁...", |
| 61 | + ["Patch.PatchDone"] = "补丁生成完成", |
| 62 | + ["Patch.Packing"] = "打包: {0}", |
| 63 | + ["Patch.Success"] = "成功: {0} ({1:F1} KB)", |
| 64 | + ["Patch.Failed"] = "失败: {0}", |
| 65 | + ["Patch.Error"] = "错误: {0}", |
| 66 | + ["Patch.OldSelected"] = "旧版本: {0}", |
| 67 | + ["Patch.NewSelected"] = "新版本: {0}", |
| 68 | + ["Patch.TempDir"] = "临时目录: {0}", |
| 69 | + ["Ext.Title"] = "扩展包生成", |
| 70 | + ["Ext.BasicInfo"] = "基本信息", |
| 71 | + ["Ext.Name"] = "名称", |
| 72 | + ["Ext.Version"] = "版本", |
| 73 | + ["Ext.Description"] = "描述", |
| 74 | + ["Ext.DescPlaceholder"] = "扩展功能描述...", |
| 75 | + ["Ext.Publisher"] = "发布者", |
| 76 | + ["Ext.License"] = "许可证", |
| 77 | + ["Ext.LicensePlaceholder"] = "MIT", |
| 78 | + ["Ext.Paths"] = "路径", |
| 79 | + ["Ext.ExtDir"] = "扩展目录", |
| 80 | + ["Ext.ExportDir"] = "导出目录", |
| 81 | + ["Ext.CustomProps"] = "自定义属性", |
| 82 | + ["Ext.Key"] = "Key", |
| 83 | + ["Ext.Value"] = "Value", |
| 84 | + ["Ext.AddProp"] = "+ 添加", |
| 85 | + ["Ext.Generate"] = "生成扩展包", |
| 86 | + ["Ext.ValidateNameVer"] = "请填写扩展名称和版本", |
| 87 | + ["Ext.ValidateDir"] = "请选择有效的扩展目录", |
| 88 | + ["Ext.Building"] = "正在生成扩展包...", |
| 89 | + ["Ext.Success"] = "成功: {0}", |
| 90 | + ["Ext.Failed"] = "失败: {0}", |
| 91 | + ["OSS.Title"] = "OSS 配置生成", |
| 92 | + ["OSS.NewEntry"] = "新建条目", |
| 93 | + ["OSS.PacketName"] = "包名", |
| 94 | + ["OSS.Version"] = "版本", |
| 95 | + ["OSS.Url"] = "URL", |
| 96 | + ["OSS.SHA256"] = "SHA256", |
| 97 | + ["OSS.ComputeHash"] = "计算", |
| 98 | + ["OSS.AddToList"] = "添加到列表", |
| 99 | + ["OSS.ConfigList"] = "配置列表", |
| 100 | + ["OSS.Clear"] = "清空", |
| 101 | + ["OSS.Export"] = "导出 JSON", |
| 102 | + ["OSS.Added"] = "已添加", |
| 103 | + ["OSS.Cleared"] = "已清空", |
| 104 | + ["OSS.Exported"] = "导出: {0} 条", |
| 105 | + ["OSS.HashResult"] = "SHA256: {0}", |
| 106 | + ["Theme.Light"] = "浅色", |
| 107 | + ["Theme.Dark"] = "深色", |
| 108 | + ["Theme.Toggle"] = "切换主题", |
| 109 | + }, |
| 110 | + ["en-US"] = new() |
| 111 | + { |
| 112 | + ["App.Title"] = "GeneralUpdate Tools", |
| 113 | + ["Nav.Patch"] = "Patch", |
| 114 | + ["Nav.Extension"] = "Extension", |
| 115 | + ["Nav.OSS"] = "OSS Config", |
| 116 | + ["Patch.Title"] = "Patch Package", |
| 117 | + ["Patch.CorePaths"] = "Core Paths", |
| 118 | + ["Patch.OldDir"] = "Old Directory", |
| 119 | + ["Patch.NewDir"] = "New Directory", |
| 120 | + ["Patch.Select"] = "Select", |
| 121 | + ["Patch.OldPlaceholder"] = "Select old version directory...", |
| 122 | + ["Patch.NewPlaceholder"] = "Select new version directory...", |
| 123 | + ["Patch.PackageInfo"] = "Package Info", |
| 124 | + ["Patch.PackageName"] = "Package Name", |
| 125 | + ["Patch.Version"] = "Version", |
| 126 | + ["Patch.OutputDir"] = "Output Directory", |
| 127 | + ["Patch.OutputPlaceholder"] = "Desktop (default)", |
| 128 | + ["Patch.Build"] = "Build", |
| 129 | + ["Patch.Ready"] = "Ready", |
| 130 | + ["Patch.ValidateDirs"] = "Please select both old and new directories", |
| 131 | + ["Patch.Building"] = "Generating diff patch...", |
| 132 | + ["Patch.Comparing"] = "Comparing directories + generating BSDiff40 patches...", |
| 133 | + ["Patch.PatchDone"] = "Patch generation complete", |
| 134 | + ["Patch.Packing"] = "Packing: {0}", |
| 135 | + ["Patch.Success"] = "Success: {0} ({1:F1} KB)", |
| 136 | + ["Patch.Failed"] = "Failed: {0}", |
| 137 | + ["Patch.Error"] = "Error: {0}", |
| 138 | + ["Patch.OldSelected"] = "Old version: {0}", |
| 139 | + ["Patch.NewSelected"] = "New version: {0}", |
| 140 | + ["Patch.TempDir"] = "Temp directory: {0}", |
| 141 | + ["Ext.Title"] = "Extension Package", |
| 142 | + ["Ext.BasicInfo"] = "Basic Info", |
| 143 | + ["Ext.Name"] = "Name", |
| 144 | + ["Ext.Version"] = "Version", |
| 145 | + ["Ext.Description"] = "Description", |
| 146 | + ["Ext.DescPlaceholder"] = "Extension description...", |
| 147 | + ["Ext.Publisher"] = "Publisher", |
| 148 | + ["Ext.License"] = "License", |
| 149 | + ["Ext.LicensePlaceholder"] = "MIT", |
| 150 | + ["Ext.Paths"] = "Paths", |
| 151 | + ["Ext.ExtDir"] = "Extension Directory", |
| 152 | + ["Ext.ExportDir"] = "Export Directory", |
| 153 | + ["Ext.CustomProps"] = "Custom Properties", |
| 154 | + ["Ext.Key"] = "Key", |
| 155 | + ["Ext.Value"] = "Value", |
| 156 | + ["Ext.AddProp"] = "+ Add", |
| 157 | + ["Ext.Generate"] = "Generate Extension", |
| 158 | + ["Ext.ValidateNameVer"] = "Please fill in extension name and version", |
| 159 | + ["Ext.ValidateDir"] = "Please select a valid extension directory", |
| 160 | + ["Ext.Building"] = "Generating extension package...", |
| 161 | + ["Ext.Success"] = "Success: {0}", |
| 162 | + ["Ext.Failed"] = "Failed: {0}", |
| 163 | + ["OSS.Title"] = "OSS Config Generator", |
| 164 | + ["OSS.NewEntry"] = "New Entry", |
| 165 | + ["OSS.PacketName"] = "Package Name", |
| 166 | + ["OSS.Version"] = "Version", |
| 167 | + ["OSS.Url"] = "URL", |
| 168 | + ["OSS.SHA256"] = "SHA256", |
| 169 | + ["OSS.ComputeHash"] = "Compute", |
| 170 | + ["OSS.AddToList"] = "Add to List", |
| 171 | + ["OSS.ConfigList"] = "Config List", |
| 172 | + ["OSS.Clear"] = "Clear", |
| 173 | + ["OSS.Export"] = "Export JSON", |
| 174 | + ["OSS.Added"] = "Added", |
| 175 | + ["OSS.Cleared"] = "Cleared", |
| 176 | + ["OSS.Exported"] = "Exported: {0} entries", |
| 177 | + ["OSS.HashResult"] = "SHA256: {0}", |
| 178 | + ["Theme.Light"] = "Light", |
| 179 | + ["Theme.Dark"] = "Dark", |
| 180 | + ["Theme.Toggle"] = "Toggle Theme", |
| 181 | + } |
| 182 | + }; |
| 183 | + |
| 184 | + public event PropertyChangedEventHandler? PropertyChanged; |
| 185 | + private void OnPropertyChanged([CallerMemberName] string? name = null) => |
| 186 | + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); |
| 187 | + |
| 188 | + public string T(string key) => this[key]; |
| 189 | + public string T(string key, params object[] args) => string.Format(this[key], args); |
| 190 | +} |
0 commit comments