From 9411f391739e205a4bfef4e56d7bf224d213a2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 15 Feb 2026 16:43:07 +0800 Subject: [PATCH] Auto-load language options --- .../Views/Setting/MacAppView.swift | 58 ++++++++++++++++--- Makefile | 3 + SFI/Info.plist | 3 + SFM.System/Info.plist | 5 +- SFM/Info.plist | 3 + SFT/Info.plist | 3 + 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/ApplicationLibrary/Views/Setting/MacAppView.swift b/ApplicationLibrary/Views/Setting/MacAppView.swift index c962e0f..c17915e 100644 --- a/ApplicationLibrary/Views/Setting/MacAppView.swift +++ b/ApplicationLibrary/Views/Setting/MacAppView.swift @@ -7,11 +7,19 @@ import SwiftUI #endif public struct AppView: View { - private static let supportedLanguages: [(code: String?, name: String)] = [ - (nil, String(localized: "System Default")), - ("en", "English"), - ("zh-Hans", "简体中文"), - ] + private struct LanguageOption: Hashable { + let code: String? + let name: String + } + + private static var supportedLanguages: [LanguageOption] { + var options = [LanguageOption(code: nil, name: String(localized: "System Default"))] + options.append(contentsOf: configuredLanguageCodes().map { code in + let name = Locale(identifier: code).localizedString(forIdentifier: code) ?? code + return LanguageOption(code: code, name: name) + }) + return options + } @State private var isLoading = true @State private var selectedLanguage: String? @@ -176,8 +184,12 @@ public struct AppView: View { else { return nil } + let current = canonicalLanguageCode(first) for language in supportedLanguages { - if let code = language.code, first.hasPrefix(code) { + guard let code = language.code else { + continue + } + if current == code || current.hasPrefix("\(code)-") || current.hasPrefix("\(code)_") { return code } } @@ -186,7 +198,7 @@ public struct AppView: View { private func updateLanguage(_ language: String?) { if let language { - UserDefaults.standard.set([language], forKey: "AppleLanguages") + UserDefaults.standard.set([Self.canonicalLanguageCode(language)], forKey: "AppleLanguages") } else { UserDefaults.standard.removeObject(forKey: "AppleLanguages") } @@ -196,6 +208,38 @@ public struct AppView: View { ) } + private static func configuredLanguageCodes() -> [String] { + let rawCodes: [String] + if let configured = Bundle.main.object(forInfoDictionaryKey: "CFBundleLocalizations") as? [String], + !configured.isEmpty + { + rawCodes = configured + } else if let development = Bundle.main.developmentLocalization, !development.isEmpty { + rawCodes = [development] + } else { + rawCodes = [] + } + + var seen = Set() + var codes: [String] = [] + for rawCode in rawCodes { + let trimmed = rawCode.trimmingCharacters(in: .whitespacesAndNewlines) + guard !trimmed.isEmpty else { + continue + } + let canonical = canonicalLanguageCode(trimmed) + guard !canonical.isEmpty, seen.insert(canonical).inserted else { + continue + } + codes.append(canonical) + } + return codes + } + + private static func canonicalLanguageCode(_ code: String) -> String { + Locale.canonicalLanguageIdentifier(from: code) + } + #if os(macOS) private func updateLoginItems(_ startAtLogin: Bool) { diff --git a/Makefile b/Makefile index f0f759f..e38c910 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ build_ios: build_macos: xcodebuild build -scheme SFM -configuration Debug -destination 'generic/platform=macOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌" +build_macos_standalone: + xcodebuild build -scheme SFM.System -configuration Debug -destination 'generic/platform=macOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌" + build_tvos: xcodebuild build -scheme SFT -configuration Debug -destination 'generic/platform=tvOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌" diff --git a/SFI/Info.plist b/SFI/Info.plist index ba92b5f..30bb80c 100644 --- a/SFI/Info.plist +++ b/SFI/Info.plist @@ -31,6 +31,9 @@ en zh-Hans + zh-Hant + ru + fa CFBundleURLTypes diff --git a/SFM.System/Info.plist b/SFM.System/Info.plist index fcffb47..8e2e0a5 100644 --- a/SFM.System/Info.plist +++ b/SFM.System/Info.plist @@ -105,7 +105,10 @@ CFBundleLocalizations en - zh_CN + zh-Hans + zh-Hant + ru + fa CFBundleDevelopmentRegion en diff --git a/SFM/Info.plist b/SFM/Info.plist index 2557bdf..3f4b2d0 100644 --- a/SFM/Info.plist +++ b/SFM/Info.plist @@ -106,6 +106,9 @@ en zh-Hans + zh-Hant + ru + fa CFBundleDevelopmentRegion en diff --git a/SFT/Info.plist b/SFT/Info.plist index 8d97161..3ff9136 100644 --- a/SFT/Info.plist +++ b/SFT/Info.plist @@ -52,6 +52,9 @@ en zh-Hans + zh-Hant + ru + fa CFBundleDevelopmentRegion en