|
|
@@ -46,12 +46,18 @@ enum AppLanguage: CaseIterable {
|
|
46
|
46
|
if lower.hasPrefix("zh") {
|
|
47
|
47
|
return .chineseSimplified
|
|
48
|
48
|
}
|
|
|
49
|
+ if lower.hasPrefix("en") {
|
|
|
50
|
+ return .english
|
|
|
51
|
+ }
|
|
49
|
52
|
if lower.hasPrefix("fr-ca") {
|
|
50
|
53
|
return .frenchCanada
|
|
51
|
54
|
}
|
|
52
|
55
|
if lower.hasPrefix("fr") {
|
|
53
|
56
|
return .french
|
|
54
|
57
|
}
|
|
|
58
|
+ if lower.hasPrefix("ar") {
|
|
|
59
|
+ return .arabic
|
|
|
60
|
+ }
|
|
55
|
61
|
for language in AppLanguage.allCases where preferred.hasPrefix(language.localeIdentifier) {
|
|
56
|
62
|
return language
|
|
57
|
63
|
}
|
|
|
@@ -86,8 +92,7 @@ func appLocalized(_ key: String, language: AppLanguage) -> String {
|
|
86
|
92
|
}
|
|
87
|
93
|
|
|
88
|
94
|
func currentAppLanguage() -> AppLanguage {
|
|
89
|
|
- let code = UserDefaults.standard.string(forKey: "com.appforindeed.preferredLanguage") ?? "en"
|
|
90
|
|
- return AppLanguage.allCases.first(where: { $0.localeIdentifier == code }) ?? .english
|
|
|
95
|
+ AppLanguageManager.resolvedLanguage
|
|
91
|
96
|
}
|
|
92
|
97
|
|
|
93
|
98
|
/// Resolves copy for the user’s currently selected language.
|
|
|
@@ -206,25 +211,28 @@ final class AppLanguageManager {
|
|
206
|
211
|
|
|
207
|
212
|
static let didChangeNotification = Notification.Name("AppLanguageManager.didChange")
|
|
208
|
213
|
|
|
209
|
|
- private enum UserDefaultsKey {
|
|
210
|
|
- static let preferredLanguage = "com.appforindeed.preferredLanguage"
|
|
|
214
|
+ private static let legacyPreferredLanguageKey = "com.appforindeed.preferredLanguage"
|
|
|
215
|
+
|
|
|
216
|
+ /// Settings override for this run only; cleared on launch so UI follows macOS each time.
|
|
|
217
|
+ nonisolated(unsafe) private static var sessionOverride: AppLanguage?
|
|
|
218
|
+
|
|
|
219
|
+ nonisolated static var resolvedLanguage: AppLanguage {
|
|
|
220
|
+ sessionOverride ?? AppLanguage.systemLanguage
|
|
211
|
221
|
}
|
|
212
|
222
|
|
|
213
|
223
|
var current: AppLanguage {
|
|
214
|
|
- currentAppLanguage()
|
|
|
224
|
+ Self.resolvedLanguage
|
|
215
|
225
|
}
|
|
216
|
226
|
|
|
217
|
227
|
func applyStoredPreferenceOnLaunch() {
|
|
218
|
228
|
// UI copy uses `appLocalized`; do not drive layout from `AppleLanguages` (Arabic forces RTL and breaks CV templates).
|
|
|
229
|
+ Self.sessionOverride = nil
|
|
219
|
230
|
UserDefaults.standard.removeObject(forKey: "AppleLanguages")
|
|
220
|
|
- if UserDefaults.standard.string(forKey: UserDefaultsKey.preferredLanguage) == nil {
|
|
221
|
|
- setLanguage(AppLanguage.systemLanguage, notify: false)
|
|
222
|
|
- }
|
|
|
231
|
+ UserDefaults.standard.removeObject(forKey: Self.legacyPreferredLanguageKey)
|
|
223
|
232
|
}
|
|
224
|
233
|
|
|
225
|
234
|
func setLanguage(_ language: AppLanguage, notify: Bool = true) {
|
|
226
|
|
- let code = language.localeIdentifier
|
|
227
|
|
- UserDefaults.standard.set(code, forKey: UserDefaultsKey.preferredLanguage)
|
|
|
235
|
+ Self.sessionOverride = language
|
|
228
|
236
|
UserDefaults.standard.removeObject(forKey: "AppleLanguages")
|
|
229
|
237
|
if notify {
|
|
230
|
238
|
NotificationCenter.default.post(name: Self.didChangeNotification, object: self)
|