Auto-load language options

This commit is contained in:
世界
2026-02-15 16:45:54 +08:00
parent 26c4b0087d
commit 9411f39173
6 changed files with 67 additions and 8 deletions
@@ -7,11 +7,19 @@ import SwiftUI
#endif #endif
public struct AppView: View { public struct AppView: View {
private static let supportedLanguages: [(code: String?, name: String)] = [ private struct LanguageOption: Hashable {
(nil, String(localized: "System Default")), let code: String?
("en", "English"), let name: String
("zh-Hans", "简体中文"), }
]
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 isLoading = true
@State private var selectedLanguage: String? @State private var selectedLanguage: String?
@@ -176,8 +184,12 @@ public struct AppView: View {
else { else {
return nil return nil
} }
let current = canonicalLanguageCode(first)
for language in supportedLanguages { 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 return code
} }
} }
@@ -186,7 +198,7 @@ public struct AppView: View {
private func updateLanguage(_ language: String?) { private func updateLanguage(_ language: String?) {
if let language { if let language {
UserDefaults.standard.set([language], forKey: "AppleLanguages") UserDefaults.standard.set([Self.canonicalLanguageCode(language)], forKey: "AppleLanguages")
} else { } else {
UserDefaults.standard.removeObject(forKey: "AppleLanguages") 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<String>()
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) #if os(macOS)
private func updateLoginItems(_ startAtLogin: Bool) { private func updateLoginItems(_ startAtLogin: Bool) {
+3
View File
@@ -12,6 +12,9 @@ build_ios:
build_macos: build_macos:
xcodebuild build -scheme SFM -configuration Debug -destination 'generic/platform=macOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌" 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: build_tvos:
xcodebuild build -scheme SFT -configuration Debug -destination 'generic/platform=tvOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌" xcodebuild build -scheme SFT -configuration Debug -destination 'generic/platform=tvOS' | xcbeautify | grep -A 10 -e "Build Succeeded" -e "BUILD FAILED" -e "❌"
+3
View File
@@ -31,6 +31,9 @@
<array> <array>
<string>en</string> <string>en</string>
<string>zh-Hans</string> <string>zh-Hans</string>
<string>zh-Hant</string>
<string>ru</string>
<string>fa</string>
</array> </array>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
<array> <array>
+4 -1
View File
@@ -105,7 +105,10 @@
<key>CFBundleLocalizations</key> <key>CFBundleLocalizations</key>
<array> <array>
<string>en</string> <string>en</string>
<string>zh_CN</string> <string>zh-Hans</string>
<string>zh-Hant</string>
<string>ru</string>
<string>fa</string>
</array> </array>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
+3
View File
@@ -106,6 +106,9 @@
<array> <array>
<string>en</string> <string>en</string>
<string>zh-Hans</string> <string>zh-Hans</string>
<string>zh-Hant</string>
<string>ru</string>
<string>fa</string>
</array> </array>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
+3
View File
@@ -52,6 +52,9 @@
<array> <array>
<string>en</string> <string>en</string>
<string>zh-Hans</string> <string>zh-Hans</string>
<string>zh-Hant</string>
<string>ru</string>
<string>fa</string>
</array> </array>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>