Commit graph

2 commits

Author SHA1 Message Date
MHSanaei
18658b7eaa
i18n: collapse two translation databases into a single web/translation/<lang>.json set
The Vue SPA had been reading from frontend/src/locales/*.json while the
Go binary still loaded web/translation/translate.*.toml — and a
sync-locales.mjs pre-build step kept the two in lockstep, with TOML as
the source of truth. Now that go-i18n v2.6.1 already flattens nested
JSON via recGetMessages/addChildMessages, both runtimes can share one
file per locale.

- Move the 13 nested-JSON locale files to web/translation/<lang>.json
  so they live alongside the Go //go:embed translation/* directive.
- Switch web/locale/locale.go from toml.Unmarshal to json.Unmarshal
  (and drop the pelletier/go-toml import — it's now indirect-only).
  Confirmed via a smoke test that pages.index.cpu, subscription.title,
  tgbot.commands.help, and menu.settings all resolve in en-US, fa-IR,
  ru-RU, and zh-CN.
- Repoint Vue's i18n loader at the new path (../../../web/translation/
  *.json glob) and drop the moved-here pathDelimiter comment that no
  longer applies.
- Delete the 13 legacy translate.*.toml files and the sync-locales.mjs
  script + its npm pre-script hooks (predev/prebuild/i18n:sync). The
  Telegram bot and subscription page still get their messages because
  they were reading the same MessageIDs the JSON files now produce.
- Update copilot-instructions.md so the next contributor knows where
  the canonical translation files live.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 18:05:56 +02:00
MHSanaei
35efeb983e
feat(frontend): Phase 7 — vue-i18n wired up + login page translated
Sets up vue-i18n on top of the panel's existing TOML translation
files. The Go side stays the source of truth — translators continue
to edit web/translation/*.toml; a sync script snapshots those files
into per-locale JSON the Vue bundle imports. The login page is
translated end-to-end as a worked example; remaining pages can be
converted incrementally without infrastructure churn.

What's in the box:
- scripts/sync-locales.mjs: small TOML→JSON converter that walks
  web/translation/*.toml and writes frontend/src/locales/<code>.json.
  Handles the narrow subset of TOML the panel uses (flat key/value
  pairs + dotted [section.subsection] heads). Wired as a `prebuild`
  + `predev` script so production builds always include the latest
  strings without a manual step.
- src/i18n/index.js: createI18n() in composition mode with all 13
  locales emitted as their own Vite chunks. The active locale (read
  from the same `lang` cookie LanguageManager has always managed)
  plus the en-US fallback are eagerly loaded; the rest are
  dynamically importable via a loadLocale(code) helper. This keeps
  the per-page bundle the user actually downloads small — only ~30
  KB of strings end up in the initial payload, vs ~220 KB if all
  13 were eager.
- All five page entries (index/login/settings/inbounds/xray) wire
  the i18n plugin into createApp via .use(i18n).
- LoginPage.vue: t(...) replaces hardcoded English on the username
  / password / 2FA placeholders, the submit button label, and the
  Settings popover title. The Hello/Welcome headline cycle stays
  hardcoded — those are stylistic, not labels.

The 'Hello'/'Welcome' cycle stays in English deliberately; the rest
of the migration's components still ship hardcoded English and will
be converted page by page in follow-up commits.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 14:54:07 +02:00