feat(ui): translate main component strings to Chinese
- Add i18n to app-render.ts (gateway disconnected message) - Add i18n to app-render.helpers.ts (theme, chat controls, language selector) - Add i18n to app-channels.ts (Nostr profile messages) - Add translation keys for theme, chat controls, gateway, and nostrProfile https://claude.ai/code/session_01UK3kVX7BRyE1zEHVh3vrFY
This commit is contained in:
parent
cdaf6b86da
commit
0622f2c752
@ -687,6 +687,33 @@ export const enUS = {
|
|||||||
light: "Light",
|
light: "Light",
|
||||||
dark: "Dark",
|
dark: "Dark",
|
||||||
system: "System",
|
system: "System",
|
||||||
|
ariaLabel: "Theme",
|
||||||
|
systemAriaLabel: "System theme",
|
||||||
|
lightAriaLabel: "Light theme",
|
||||||
|
darkAriaLabel: "Dark theme",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Chat controls
|
||||||
|
chatControls: {
|
||||||
|
disabledDuringOnboarding: "Disabled during onboarding",
|
||||||
|
toggleThinking: "Toggle assistant thinking/working output",
|
||||||
|
toggleFocusMode: "Toggle focus mode (hide sidebar + page header)",
|
||||||
|
selectLanguage: "Select language",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Gateway connection
|
||||||
|
gateway: {
|
||||||
|
disconnected: "Disconnected from gateway.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nostr profile messages
|
||||||
|
nostrProfile: {
|
||||||
|
publishFailed: "Profile publish failed on all relays.",
|
||||||
|
publishSuccess: "Profile published to relays.",
|
||||||
|
updateFailed: "Profile update failed",
|
||||||
|
importFailed: "Profile import failed",
|
||||||
|
importedFromRelays: "Profile imported from relays. Review and publish.",
|
||||||
|
importedReviewPublish: "Profile imported. Review and publish.",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Time/date formatting
|
// Time/date formatting
|
||||||
|
|||||||
@ -694,6 +694,33 @@ export const zhTW = {
|
|||||||
light: "淺色",
|
light: "淺色",
|
||||||
dark: "深色",
|
dark: "深色",
|
||||||
system: "跟隨系統",
|
system: "跟隨系統",
|
||||||
|
ariaLabel: "主題",
|
||||||
|
systemAriaLabel: "跟隨系統主題",
|
||||||
|
lightAriaLabel: "淺色主題",
|
||||||
|
darkAriaLabel: "深色主題",
|
||||||
|
},
|
||||||
|
|
||||||
|
// 對話控制
|
||||||
|
chatControls: {
|
||||||
|
disabledDuringOnboarding: "引導期間已停用",
|
||||||
|
toggleThinking: "切換助手思考/工作輸出",
|
||||||
|
toggleFocusMode: "切換專注模式(隱藏側邊欄和頁首)",
|
||||||
|
selectLanguage: "選擇語言",
|
||||||
|
},
|
||||||
|
|
||||||
|
// 閘道器連線
|
||||||
|
gateway: {
|
||||||
|
disconnected: "已與閘道器斷線。",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nostr 個人檔案訊息
|
||||||
|
nostrProfile: {
|
||||||
|
publishFailed: "個人檔案發布至所有中繼站失敗。",
|
||||||
|
publishSuccess: "個人檔案已發布至中繼站。",
|
||||||
|
updateFailed: "個人檔案更新失敗",
|
||||||
|
importFailed: "個人檔案匯入失敗",
|
||||||
|
importedFromRelays: "已從中繼站匯入個人檔案。請檢視並發布。",
|
||||||
|
importedReviewPublish: "已匯入個人檔案。請檢視並發布。",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 時間/日期格式
|
// 時間/日期格式
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { loadConfig, saveConfig } from "./controllers/config";
|
|||||||
import type { MoltbotApp } from "./app";
|
import type { MoltbotApp } from "./app";
|
||||||
import type { NostrProfile } from "./types";
|
import type { NostrProfile } from "./types";
|
||||||
import { createNostrProfileFormState } from "./views/channels.nostr-profile-form";
|
import { createNostrProfileFormState } from "./views/channels.nostr-profile-form";
|
||||||
|
import { t } from "../i18n";
|
||||||
|
|
||||||
export async function handleWhatsAppStart(host: MoltbotApp, force: boolean) {
|
export async function handleWhatsAppStart(host: MoltbotApp, force: boolean) {
|
||||||
await startWhatsAppLogin(host, force);
|
await startWhatsAppLogin(host, force);
|
||||||
@ -142,7 +143,7 @@ export async function handleNostrProfileSave(host: MoltbotApp) {
|
|||||||
host.nostrProfileFormState = {
|
host.nostrProfileFormState = {
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
saving: false,
|
||||||
error: "Profile publish failed on all relays.",
|
error: t("nostrProfile.publishFailed"),
|
||||||
success: null,
|
success: null,
|
||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
@ -152,7 +153,7 @@ export async function handleNostrProfileSave(host: MoltbotApp) {
|
|||||||
...state,
|
...state,
|
||||||
saving: false,
|
saving: false,
|
||||||
error: null,
|
error: null,
|
||||||
success: "Profile published to relays.",
|
success: t("nostrProfile.publishSuccess"),
|
||||||
fieldErrors: {},
|
fieldErrors: {},
|
||||||
original: { ...state.values },
|
original: { ...state.values },
|
||||||
};
|
};
|
||||||
@ -161,7 +162,7 @@ export async function handleNostrProfileSave(host: MoltbotApp) {
|
|||||||
host.nostrProfileFormState = {
|
host.nostrProfileFormState = {
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
saving: false,
|
||||||
error: `Profile update failed: ${String(err)}`,
|
error: `${t("nostrProfile.updateFailed")}: ${String(err)}`,
|
||||||
success: null,
|
success: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -214,8 +215,8 @@ export async function handleNostrProfileImport(host: MoltbotApp) {
|
|||||||
values: nextValues,
|
values: nextValues,
|
||||||
error: null,
|
error: null,
|
||||||
success: data.saved
|
success: data.saved
|
||||||
? "Profile imported from relays. Review and publish."
|
? t("nostrProfile.importedFromRelays")
|
||||||
: "Profile imported. Review and publish.",
|
: t("nostrProfile.importedReviewPublish"),
|
||||||
showAdvanced,
|
showAdvanced,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -226,7 +227,7 @@ export async function handleNostrProfileImport(host: MoltbotApp) {
|
|||||||
host.nostrProfileFormState = {
|
host.nostrProfileFormState = {
|
||||||
...state,
|
...state,
|
||||||
importing: false,
|
importing: false,
|
||||||
error: `Profile import failed: ${String(err)}`,
|
error: `${t("nostrProfile.importFailed")}: ${String(err)}`,
|
||||||
success: null,
|
success: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,8 +107,8 @@ export function renderChatControls(state: AppViewState) {
|
|||||||
}}
|
}}
|
||||||
aria-pressed=${showThinking}
|
aria-pressed=${showThinking}
|
||||||
title=${disableThinkingToggle
|
title=${disableThinkingToggle
|
||||||
? "Disabled during onboarding"
|
? t("chatControls.disabledDuringOnboarding")
|
||||||
: "Toggle assistant thinking/working output"}
|
: t("chatControls.toggleThinking")}
|
||||||
>
|
>
|
||||||
${icons.brain}
|
${icons.brain}
|
||||||
</button>
|
</button>
|
||||||
@ -124,8 +124,8 @@ export function renderChatControls(state: AppViewState) {
|
|||||||
}}
|
}}
|
||||||
aria-pressed=${focusActive}
|
aria-pressed=${focusActive}
|
||||||
title=${disableFocusToggle
|
title=${disableFocusToggle
|
||||||
? "Disabled during onboarding"
|
? t("chatControls.disabledDuringOnboarding")
|
||||||
: "Toggle focus mode (hide sidebar + page header)"}
|
: t("chatControls.toggleFocusMode")}
|
||||||
>
|
>
|
||||||
${focusIcon}
|
${focusIcon}
|
||||||
</button>
|
</button>
|
||||||
@ -172,14 +172,14 @@ export function renderThemeToggle(state: AppViewState) {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="theme-toggle" style="--theme-index: ${index};">
|
<div class="theme-toggle" style="--theme-index: ${index};">
|
||||||
<div class="theme-toggle__track" role="group" aria-label="Theme">
|
<div class="theme-toggle__track" role="group" aria-label="${t("theme.ariaLabel")}">
|
||||||
<span class="theme-toggle__indicator"></span>
|
<span class="theme-toggle__indicator"></span>
|
||||||
<button
|
<button
|
||||||
class="theme-toggle__button ${state.theme === "system" ? "active" : ""}"
|
class="theme-toggle__button ${state.theme === "system" ? "active" : ""}"
|
||||||
@click=${applyTheme("system")}
|
@click=${applyTheme("system")}
|
||||||
aria-pressed=${state.theme === "system"}
|
aria-pressed=${state.theme === "system"}
|
||||||
aria-label="System theme"
|
aria-label="${t("theme.systemAriaLabel")}"
|
||||||
title="System"
|
title="${t("theme.system")}"
|
||||||
>
|
>
|
||||||
${renderMonitorIcon()}
|
${renderMonitorIcon()}
|
||||||
</button>
|
</button>
|
||||||
@ -187,8 +187,8 @@ export function renderThemeToggle(state: AppViewState) {
|
|||||||
class="theme-toggle__button ${state.theme === "light" ? "active" : ""}"
|
class="theme-toggle__button ${state.theme === "light" ? "active" : ""}"
|
||||||
@click=${applyTheme("light")}
|
@click=${applyTheme("light")}
|
||||||
aria-pressed=${state.theme === "light"}
|
aria-pressed=${state.theme === "light"}
|
||||||
aria-label="Light theme"
|
aria-label="${t("theme.lightAriaLabel")}"
|
||||||
title="Light"
|
title="${t("theme.light")}"
|
||||||
>
|
>
|
||||||
${renderSunIcon()}
|
${renderSunIcon()}
|
||||||
</button>
|
</button>
|
||||||
@ -196,8 +196,8 @@ export function renderThemeToggle(state: AppViewState) {
|
|||||||
class="theme-toggle__button ${state.theme === "dark" ? "active" : ""}"
|
class="theme-toggle__button ${state.theme === "dark" ? "active" : ""}"
|
||||||
@click=${applyTheme("dark")}
|
@click=${applyTheme("dark")}
|
||||||
aria-pressed=${state.theme === "dark"}
|
aria-pressed=${state.theme === "dark"}
|
||||||
aria-label="Dark theme"
|
aria-label="${t("theme.darkAriaLabel")}"
|
||||||
title="Dark"
|
title="${t("theme.dark")}"
|
||||||
>
|
>
|
||||||
${renderMoonIcon()}
|
${renderMoonIcon()}
|
||||||
</button>
|
</button>
|
||||||
@ -263,7 +263,7 @@ export function renderLanguageSwitcher() {
|
|||||||
class="language-switcher__select"
|
class="language-switcher__select"
|
||||||
.value=${currentLocale}
|
.value=${currentLocale}
|
||||||
@change=${handleChange}
|
@change=${handleChange}
|
||||||
aria-label="Select language"
|
aria-label="${t("chatControls.selectLanguage")}"
|
||||||
>
|
>
|
||||||
${locales.map(
|
${locales.map(
|
||||||
(locale) => html`
|
(locale) => html`
|
||||||
|
|||||||
@ -106,7 +106,7 @@ export function renderApp(state: AppViewState) {
|
|||||||
const presenceCount = state.presenceEntries.length;
|
const presenceCount = state.presenceEntries.length;
|
||||||
const sessionsCount = state.sessionsResult?.count ?? null;
|
const sessionsCount = state.sessionsResult?.count ?? null;
|
||||||
const cronNext = state.cronStatus?.nextWakeAtMs ?? null;
|
const cronNext = state.cronStatus?.nextWakeAtMs ?? null;
|
||||||
const chatDisabledReason = state.connected ? null : "Disconnected from gateway.";
|
const chatDisabledReason = state.connected ? null : t("gateway.disconnected");
|
||||||
const isChat = state.tab === "chat";
|
const isChat = state.tab === "chat";
|
||||||
const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);
|
const chatFocus = isChat && (state.settings.chatFocusMode || state.onboarding);
|
||||||
const showThinking = state.onboarding ? false : state.settings.chatShowThinking;
|
const showThinking = state.onboarding ? false : state.settings.chatShowThinking;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user