iobroker.roborock
Version:
93 lines (74 loc) • 3.31 kB
text/typescript
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;
}
}