fix(ui): load saved locale on startup

This commit is contained in:
chilu18
2026-02-23 20:36:15 +00:00
committed by Peter Steinberger
parent 7a42558a3e
commit 053b0df7d4
2 changed files with 38 additions and 15 deletions

View File

@@ -18,20 +18,30 @@ class I18nManager {
this.loadLocale();
}
private loadLocale() {
private resolveInitialLocale(): Locale {
const saved = localStorage.getItem("openclaw.i18n.locale");
if (isSupportedLocale(saved)) {
this.locale = saved;
} else {
const navLang = navigator.language;
if (navLang.startsWith("zh")) {
this.locale = navLang === "zh-TW" || navLang === "zh-HK" ? "zh-TW" : "zh-CN";
} else if (navLang.startsWith("pt")) {
this.locale = "pt-BR";
} else {
this.locale = "en";
}
return saved;
}
const navLang = navigator.language;
if (navLang.startsWith("zh")) {
return navLang === "zh-TW" || navLang === "zh-HK" ? "zh-TW" : "zh-CN";
}
if (navLang.startsWith("pt")) {
return "pt-BR";
}
return "en";
}
private loadLocale() {
const initialLocale = this.resolveInitialLocale();
if (initialLocale === "en") {
this.locale = "en";
return;
}
// Use the normal locale setter so startup locale loading follows the same
// translation-loading + notify path as manual locale changes.
void this.setLocale(initialLocale);
}
public getLocale(): Locale {
@@ -39,12 +49,13 @@ class I18nManager {
}
public async setLocale(locale: Locale) {
if (this.locale === locale) {
const needsTranslationLoad = !this.translations[locale];
if (this.locale === locale && !needsTranslationLoad) {
return;
}
// Lazy load translations if needed
if (!this.translations[locale]) {
if (needsTranslationLoad) {
try {
let module: Record<string, TranslationMap>;
if (locale === "zh-CN") {

View File

@@ -2,10 +2,10 @@ import { describe, it, expect, beforeEach } from "vitest";
import { i18n, t } from "../lib/translate.ts";
describe("i18n", () => {
beforeEach(() => {
beforeEach(async () => {
localStorage.clear();
// Reset to English
void i18n.setLocale("en");
await i18n.setLocale("en");
});
it("should return the key if translation is missing", () => {
@@ -28,4 +28,16 @@ describe("i18n", () => {
// but let's assume it falls back to English for now.
expect(t("common.health")).toBeDefined();
});
it("loads translations even when setting the same locale again", async () => {
const internal = i18n as unknown as {
locale: string;
translations: Record<string, unknown>;
};
internal.locale = "zh-CN";
delete internal.translations["zh-CN"];
await i18n.setLocale("zh-CN");
expect(t("common.health")).toBe("健康状况");
});
});