Răsfoiți Sursa

Remove System Language option from the settings language picker.

Users now choose an explicit app language only, with the picker defaulting to the best match for the system locale when no preference is saved.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 lună în urmă
părinte
comite
99f7e1f6b6

+ 28 - 3
meetings_app/Localization/AppLanguageManager.swift

@@ -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"),

+ 4 - 13
meetings_app/ViewController.swift

@@ -4667,17 +4667,12 @@ private extension ViewController {
         popup.target = self
         popup.action = #selector(settingsPageAppLanguageChanged(_:))
 
-        popup.addItem(withTitle: "System Language".localized)
-        popup.lastItem?.representedObject = AppLanguageManager.systemLanguagePopupIdentifier
-
         for code in AppLanguageManager.availableLanguageCodes {
             popup.addItem(withTitle: AppLanguageManager.displayName(for: code))
             popup.lastItem?.representedObject = code
         }
 
-        let selectedIdentifier = AppLanguageManager.selectedLanguageCode
-            ?? AppLanguageManager.systemLanguagePopupIdentifier
-        selectSettingsPageLanguage(identifier: selectedIdentifier, in: popup)
+        selectSettingsPageLanguage(identifier: AppLanguageManager.pickerSelectedLanguageCode, in: popup)
         settingsPageAppLanguagePopup = popup
 
         row.addSubview(titleLabel)
@@ -4759,13 +4754,9 @@ private extension ViewController {
     }
 
     @objc private func settingsPageAppLanguageChanged(_ sender: NSPopUpButton) {
-        let identifier = sender.selectedItem?.representedObject as? String
-            ?? AppLanguageManager.systemLanguagePopupIdentifier
-        if identifier.isEmpty {
-            AppLanguageManager.setLanguage(code: nil)
-        } else {
-            AppLanguageManager.setLanguage(code: identifier)
-        }
+        guard let identifier = sender.selectedItem?.representedObject as? String,
+              identifier.isEmpty == false else { return }
+        AppLanguageManager.setLanguage(code: identifier)
         reloadTheme()
     }