Skip to content

refactor(i18n): each feature module keeps its strings in its own namespace - #261

Merged
YIWANG3 merged 1 commit into
mainfrom
feat/feature-i18n
Nov 4, 2026
Merged

YIWANG3 merged 1 commit into
mainfrom
feat/feature-i18n

Conversation

@YIWANG3

@YIWANG3 YIWANG3 commented Nov 3, 2026

Copy link
Copy Markdown
Owner

What

The last item the feature-module plan deferred (§11.4): the LUT, AI Repaint and sticker strings move out of the host's editor / settings / nav namespaces (and the standalone stickerView one) into one namespace per feature, named by its manifest id, in features/<id>/renderer/locales/{en,zh-CN}.json. Details and decisions in docs/feature-modules-plan.md §13.

  • features/i18n.js collects the locale files with import.meta.glob (asserting both languages per manifest); src/i18n/index.js registers them next to the host's. JSON only, so no src/i18n → renderers → host components → src/i18n cycle; SUPPORTED_LOCALES moves to src/i18n/locales.js for the same reason.
  • Moved: editor.lut.* → lut (+ settings.library.lut* → lut.settings.*); editor.repaint.*, settings.tabs.repaint, settings.repaint.* → repaint (settings under repaint.settings.*: two keys clash); editor.sticker.*, nav.sidebar.stickers, the layer-picker labels and all of stickerView → sticker (the view under sticker.view.*, read with keyPrefix). The host's JSON files only lose lines; no copy changes.
  • Code: LutPanel/useLutTool use their own useTranslation("lut") instead of the t EditorOverlay passed; the sticker and repaint panels switch namespaces and drop prefixes; RepaintSettings keeps the settings hook for the shared providers.* rows and names its own keys repaint:settings.*; LutLibraryGroup does the reverse for openFolder.
  • Manifests: every labelKey carries its namespace ("lut:tool", "sticker:sidebar", …), so the host's t(labelKey) resolves whatever namespace its hook has. settingsTab.key → labelKey, like the other contributions. This amends manifest v1 in place rather than bumping to v2: no manifest exists outside the repository yet, and the README, manifestSchema.mjs and plan §12 record the amendment and its date.
  • Not moved: providers.*, handwriting.*, the rest of text.* (text tool / AI providers, host-owned). One host-side reference to a feature string remains, noted in EditorOverlay (lut:base.rendering).

Tests

features/index.test.js +3: a namespace per manifest in both languages; en and zh-CN key sets in step per feature (plural suffixes aside); every manifest labelKey resolves in its own namespace.

lint clean · test:electron 299 · test:renderer 437 · build OK · e2e 02/03/04/10/13/19/24/43/67/80: 68 passed, 1 skipped (the off-macOS case) · npm run e2e:ci-skipped: 29 passed. The whole suite runs in CI.

🤖 Generated with Claude Code

…space

The LUT, AI Repaint and sticker features' strings were spread over the
host's editor, settings and nav namespaces and a stickerView namespace of
their own (docs/feature-modules-plan.md §11.4 deferred the move until all
three had landed). Now each feature has one namespace, named by its
manifest id, in features/<id>/renderer/locales/{en,zh-CN}.json.

- features/i18n.js collects the locale files with import.meta.glob into
  featureResources (asserting both languages per manifest) and
  src/i18n/index.js registers them next to the host's namespaces. It imports
  JSON only, so src/i18n can import it without a cycle through the
  renderers; SUPPORTED_LOCALES moves to src/i18n/locales.js for the same
  reason.
- Moved: editor.lut.* and overlay.tools.lut → lut (settings.library.lut*
  → lut.settings.*, lut prefix dropped); editor.repaint.*,
  overlay.tools.repaint, settings.tabs.repaint and settings.repaint.* →
  repaint (the last under repaint.settings.*: addProvider/editProvider exist
  in both); editor.sticker.*, overlay.tools.sticker, nav.sidebar.stickers,
  text.addStickerLayer/hideStickerPicker and the whole stickerView namespace
  → sticker (the view under sticker.view.*, read with keyPrefix). The host's
  JSON files only lose lines.
- LutPanel and useLutTool translate with their own hook instead of the t
  EditorOverlay passed them; StickerPanel and AiRepaintPanel switch
  namespaces and drop the prefixes; RepaintSettings keeps the settings hook
  for the shared providers.* rows and names its own keys
  (repaint:settings.*); LutLibraryGroup does the reverse for openFolder.
- Manifests: every labelKey carries its namespace ("lut:tool",
  "sticker:sidebar", "sticker:addLayer", …), which the host's t() resolves
  whatever namespace its hook has. settingsTab.key becomes labelKey like
  the other contributions; SettingsOverlay reads it for feature tabs. This
  amends manifest v1 in place — no manifest exists outside the repository
  yet — and manifestSchema.mjs, the README and plan §12/§13 say so.
- Tests: features/index.test.js gains three cases (a namespace per manifest
  in both languages; en and zh-CN key sets in step per feature, plural
  suffixes aside; every manifest labelKey resolves in its own namespace).

No copy changes, so every e2e that finds elements by text is unaffected.
lint clean; test:electron 299, test:renderer 437, build OK; e2e
02/03/04/10/13/19/24/43/67/80: 68 passed, 1 skipped (off-macOS case);
e2e:ci-skipped: 29 passed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@YIWANG3
YIWANG3 merged commit 8e266d3 into main Nov 4, 2026
4 checks passed
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.

1 participant