From 6f3ed4f3b8eb45734ca77916b4c96fab937cb2e2 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sun, 31 May 2026 02:58:27 +0800
Subject: [PATCH] Prepare 7.8.7 dock policy release
---
Apptag/L10n.swift | 140 ++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 132 insertions(+), 8 deletions(-)
diff --git a/Apptag/L10n.swift b/Apptag/L10n.swift
index be24145..0d1f1b3 100644
--- a/Apptag/L10n.swift
+++ b/Apptag/L10n.swift
@@ -2,8 +2,14 @@
// MARK: - Localization Manager
+extension Notification.Name {
+ static let appLanguageDidChange = Notification.Name("AppLanguageDidChange")
+}
+
enum L10n {
+ static let automaticCode = "auto"
static var current: [String: String] = [:]
+ private(set) static var currentCode = "en"
/// Call once at startup to load the saved or system language.
static func setup() {
@@ -13,19 +19,97 @@
static let supported: [(code: String, name: String)] = [
("en", "English"),
- ("zh-Hans", "简体中文"),
- ("zh-Hant", "繁體中文"),
- ("ja", "日本語"),
- ("ko", "한국어"),
- ("ru", "Русский"),
("fr", "Français"),
("it", "Italiano"),
+ ("de", "Deutsch"),
("es", "Español"),
+ ("pt-BR", "Português (Brasil)"),
+ ("zh-Hans", "简体中文"),
+ ("zh-Hant", "繁體中文"),
+ ("ko", "한국어"),
+ ("ja", "日本語"),
+ ("ru", "Русский"),
+ ("sr-Cyrl", "Српски (ћирилица)"),
+ ("uk", "Українська"),
+ ("th", "ไทย"),
+ ("vi", "Tiếng Việt"),
+ ("ar", "العربية"),
+ ("ar-Najdi", "العربية (نجدي)"),
+ ("tr", "Türkçe"),
+ ("id", "Bahasa Indonesia"),
+ ("cs", "Čeština"),
+ ("da", "Dansk"),
+ ("nl", "Nederlands"),
+ ("no", "Norsk"),
+ ("nn", "Norsk nynorsk"),
+ ("nb", "Norsk bokmål"),
+ ("ms", "Bahasa Melayu"),
+ ("pl", "Polski"),
+ ("ro", "Română"),
+ ("sv", "Svenska"),
]
- static func switchTo(_ code: String) {
+ static var selectedLanguageCode: String {
+ UserDefaults.standard.string(forKey: "appLanguage") ?? automaticCode
+ }
+
+ static var isAutomatic: Bool {
+ UserDefaults.standard.string(forKey: "appLanguage") == nil
+ }
+
+ static func switchSelection(to code: String) {
+ if code == automaticCode {
+ switchToAutomatic()
+ } else {
+ switchTo(code)
+ }
+ }
+
+ static func switchToAutomatic() {
+ let code = fallbackCode()
+ let previousCode = currentCode
load(code)
+ UserDefaults.standard.removeObject(forKey: "appLanguage")
+ let relocalizedTags = previousCode != currentCode
+ ? TagDatabase.relocalizeSystemTagsForCurrentLanguage()
+ : false
+ NotificationCenter.default.post(
+ name: .appLanguageDidChange,
+ object: nil,
+ userInfo: ["code": automaticCode, "effectiveCode": currentCode]
+ )
+ if relocalizedTags {
+ NotificationCenter.default.post(name: .tagLauncherDataDidChange, object: nil)
+ }
+ }
+
+ static func switchTo(_ code: String) {
+ guard supported.contains(where: { $0.code == code }) else { return }
+ let previousSelection = selectedLanguageCode
+ guard code != currentCode || previousSelection == automaticCode else { return }
+ load(code)
+ let relocalizedTags = TagDatabase.relocalizeSystemTagsForCurrentLanguage()
UserDefaults.standard.set(code, forKey: "appLanguage")
+ NotificationCenter.default.post(
+ name: .appLanguageDidChange,
+ object: nil,
+ userInfo: ["code": currentCode, "effectiveCode": currentCode]
+ )
+ if relocalizedTags {
+ NotificationCenter.default.post(name: .tagLauncherDataDidChange, object: nil)
+ }
+ }
+
+ /// Load a specific key's translation for a given language code without switching.
+ static func loadedTranslation(_ key: String, for code: String) -> String? {
+ guard let url = Bundle.main.url(
+ forResource: code, withExtension: "json",
+ subdirectory: "Localization"
+ ) else { return nil }
+ guard let data = try? Data(contentsOf: url),
+ let dict = try? JSONSerialization.jsonObject(with: data) as? [String: String]
+ else { return nil }
+ return dict[key]
}
private static func load(_ code: String) {
@@ -33,7 +117,6 @@
forResource: code, withExtension: "json",
subdirectory: "Localization"
) else {
- // Fallback to bundled English
if code != "en" { load("en") }
return
}
@@ -41,18 +124,38 @@
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: String]
else { return }
current = dict
+ currentCode = code
}
- private static func fallbackCode() -> String {
+ static func fallbackCode() -> String {
let lang = Locale.preferredLanguages.first ?? "en"
if lang.hasPrefix("zh-Hant") || lang.hasPrefix("zh-HK") || lang.hasPrefix("zh-TW") { return "zh-Hant" }
if lang.hasPrefix("zh") { return "zh-Hans" }
+ if lang.hasPrefix("pt-BR") || lang.hasPrefix("pt_BR") || lang.hasPrefix("pt") { return "pt-BR" }
+ if lang.hasPrefix("sr-Cyrl") || lang.hasPrefix("sr_Cyrl") || lang.hasPrefix("sr") { return "sr-Cyrl" }
+ if lang.hasPrefix("ar") { return "ar" }
+ if lang.hasPrefix("de") { return "de" }
if lang.hasPrefix("ja") { return "ja" }
if lang.hasPrefix("ko") { return "ko" }
if lang.hasPrefix("ru") { return "ru" }
+ if lang.hasPrefix("uk") { return "uk" }
if lang.hasPrefix("fr") { return "fr" }
if lang.hasPrefix("it") { return "it" }
if lang.hasPrefix("es") { return "es" }
+ if lang.hasPrefix("th") { return "th" }
+ if lang.hasPrefix("vi") { return "vi" }
+ if lang.hasPrefix("tr") { return "tr" }
+ if lang.hasPrefix("id") { return "id" }
+ if lang.hasPrefix("cs") { return "cs" }
+ if lang.hasPrefix("da") { return "da" }
+ if lang.hasPrefix("nl") { return "nl" }
+ if lang.hasPrefix("nn") { return "nn" }
+ if lang.hasPrefix("nb") { return "nb" }
+ if lang.hasPrefix("no") { return "no" }
+ if lang.hasPrefix("ms") { return "ms" }
+ if lang.hasPrefix("pl") { return "pl" }
+ if lang.hasPrefix("ro") { return "ro" }
+ if lang.hasPrefix("sv") { return "sv" }
return "en"
}
}
@@ -61,3 +164,24 @@
func tr(_ key: String) -> String {
L10n.current[key] ?? key
}
+
+enum HelpDocument {
+ private static let baseURL = "https://github.com/shanghai3168/taglauncher/releases/download/v7.6.0"
+
+ static var currentURL: URL {
+ URL(string: "\(baseURL)/Taglauncher-help-\(languageCode(for: L10n.currentCode)).pdf")!
+ }
+
+ private static func languageCode(for appLanguageCode: String) -> String {
+ switch appLanguageCode {
+ case "zh-Hans": return "zh"
+ case "zh-Hant": return "zh-Hant"
+ case "en", "ar", "ar-Najdi", "cs", "da", "de", "es", "fr", "id",
+ "it", "ja", "ko", "ms", "nb", "nl", "nn", "no", "pl", "pt-BR",
+ "ro", "ru", "sr-Cyrl", "sv", "th", "tr", "uk", "vi":
+ return appLanguageCode
+ default:
+ return "en"
+ }
+ }
+}
--
Gitblit v1.9.3