diff --git a/ui/src/i18n/locales/pt-BR.ts b/ui/src/i18n/locales/pt-BR.ts
index bb01a19f79a..f656793e78b 100644
--- a/ui/src/i18n/locales/pt-BR.ts
+++ b/ui/src/i18n/locales/pt-BR.ts
@@ -2,6 +2,7 @@ import type { TranslationMap } from "../lib/types.ts";
export const pt_BR: TranslationMap = {
common: {
+ version: "Versão",
health: "Saúde",
ok: "OK",
offline: "Offline",
diff --git a/ui/src/i18n/locales/zh-CN.ts b/ui/src/i18n/locales/zh-CN.ts
index e4ded13cb12..ef3cd77ae17 100644
--- a/ui/src/i18n/locales/zh-CN.ts
+++ b/ui/src/i18n/locales/zh-CN.ts
@@ -2,6 +2,7 @@ import type { TranslationMap } from "../lib/types.ts";
export const zh_CN: TranslationMap = {
common: {
+ version: "版本",
health: "健康状况",
ok: "正常",
offline: "离线",
diff --git a/ui/src/i18n/locales/zh-TW.ts b/ui/src/i18n/locales/zh-TW.ts
index 6831167c666..580f8a3de92 100644
--- a/ui/src/i18n/locales/zh-TW.ts
+++ b/ui/src/i18n/locales/zh-TW.ts
@@ -2,6 +2,7 @@ import type { TranslationMap } from "../lib/types.ts";
export const zh_TW: TranslationMap = {
common: {
+ version: "版本",
health: "健康狀況",
ok: "正常",
offline: "離線",
diff --git a/ui/src/i18n/test/translate.test.ts b/ui/src/i18n/test/translate.test.ts
index 178fd12b1e3..29915c63b01 100644
--- a/ui/src/i18n/test/translate.test.ts
+++ b/ui/src/i18n/test/translate.test.ts
@@ -1,5 +1,8 @@
import { describe, it, expect, beforeEach, vi } from "vitest";
import { i18n, t } from "../lib/translate.ts";
+import { pt_BR } from "../locales/pt-BR.ts";
+import { zh_CN } from "../locales/zh-CN.ts";
+import { zh_TW } from "../locales/zh-TW.ts";
describe("i18n", () => {
beforeEach(async () => {
@@ -44,13 +47,17 @@ describe("i18n", () => {
it("loads saved non-English locale on startup", async () => {
localStorage.setItem("openclaw.i18n.locale", "zh-CN");
vi.resetModules();
- const fresh = await import("../lib/translate.ts");
-
- for (let index = 0; index < 5 && fresh.i18n.getLocale() !== "zh-CN"; index += 1) {
- await Promise.resolve();
- }
-
+ const fresh = await import("../lib/translate.ts?startup-locale");
+ await vi.waitFor(() => {
+ expect(fresh.i18n.getLocale()).toBe("zh-CN");
+ });
expect(fresh.i18n.getLocale()).toBe("zh-CN");
expect(fresh.t("common.health")).toBe("健康状况");
});
+
+ it("keeps the version label available in shipped locales", () => {
+ expect(pt_BR.common.version).toBeTruthy();
+ expect(zh_CN.common.version).toBeTruthy();
+ expect(zh_TW.common.version).toBeTruthy();
+ });
});
diff --git a/ui/src/ui/app-render.helpers.ts b/ui/src/ui/app-render.helpers.ts
index 68dfbe5e76d..0678706cd04 100644
--- a/ui/src/ui/app-render.helpers.ts
+++ b/ui/src/ui/app-render.helpers.ts
@@ -490,7 +490,7 @@ function countHiddenCronSessions(sessionKey: string, sessions: SessionsListResul
const THEME_ORDER: ThemeMode[] = ["system", "light", "dark"];
export function renderThemeToggle(state: AppViewState) {
- const index = Math.max(0, THEME_ORDER.indexOf(state.theme));
+ const index = Math.max(0, THEME_ORDER.indexOf(state.themeMode));
const applyTheme = (next: ThemeMode) => (event: MouseEvent) => {
const element = event.currentTarget as HTMLElement;
const context: ThemeTransitionContext = { element };
@@ -498,7 +498,7 @@ export function renderThemeToggle(state: AppViewState) {
context.pointerClientX = event.clientX;
context.pointerClientY = event.clientY;
}
- state.setTheme(next, context);
+ state.setThemeMode(next, context);
};
return html`
@@ -506,27 +506,27 @@ export function renderThemeToggle(state: AppViewState) {