Skip to content

i18n: offer Chinese by script (zh-Hans/zh-Hant) and extract the window shell - #77

Merged
Omar-VF merged 5 commits into
Liquid-co:dev-publicfrom
Janlhin:pr-1-window-shell
Oct 19, 2026
Merged

Omar-VF merged 5 commits into
Liquid-co:dev-publicfrom
Janlhin:pr-1-window-shell

Conversation

@Janlhin

@Janlhin Janlhin commented Oct 16, 2026 •

Copy link
Copy Markdown

Implements step 1 of the i18n plan from #18: Chinese offered by script instead of region, and the window shell extracted into the catalog.

What

  • zh-CN.json → zh-Hans.json + zh-Hant.json. lib/i18n.js gains scriptFor(): tw / hk / mo resolve to Traditional, everything else to Simplified. The Settings picker lists 中文(简体) and 中文(繁體) as separate entries; an explicit pick is persisted, "System default" resolves through scriptFor(), and <html lang> follows (zh-Hans / zh-Hant).
  • Window shell extracted (commit 2): TitleBar, StatusBar (incl. the syncing / devices-online plurals through Intl.PluralRules — Chinese uses the single form), TransfersPanel, Toasts, plus the Modal / Skeleton primitives that render user-facing text. One sentence per key; keys grouped per component (titleBar.*, statusBar.*, transfers.*, common.*).
  • Carry-over of Track a game from the game database; one folder, one game #73's keys. The zh split must not lose Track game's text, so the 25 keys Track a game from the game database; one folder, one game #73 added (home.trackGame*, home.findGame.*, home.addGame.recognisedAs) are ported into both scripts. A review pass applied on top: save-folder and program terms unified (存档文件夾 / 游戏程序), the noSavesHere / noSavesYet phrasings aligned, inline 该游戏 → 这款游戏, and one sentence smoothed. zh-Hant is the OpenCC s2twp rendering with the catalog's current house terms (跟踪/資料庫/程式/資料夾; the 追蹤/搜尋 polish pass comes as a later PR in this series).
  • One key renamed: home.trackGameTitle → home.trackGameHint — it is the button's hint text, not a title (the dialog title is home.findGame.title). Worth knowing for the key migrations in Restore as many files at a time as the drive does best, with progress #55 / sync: closest devices first, by measured link speed #27.

Notes

Verification

  • npm test: 299/299 (catalog completeness both ways, English fallback, placeholder filling, plural categories, script resolution tw/hk/mo → zh-Hant, saved choice > system language > en).
  • vite build: clean.
  • Rendered check in the built app on Windows 11: title bar, status bar, transfers panel and toasts in en / 简体 / 繁體, including a language switch without restart.

Translation: @Janlhin (simplified & traditional)

@vercel

vercel Bot commented Oct 16, 2026

Copy link
Copy Markdown

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.

@Omar-VF

Omar-VF commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Thanks, splitting Chinese by script is a good call, and approved. Two requests:

Janlhin pushed a commit to Janlhin/OpenSave that referenced this pull request Oct 18, 2026
A saved 'zh-CN' (or any other zh-* tag) from before the script split is
no longer a LOCALES id, so it fell back to the system language and
someone who picked Chinese silently lost it. sanitizeLocale now maps
such tags through scriptFor: zh-CN -> zh-Hans, zh-TW/zh-HK/zh-MO ->
zh-Hant, bare zh -> zh-Hans. Non-Chinese garbage still rejects to null.

Requested by Omar-VF in Liquid-co#77.
@Janlhin

Janlhin commented Oct 18, 2026

Copy link
Copy Markdown
Author

Done: sanitizeLocale now maps a saved zh-CN (and any other zh-* tag) through scriptFor — zh-CN/zh-SG/bare zh → zh-Hans, zh-TW/zh-HK/zh-MO → zh-Hant — so someone who picked Chinese before the split keeps it. Non-Chinese garbage still rejects to null.

