|
|
@@ -11,9 +11,6 @@ enum AppLanguageManager {
|
|
|
/// UI languages shown in Settings → Language (order preserved).
|
|
|
private static let supportedLanguageCodes = ["en", "fr", "fr-CA", "es-ES", "es-MX", "de", "it", "nl", "pl", "sv", "nb", "fi", "el", "he", "ar", "ko", "pt-BR", "ru", "uk", "vi", "zh-Hans", "zh-Hant"]
|
|
|
|
|
|
- /// `representedObject` for Settings → Language when following the system locale.
|
|
|
- static let systemLanguagePopupIdentifier = ""
|
|
|
-
|
|
|
/// `nil` follows the system language; otherwise uses the selected `.lproj` code.
|
|
|
static var selectedLanguageCode: String? {
|
|
|
get {
|
|
|
@@ -36,6 +33,34 @@ enum AppLanguageManager {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// Language code shown in Settings → Language when no explicit choice is stored.
|
|
|
+ static var pickerSelectedLanguageCode: String {
|
|
|
+ if let code = selectedLanguageCode {
|
|
|
+ return code
|
|
|
+ }
|
|
|
+ return bestMatchingAvailableLanguageCode() ?? availableLanguageCodes.first ?? "en"
|
|
|
+ }
|
|
|
+
|
|
|
+ private static func bestMatchingAvailableLanguageCode() -> String? {
|
|
|
+ let available = availableLanguageCodes
|
|
|
+ guard available.isEmpty == false else { return nil }
|
|
|
+
|
|
|
+ func match(_ identifier: String) -> String? {
|
|
|
+ let normalized = identifier.replacingOccurrences(of: "_", with: "-")
|
|
|
+ if available.contains(normalized) { return normalized }
|
|
|
+ let base = normalized.split(separator: "-").first.map(String.init) ?? normalized
|
|
|
+ if available.contains(base) { return base }
|
|
|
+ return available.first { code in
|
|
|
+ code.split(separator: "-").first.map(String.init) == base
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for preferred in Locale.preferredLanguages {
|
|
|
+ if let code = match(preferred) { return code }
|
|
|
+ }
|
|
|
+ return match(Locale.current.identifier)
|
|
|
+ }
|
|
|
+
|
|
|
static var localizationBundle: Bundle {
|
|
|
guard let code = selectedLanguageCode,
|
|
|
let path = Bundle.main.path(forResource: code, ofType: "lproj"),
|