UNPKG

iobroker.roborock

Version:
93 lines (74 loc) 3.31 kB
import * as fs from "node:fs"; import * as path from "node:path"; import type { Roborock } from "../main"; export class TranslationManager { private adapter: Roborock; private translations: Record<string, Record<string, string>> = {}; private currentLanguage: string = "en"; constructor(adapter: Roborock) { this.adapter = adapter; } public init() { const systemLang = (this.adapter.language || "en").toString().toLowerCase(); this.currentLanguage = this.resolveLanguage(systemLang); this.adapter.rLog("System", null, "Info", undefined, undefined, `[Translation] System language="${this.adapter.language}" normalized="${systemLang}" selected="${this.currentLanguage}"`, "info"); this.loadTranslations(); } private loadTranslations() { const jsonPath = path.join(__dirname, "..", "..", "lib", "protocols", "roborock_strings.json"); this.adapter.rLog("System", null, "Debug", undefined, undefined, `[Translation] Loading translations from ${jsonPath}`, "debug"); try { if (fs.existsSync(jsonPath)) { const data = fs.readFileSync(jsonPath, "utf8"); const rawTranslations = JSON.parse(data); // Re-index all keys to lowercase to ensure case-insensitive lookups this.translations = {}; for (const [lang, keys] of Object.entries(rawTranslations)) { this.translations[lang] = {}; for (const [key, val] of Object.entries(keys as Record<string, string>)) { this.translations[lang][key.toLowerCase()] = val; } } const langCount = Object.keys(this.translations).length; const currentKeys = this.translations[this.currentLanguage] ? Object.keys(this.translations[this.currentLanguage]).length : 0; this.adapter.rLog("System", null, "Info", undefined, undefined, `[Translation] Loaded ${langCount} languages. Current language "${this.currentLanguage}" has ${currentKeys} keys.`, "info"); } else { this.adapter.rLog("System", null, "Error", undefined, undefined, `[Translation] File not found at ${jsonPath}`, "error"); } } catch (e: unknown) { this.adapter.rLog("System", null, "Error", undefined, undefined, `[Translation] Failed to load translations: ${e instanceof Error ? e.message : String(e)}`, "error"); } } private resolveLanguage(lang: string): string { const LANGUAGE_MAP: Record<string, string> = { "zh-cn": "zh-hans", "zh-tw": "zh-hant", "zh-hk": "zh-hk", "de-de": "de", "en-us": "en", "en-gb": "en" }; if (LANGUAGE_MAP[lang]) { return LANGUAGE_MAP[lang]; } if (lang.includes("-")) { const base = lang.split("-")[0]; if (LANGUAGE_MAP[base]) return LANGUAGE_MAP[base]; return base; } return lang; } public get(key: string, defaultVal?: string): string { const lookupKey = key.toLowerCase(); // Try exact match in loaded Roborock translations if (this.translations[this.currentLanguage] && this.translations[this.currentLanguage][lookupKey]) { return this.translations[this.currentLanguage][lookupKey]; } // Try English fallback in loaded Roborock translations if (this.currentLanguage !== "en" && this.translations["en"] && this.translations["en"][lookupKey]) { return this.translations["en"][lookupKey]; } // Return defaultVal or key if translation completely missing return defaultVal !== undefined ? defaultVal : key; } }