feat(i18n): add language switcher with en/ja translations

- New client-side i18n via React Context (useI18n, tArray, I18nProvider)
- Catalog ships 21 locale stubs; only zh-CN/en/ja have reviewed translations
- Header language switcher (globe icon + short label) before settings gear
- All hardcoded Chinese UI text migrated to keys: typewriter, options,
  hints (with embedded gear icon via dangerouslySetInnerHTML), settings
  panel, footer/about, play page hints
- AI output language follows user-selected locale via trailing one-liner
  directive appended to Architect/Writer/CharacterDesigner/InsertBeat
  user messages (preserves system-prompt cacheability)
- Per-locale separator rule: zh uses middot between every glyph; en/ja
  use plain spaces
- Option value → i18n key suffix maps preserve Chinese as the underlying
  identifier so analytics unions and STYLE_MAP keys stay byte-stable

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
DESKTOP-I1T6TF3\Q
2026-06-18 16:54:35 +08:00
parent f1fe7964a2
commit 2d35c1d9de
52 changed files with 6411 additions and 261 deletions
+11
View File
@@ -309,6 +309,14 @@ export type Session = {
* only (localStorage); never persisted server-side.
*/
playerName?: string;
/**
* Active UI locale when the session was started, in BCP-47 form (e.g.
* "zh-CN", "en", "ja"). The engine appends a single-line language directive
* to the Architect / Writer user messages so AI-generated dialogue, beats,
* and narration are produced in this language. Absent → "zh-CN" for
* back-compat with sessions created before this field existed.
*/
language?: string;
};
// ──────────────────────────────────────────────────────────────────────
@@ -428,6 +436,9 @@ export type StartRequest = {
orientation?: Orientation;
/** Optional player display name — see Session.playerName. */
playerName?: string;
/** Active UI locale — see Session.language. Drives the engine's language
* directive so AI output is generated in the player's chosen language. */
language?: string;
};
// /api/parse-style-image — vision LLM extracts a textual painting-style