Ariver
2026-05-13 beebaf7b68b3749f4a1bc4d916e23906b8c16d7f
Apptag/L10n.swift
@@ -2,8 +2,13 @@
// MARK: - Localization Manager
extension Notification.Name {
    static let appLanguageDidChange = Notification.Name("AppLanguageDidChange")
}
enum L10n {
    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() {
@@ -24,8 +29,23 @@
    ]
    static func switchTo(_ code: String) {
        guard supported.contains(where: { $0.code == code }) else { return }
        guard code != currentCode else { return }
        load(code)
        UserDefaults.standard.set(code, forKey: "appLanguage")
        NotificationCenter.default.post(name: .appLanguageDidChange, object: nil, userInfo: ["code": currentCode])
    }
    /// 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 +53,6 @@
            forResource: code, withExtension: "json",
            subdirectory: "Localization"
        ) else {
            // Fallback to bundled English
            if code != "en" { load("en") }
            return
        }
@@ -41,6 +60,7 @@
              let dict = try? JSONSerialization.jsonObject(with: data) as? [String: String]
        else { return }
        current = dict
        currentCode = code
    }
    private static func fallbackCode() -> String {