2d35c1d9de
- 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>
19 lines
620 B
TypeScript
19 lines
620 B
TypeScript
import type { Locale } from "./config";
|
|
|
|
// Translation value type - can be a string or a function that takes parameters
|
|
export type TranslationValue = string | ((params: Record<string, string | number>) => string);
|
|
|
|
// Translation structure - nested objects with translation values at leaves
|
|
export type TranslationStructure = Record<string, unknown>;
|
|
|
|
// Flatten a nested object to dot-notation keys
|
|
export type Flatten<T> = T extends object
|
|
? {
|
|
[K in keyof T]: T[K] extends (...args: any[]) => any
|
|
? T[K]
|
|
: T[K] extends object
|
|
? Flatten<T[K]>
|
|
: T[K];
|
|
}[keyof T]
|
|
: T;
|