feat(ui): locale persistence + i18n completeness guards (F3)
An audit found the client already i18n-first: one hard-coded UI string (the battle-scene aria-label, now keyed) and en/ru already share an identical 692-key set. - Persist the locale: i18n.setLocale writes localStorage (galaxy-locale) and the store boots from stored > browser detection > default, so a language switch survives reloads. - tests/i18n-completeness.test.ts: en/ru key-set parity, non-empty values, and locale persistence. - Docs: ui/docs/i18n.md; mark F3 done in ui/PLAN-finalize.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+10
-6
@@ -82,12 +82,13 @@ Native wrappers (Wails, Capacitor) will pass their system locale
|
||||
once the desktop/mobile targets land (see ../ROADMAP.md); the
|
||||
helper is platform-agnostic by design.
|
||||
|
||||
The detection runs once at module load — there is no asynchronous
|
||||
init step. Callers that mutate the locale (e.g. the language picker
|
||||
on `/login`) call `i18n.setLocale(next)` directly. The choice is
|
||||
**not** persisted between page reloads; the next visit re-runs
|
||||
detection. Persistence is deferred to the finalization plan
|
||||
(../Plan-finalize.md).
|
||||
The boot locale resolves once at module load (no async init):
|
||||
an explicit stored choice wins, otherwise browser/system detection,
|
||||
otherwise `DEFAULT_LOCALE`. Callers that mutate the locale (the language
|
||||
pickers on `/login` and in the account menu) call `i18n.setLocale(next)`,
|
||||
which **persists** the choice to `localStorage` (key `galaxy-locale`) so
|
||||
it survives reloads. An unrecognised stored value is ignored and falls
|
||||
back to detection.
|
||||
|
||||
## Forwarding the locale to the gateway
|
||||
|
||||
@@ -135,6 +136,9 @@ at challenge issuance and replayed from the challenge row.
|
||||
- `tests/i18n.test.ts` covers `detectInitialLocale`,
|
||||
`i18n.setLocale`, parameter interpolation, and the unknown-key
|
||||
fallback.
|
||||
- `tests/i18n-completeness.test.ts` enforces en/ru key-set parity (no
|
||||
key present in one locale but missing in the other), non-empty values,
|
||||
and locale persistence (a stored choice is restored on the next load).
|
||||
- `tests/login-page.test.ts` asserts the language picker renders
|
||||
with native names, switching the locale re-renders the form
|
||||
text, and `sendEmailCode` receives the active locale.
|
||||
|
||||
Reference in New Issue
Block a user