Repository navigation
i18n: skeleton with Settings language picker and Home extracted (en + zh-CN) - #19
Conversation
- lib/i18n.js: zero-dependency t store + t(key, params), locale persisted per device, system-language default, English fallback for missing keys, plurals through Intl.PluralRules - src/locales/en.json (source of truth) + zh-CN.json - Settings > Appearance: language dropdown - Home view extracted (en + zh-CN) - format.js plural() now selects via the chosen locale's plural rules - tests: catalog completeness (no missing/extra keys), fallback, params, plural categories, locale detection; language pinned where tests assert English wording
|
Someone is attempting to deploy a commit to the sivadaboi's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
sivadaboi
left a comment
There was a problem hiding this comment.
New branch: I've made an i18n branch for this work and pointed this PR at it. Please open the next PRs against i18n instead of dev. That way the translation can land screen by screen, and I'll merge i18n into dev when it's in a good state.
Four small changes before I merge:
- The catalog tests break on the first plural.
leafKeys()walks into plural objects, so{ "one", "other" }in en.json becomesk.one+k.otherwhile zh-CN's plain string isk, and all three catalog tests fail. Since the catalogs are flat, comparing top-level keys is enough, with a plural counted as one value that must have anotherform. - One sentence, one key. The welcome hint is split into
hintA/hintB/hintC, which translators can't reorder (and it leaves stray spaces around 设备 and 云备份). Please make it one string with{devices}and{cloud}placeholders, plus a small helper to render those parts in bold. Let's use that rule for every view. - Only save the language when someone picks one. Right now the detected language is saved on the first launch, so the app never follows the system language again. Please add a "System default" option at the top of the dropdown too.
- Set
<html lang>to the chosen language. It staysentoday, and for Chinese that can make Windows use Japanese glyph shapes for some characters.
Once those are in I'll merge, and you're welcome to start on the next views. Thanks again!
- catalog tests compare top-level keys and require an 'other' form on
plural values (leaf-walking broke on the first plural)
- welcome hint is one key with {devices}/{cloud} placeholders; new
segments() helper renders the filled parts in bold
- language is 'system' until explicitly picked; only an explicit pick is
persisted, and the picker gains a System default option
- <html lang> follows the resolved locale in App.svelte
|
All four points are addressed in 5ab46ba:
Happy to rebase onto anything else — and I'll open the next PRs against |
Follows the pattern from Liquid-co#19: one sentence per key, bold parts through segments() placeholders, counts through Intl.PluralRules. - home/ScanDialog, ScanFolderList, SetupGuide, LibraryGrid, LibraryTile, LibraryViewOptions, HomeSummary, AddGameCard, OfferedGames, RecentActivity - 146 new keys, grouped per component - a few generic strings land in common.* (cancel, nowTracking) so the same wording is not translated twice; duplicated existing keys reuse the originals (home.devices, home.scanning, home.chooseFolderDialog, home.welcome.scanForSaves) - Labels built in lib/ (cover styles, sort names, status text, time ago) are still English: they return words, not sentences, so they need their own pass to expose keys instead. Left out to keep this reviewable. - Windows example path in AddGameCard's placeholder stays as typed npm test: 271/271; vite build clean
Follows the pattern from Liquid-co#19: one sentence per key, bold parts through segments() placeholders, counts through Intl.PluralRules. - home/ScanDialog, ScanFolderList, SetupGuide, LibraryGrid, LibraryTile, LibraryViewOptions, HomeSummary, AddGameCard, OfferedGames, RecentActivity - 146 new keys, grouped per component - a few generic strings land in common.* (cancel, nowTracking) so the same wording is not translated twice; duplicated existing keys reuse the originals (home.devices, home.scanning, home.chooseFolderDialog, home.welcome.scanForSaves) - Labels built in lib/ (cover styles, sort names, status text, time ago) are still English: they return words, not sentences, so they need their own pass to expose keys instead. Left out to keep this reviewable. - Windows example path in AddGameCard's placeholder stays as typed npm test: 271/271; vite build clean
Implements the plan agreed in #18.
What's in this PR
lib/i18n.js— a small, zero-dependency module:tis a Svelte store whose value is the translate function, so$t('key')in templates re-renders on language switch with no wiring. Locale is persisted per device (opensave.locale), defaults to the system language, and any key missing from the active catalog falls back to English, so partial translations never show blanks.src/locales/en.json(source of truth) +zh-CN.json— flat, dot-keyed, grouped by view (home.*,settings.*). A plural value is an object keyed byIntl.PluralRulescategories ({ "one": …, "other": … }); single-form languages like Chinese are plain strings.format.jsplural()now selects through the chosen locale's plural rules instead ofn === 1.i18n.test.js, 12 cases): catalog completeness both ways (no missing keys, no extra keys, no empty values), English fallback,{param}filling, plural category selection includingndefaulting to 0, and locale detection (saved choice > system language > English, storage-refusal safe). Two existing suites that assert English wording now pinlocale.set('en')so they don't depend on the machine's language.npm test: 305/305 (was 249 + these new tests; dev gained tests since v2.4.0).Notes
{n}unfilled —translatenow defaults it to 0 before substitution.home/components, then the Go-side map for tray/notifications.Closes #18 (the skeleton step; I'll keep referencing it from the per-view PRs).