Heads-up for the key migrations in #55 / #84 and the draft stack: we renamed home.trackGameTitle → home.trackGameHint — it is the button's hint text, not a title (the dialog title is home.findGame.title). The ported #73 strings also got a light review pass (terms unified: 存档文件夹 / 游戏程序).

Holding the rebase until you confirm #54 / #84 have landed, as you suggested — will rebase once and push here.

@Omar-VF

Omar-VF commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

#54 and #84 are merged now, so this is a good time to rebase onto dev-public. Thanks for waiting.

Janlhin added 5 commits October 19, 2026 18:13
Whether a reader wants simplified or traditional characters is not the
same question as where they are, so Chinese is no longer split into
zh-CN / zh-TW / zh-HK and the rest. Two scripts are offered instead,
and each region maps onto one of them.

- zh-CN.json becomes zh-Hans.json.
- zh-Hant.json is new: all 167 keys, converted with OpenCC (s2twp). Two
  words that OpenCC renders the wrong way round are corrected by hand:
  镜像 (not 映象) and 帳號 (not 賬號).
- scriptFor() reads the script out of an OS language tag: zh-TW, zh-HK,
  zh-MO and any zh-Hant-* are traditional; every other Chinese region,
  and a bare zh, are simplified. A tag naming its own script wins over
  the region guess.
- The catalog tests walk a list of catalogs, so a new language is one
  line there plus one in LOCALES.

npm test: 310/310.
…sts)

Whatever page you are on, these are on screen: the minimise / maximise /
close buttons, the status line, the transfers panel and the toast's
dismiss button, plus the shared Close / Dismiss / Loading labels the
dialogs and the skeleton use.

- Two keys are plurals (statusBar.syncing, statusBar.devicesOnline).
  Chinese has a single form, so both Chinese catalogs carry a plain
  string with {n}.
- transfers.readError fills {error}; the status bar's hand-built
  "1 game / 2 games" plural is replaced by the catalog's own.
- 21 new keys in each catalog.

Left for another PR, because they are not plain strings:
- the paused status and PauseButton: their text embeds pauseLength()
- CloudOfferBanner and PairingBanner: the sentence is assembled around
  a device name in English word order
- Sidebar's "in progress", CommandPalette's entries, ConflictModal and
  LocationConflictModal

npm test: 310/310.
Review pass on the ported keys:
- unify save-folder term (存档文件夹 / 存檔資料夾) in noSavesYet
- unify program term (游戏程序 / 遊戲程式) with chooseProgram/programDialog
- align noSavesHere / noSavesYet phrasing (没有找到它的存档)
- theGame: 该游戏 -> 这款游戏 (more natural inline)
- already: 请改为将该条目关联到 -> 请把该条目关联到
- rename home.trackGameTitle -> home.trackGameHint (it is the button's
  hint text, not a title; the dialog title is home.findGame.title)
A saved 'zh-CN' (or any other zh-* tag) from before the script split is
no longer a LOCALES id, so it fell back to the system language and
someone who picked Chinese silently lost it. sanitizeLocale now maps
such tags through scriptFor: zh-CN -> zh-Hans, zh-TW/zh-HK/zh-MO ->
zh-Hant, bare zh -> zh-Hans. Non-Chinese garbage still rejects to null.

Requested by Omar-VF in Liquid-co#77.
zh-CN is no longer a LOCALES id after the script split; the test
must target zh-Hans, the Simplified catalog, to assert Chinese text.
@Omar-VF
Omar-VF merged commit 7639920 into Liquid-co:dev-public Oct 19, 2026
10 of 11 checks passed
@Omar-VF Omar-VF mentioned this pull request Oct 19, 2026
Omar-VF added a commit that referenced this pull request Oct 20, 2026
ChakraFusion pushed a commit to ChakraFusion/OpenSave that referenced this pull request Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants