-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLocalizationService.cs
More file actions
106 lines (89 loc) · 3.31 KB
/
Copy pathLocalizationService.cs
File metadata and controls
106 lines (89 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System.IO;
using System.Text.Json;
namespace OpenSnap;
/// <summary>
/// Lightweight localization service. Loads JSON translation files from
/// Resources/Lang/{code}.json and provides string lookups via GetString().
/// Falls back to English for any missing key.
/// </summary>
public sealed class LocalizationService
{
private static readonly string LangDir = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "Resources", "Lang");
private readonly Dictionary<string, string> _strings = new();
private string _currentCode;
/// <summary>Supported language codes.</summary>
public static readonly (string Code, string Name)[] Languages =
[
("en", "English"),
("fr", "Français"),
("de", "Deutsch"),
("es", "Español"),
("ja", "日本語"),
];
public string CurrentCode => _currentCode;
/// <summary>Fired when the language changes so windows can refresh.</summary>
public event Action? LanguageChanged;
public LocalizationService(string languageCode = "en")
{
_currentCode = languageCode;
LoadLanguage(languageCode);
}
public void SetLanguage(string code)
{
if (code == _currentCode) return;
_currentCode = code;
LoadLanguage(code);
LanguageChanged?.Invoke();
}
private void LoadLanguage(string code)
{
_strings.Clear();
// Always load English as base (fallback)
LoadFile("en");
// Load the target language on top (overrides)
if (code != "en")
LoadFile(code);
}
private void LoadFile(string code)
{
try
{
// Try app directory first (published), then repo source
var paths = new[]
{
Path.Combine(LangDir, $"{code}.json"),
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Lang", $"{code}.json"),
};
foreach (var path in paths)
{
if (!File.Exists(path)) continue;
var json = File.ReadAllText(path);
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
if (dict is null) continue;
foreach (var (key, value) in dict)
_strings[key] = value;
return;
}
}
catch { /* best-effort — fall through to empty */ }
}
/// <summary>Get a localized string. Falls back to key if not found.</summary>
public string GetString(string key) =>
_strings.TryGetValue(key, out var value) ? value : key;
/// <summary>Get a localized string with format arguments.</summary>
public string Format(string key, params object[] args)
{
var fmt = GetString(key);
try { return string.Format(fmt, args); }
catch { return fmt; }
}
// ── Loader helper for App.xaml.cs ─────────────────────────────────
/// <summary>Create from a persisted language code (validates + falls back).</summary>
public static LocalizationService FromCode(string? code)
{
if (code is not null && Languages.Any(l => l.Code == code))
return new LocalizationService(code);
return new LocalizationService("en");
}
}