docs(i18n): migration tracking doc for incremental string conversion
This commit is contained in:
1 parent
77234e697d
commit
e1e2808d9c
1 file changed
+99
@@ -0,0 +1,99 @@
|
||||
# i18n migration tracking
|
||||
|
||||
Working doc for the incremental UI-string translation effort. The i18n **mechanism**
|
||||
is done; this tracks moving the app's remaining hardcoded strings into the translation
|
||||
files, one batch at a time. Tick boxes as views are converted.
|
||||
|
||||
- **Engine:** hand-rolled, zero-dependency. `src/lib/i18n/index.svelte.ts`
|
||||
- **Baseline dictionary:** `src/lib/i18n/en.json` (English is the source-of-truth key set
|
||||
**and** the fallback for any missing key)
|
||||
- **Selector:** Settings → Language (`section === "language"`)
|
||||
- **Scope decision:** display language is separate from the transcription `whisper_language`
|
||||
setting — don't conflate them.
|
||||
|
||||
## How to convert a string (the pattern)
|
||||
|
||||
1. Add a key to `en.json`. Naming: `<area>.<subarea>.<name>`, dotted, grouped by view —
|
||||
e.g. `nav.recording`, `settings.transcription.title`, `meetings.empty`.
|
||||
2. Replace the literal in markup with `{t("key")}` (import `t` from `../i18n/index.svelte`).
|
||||
3. Dynamic bits use placeholders: `t("meetings.count", { n })` against
|
||||
`"meetings.count": "{n} meetings"`. Handle plurals with a caller-side ternary for now
|
||||
(`n === 1 ? t("...one") : t("...many")`) — the engine is intentionally simple.
|
||||
4. Attributes translate the same way: `title={t("...")}`, `aria-label={t("...")}`,
|
||||
`placeholder={t("...")}`.
|
||||
5. `npm run check` must stay at 0 errors/warnings.
|
||||
|
||||
> When adding a **new language** (not covered by this doc's batches): copy `en.json` to
|
||||
> `<code>.json`, translate it, and register it in `DICTS` + `LOCALES` in
|
||||
> `index.svelte.ts`. That one file is the whole job.
|
||||
|
||||
## Done
|
||||
|
||||
- [x] i18n engine + `en.json` baseline + Settings language selector (branch
|
||||
`feature_chore_bug_007`)
|
||||
- [x] `Settings.svelte` — nav labels (`nav.*`), the Language section
|
||||
(`settings.language.*`), and the Transcription Language section
|
||||
(`settings.transcription.*`)
|
||||
|
||||
Current key count in `en.json`: **18** (`nav.*`, `settings.language.*`,
|
||||
`settings.transcription.*`).
|
||||
|
||||
## Outstanding — suggested batches
|
||||
|
||||
Ordered roughly by user-visibility ÷ effort. Sizes are rough (line count / labeled
|
||||
attributes) to help portion the work, not exact string counts. A file isn't "done" until
|
||||
its visible text **and** its `title`/`aria-label`/`placeholder` attributes are keyed.
|
||||
|
||||
### Batch A — app shell (high visibility, medium size)
|
||||
- [ ] `src/App.svelte` (~846 lines, ~21 labeled attrs) — top nav, window/tray strings,
|
||||
dialog prompts, empty states. Prefix `app.*`.
|
||||
|
||||
### Batch B — meetings list (small, high traffic)
|
||||
- [ ] `src/lib/views/MeetingsList.svelte` (~373 lines, ~9 attrs) — list headers, empty
|
||||
state, search/filter placeholders, date/tag labels. Prefix `meetings.*`.
|
||||
|
||||
### Batch C — transcript & notes (large surface)
|
||||
- [ ] `src/lib/views/TranscriptNotes.svelte` (~869 lines, ~40 attrs) — export button
|
||||
labels, editor toolbar tooltips, reprocess controls, pane toggles, empty states.
|
||||
Prefix `transcript.*` / `notes.*`. (Timestamps + the Obsidian/Bundle button labels
|
||||
live here.)
|
||||
|
||||
### Batch D — summary panel (medium)
|
||||
- [ ] `src/lib/views/SummaryPanel.svelte` (~1335 lines, ~14 attrs) — summary/action-item
|
||||
UI, participants, recording playback labels, LLM status copy. Prefix `summary.*`.
|
||||
|
||||
### Batch E — Settings, remaining sections (largest; split further as needed)
|
||||
The file is big — do it section by section, one sub-batch each:
|
||||
- [ ] Recording (`section === "recording"`) — prefix `settings.recording.*`
|
||||
- [ ] Hardware (`section === "hardware"`, excluding the already-done Transcription Language)
|
||||
- [ ] Storage (incl. the Export/Import copy) — `settings.storage.*`
|
||||
- [ ] Calendar — `settings.calendar.*`
|
||||
- [ ] Sync — `settings.sync.*`
|
||||
- [ ] AI — `settings.ai.*`
|
||||
- [ ] MCP server — `settings.mcp.*`
|
||||
- [ ] Privacy — `settings.privacy.*`
|
||||
- [ ] About — `settings.about.*`
|
||||
|
||||
### Batch F — components
|
||||
- [ ] `ConsentNotice.svelte` (~72 lines) — **legal/consent copy; translate carefully**
|
||||
- [ ] `HostedAiBanner.svelte` (~93 lines) — third-party-egress disclosure copy
|
||||
- [ ] `ImportMeeting.svelte` (~229 lines, ~5 attrs) — import dialog
|
||||
- [ ] `ThemeToggle.svelte` (~72 lines) — one aria-label
|
||||
- [ ] `TagChip.svelte`, `LevelMeter.svelte`, `Splitter.svelte` — check for any stray
|
||||
user-facing strings (likely minimal)
|
||||
|
||||
## Not translated (intentional)
|
||||
|
||||
- Backend / Rust error messages surfaced via `WaError` — out of scope for the frontend
|
||||
`t()`; revisit only if we localize command errors.
|
||||
- Provider/proper names (Ollama, Anthropic, OpenAI, Obsidian, WebDAV, WhispAssist),
|
||||
model ids, ISO language codes.
|
||||
- Console/`tracing` logs.
|
||||
|
||||
## Batch log
|
||||
|
||||
Record each landed batch here (date / branch / commit) so progress is auditable.
|
||||
|
||||
| Date | Batch | Branch / commit | Notes |
|
||||
|------|-------|-----------------|-------|
|
||||
| 2026-07-12 | Infra + Settings nav/language/transcription | `feature_chore_bug_007` | engine + en.json + selector |
|
||||
Reference in new issue
Block a user