Files
cortiq-gateway/web/js/i18n.js
T
infosave2007 10b5101757 fix(i18n): complexity tier names are translated everywhere they're shown
low/medium/high leaked as raw English into the bands legend, the tier badges
on the Routing page, the pair complexity selects, the benchmark's tier column
and the Playground decision panel. New trTier() helper renders the human name
(ru: лёгкий/средний/сложный, de: leicht/mittel/schwer, fr/es/zh/tr likewise);
custom tier names pass through untouched, badge colors stay keyed by the raw
tier. Verified in the browser in Russian and German.
2026-08-08 09:51:38 +03:00

62 lines
1.9 KiB
JavaScript
Vendored

// i18n engine. English is the source of truth; other languages override per key
// and fall back to English for any missing key.
import en from "./i18n/en.js";
import ru from "./i18n/ru.js";
import de from "./i18n/de.js";
import fr from "./i18n/fr.js";
import es from "./i18n/es.js";
import zh from "./i18n/zh.js";
import tr from "./i18n/tr.js";
const DICTS = { en, ru, de, fr, es, zh, tr };
export const LANGS = [
{ code: "en", label: "English", flag: "🇬🇧" },
{ code: "ru", label: "Русский", flag: "🇷🇺" },
{ code: "de", label: "Deutsch", flag: "🇩🇪" },
{ code: "fr", label: "Français", flag: "🇫🇷" },
{ code: "es", label: "Español", flag: "🇪🇸" },
{ code: "zh", label: "中文", flag: "🇨🇳" },
{ code: "tr", label: "Türkçe", flag: "🇹🇷" },
];
const listeners = new Set();
function detect() {
const saved = localStorage.getItem("allaigate_lang");
if (saved && DICTS[saved]) return saved;
const url = new URLSearchParams(location.search).get("lang");
if (url && DICTS[url]) return url;
const nav = (navigator.language || "en").slice(0, 2).toLowerCase();
return DICTS[nav] ? nav : "en";
}
let lang = detect();
export function getLang() {
return lang;
}
export function setLang(l) {
lang = DICTS[l] ? l : "en";
localStorage.setItem("allaigate_lang", lang);
document.documentElement.setAttribute("lang", lang);
listeners.forEach((fn) => fn(lang));
}
export function onLangChange(fn) {
listeners.add(fn);
return () => listeners.delete(fn);
}
// Human name for a complexity tier; custom tier names pass through as-is.
export function trTier(tier) {
return ["low", "medium", "high"].includes(tier) ? t("tier." + tier) : tier;
}
export function t(key, vars) {
const d = DICTS[lang] || en;
let s = d[key] ?? en[key] ?? key;
if (vars) for (const k of Object.keys(vars)) s = s.split("{" + k + "}").join(vars[k]);
return s;
}