Skip to content

feat(i18n): move settings texts into dictionaries with en and zh - #178

Merged
AliceSaikawa merged 4 commits into
mainfrom
feat/issue-78-i18n-settings
Oct 22, 2026
Merged

AliceSaikawa merged 4 commits into
mainfrom
feat/issue-78-i18n-settings

Conversation

@AliceSaikawa

@AliceSaikawa AliceSaikawa commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Why

Part of the English and Simplified Chinese rollout (Issue #78). The settings tab still wrote its Japanese inline, and the settings store and schema produced Japanese text outside React. This moves the settings tab (except providers and models, #179) into dictionaries with ja, en and zh. Until the last PR adds the languages to DISPLAY_LOCALES, the page stays Japanese.

Scope

  • web/src/features/settings/messages.ts: en/zh for agentPresetMessages; new appearanceMessages, settingsFieldMessages, settingsSchemaMessages, settingsScreenMessages, settingsStoreMessages. generalMessages is unchanged.
  • schema.ts: names, notes, summaries and parse errors come from settingsSchemaMessages; hostTextInLocale replaces the Japanese-only japanese() filter.
  • store.ts: texts are made with currentLocale() when they happen; displayableRejection(message, locale).
  • SettingsScreen.tsx, SettingsDetailScreen.tsx, SchemaFields.tsx, AppearanceSheet.tsx; theme color names move from THEME_COLOR_PRESETS (web/src/app/theme/appearance.ts) into appearanceMessages.
  • SchemaFields.tsx FieldEditor: each option label sits in a keyed span and the select's value is set again once it settles, because m3e-select kept stale option copies and could lose its selection when the language and the stored value changed together (found by the language-row e2e of the last PR).
  • Terms: docs/i18n/terms/settings.md; the main terms are also rows in docs/i18n/glossary.md.

Tradeoffs

  • A Host title or description is shown only when it is written in the page language (Japanese keeps its old rule; Chinese: Han without kana; English: ASCII with a letter). Otherwise M3E's own name or the numbered fallback is used, as Japanese does today.
  • Rejection reasons: Chinese shows a Chinese-only reason as is; English always shows the fixed text, because an English reason cannot be told apart from one that carries input values.
  • About 600 of the added lines are dictionary entries.

Blast radius

No visible change: Japanese strings and results are identical, and the existing settings unit tests (tests/08-*.test.ts) pass with unchanged expectations.

Verification

  • pnpm typecheck, pnpm test (1,460 tests, 1,458 pass, 2 existing skips), git diff --check pass.
  • tests/08-i18n-settings-core.test.ts checks hostTextInLocale, displayableRejection and parse errors per language.
  • With every i18n PR merged and English and Chinese enabled, the full mock e2e (425 tests, ja-JP) passes except the language-row tests that the last PR rewrites.

Refs #78

…d Chinese

The settings tab, its detail pages, the schema-driven fields, the appearance sheet and the modes page now read their texts from web/src/features/settings/messages.ts, with English and Simplified Chinese next to the Japanese. Host titles and descriptions are shown only when they are written in the page language. In Chinese a Chinese-only rejection reason is shown as is, and in English the fixed message is used.
… language change

m3e-select copies its options only when their child list changes, so a select kept showing the old option labels after the page language changed. Each label now sits in a keyed span, so a new label replaces a node and the copy is made again. The select also applies each value asynchronously and could end with no option selected when the language and the stored value changed together, so the field sets the value again once those applications have settled.

Copy link
Copy Markdown
Owner Author

独立レビュー(自動)の結果です。

判定:直してからマージ

指摘(優先度順)

  1. 設定トップの提供元の行の補足だけが日本語のまま(web/src/features/settings/use-provider-summary.ts:26)
    • return providerSummary(state) が引数なしで呼ばれ、providerSummary(schema.ts:571)の既定値 text = schemaText()・locale = 'ja' が使われます。英語・中国語でも日本語の補足が出ます。
    • 直し方:フック内で今の言語の辞書と locale(useMessages(...)・useLocale() など)を取り、providerSummary(state, text, locale) と渡してください。言語切り替えで描き直されることを試験で確認してください。
  2. 数値の刻みの誤りを「倍数」と案内している(web/src/features/settings/messages.ts:344 英語、:423 中国語)
    • 判定は matchesNumberStep(value, field.min, field.step)(schema.ts:505)で、min を起点にした刻みです。min が 0 でないとき「〜の倍数」は誤りです。日本語「${value} 刻みで入力してください。」(L265) の意味に合わせ、英語は Enter a value in steps of ${value}.、中国語は 请按 ${value} 的步长输入。 のようにしてください。
  3. 最小モードの説明が日本語の原文にない内容を含む(messages.ts:79 英語、:116 中国語)
    • 日本語 (L42) は「ターミナルのツールだけを使って作業します。基本的な性能を確かめたり比べたりするのに使えます。」ですが、英語・中国語は「画像の読み取り」「コンテキストの圧縮」を足しています。日本語の原文どおりに訳すか、DSH の guideMinimalIntro に合わせるなら日本語側も同じ内容にそろえてください(三言語で同じ意味に)。
  4. 言語切り替え後に画面を離れると、通知に切り替え前の項目名が出る(web/src/features/settings/SchemaFields.tsx:100)
    • useEffect(..., [input]) のクリーンアップ内で field.label を読んでおり、最初の描画時のクロージャの値(切り替え前の言語)が使われます。
    • 直し方:const labelRef = useRef(field.label); labelRef.current = field.label のように毎回の描画で更新し、クリーンアップでは labelRef.current を使ってください。
  5. PR タイトルが 78 字:AGENTS.md の上限 72 字を超えていて、.github/workflows/pr-title.yml で落ちます。
    • 短縮案:feat(i18n): move settings texts into dictionaries with en and zh(64 字)
  6. glossary 未更新
    • docs/design/11-i18n.md:118 の規則(訳を足す PR では docs/i18n/glossary.md に新しい用語を足す)に反しています。用語は docs/i18n/terms/settings.md にだけ書かれています。
    • 新しい用語を docs/i18n/glossary.md の表に行として追記してください(terms ファイルを残すなら glossary.md からリンク)。

確認済み

  • typecheck・test(失敗 0)は通っています。

メモ:#179 はこの PR のブランチを base にしています。この PR を先にマージし、その後 #179 を main に向け直して rebase してください。

@AliceSaikawa AliceSaikawa changed the title feat(i18n): move the settings texts into dictionaries with English and Chinese feat(i18n): move settings texts into dictionaries with en and zh Oct 22, 2026
… notices

The provider row on the settings top now builds its summary with the page language's dictionary and number format, instead of the Japanese defaults of providerSummary. When a field is left after a language change, the save failure notice names the field in the current language, because SchemaFields reads the label through a ref.

The English and Chinese step error now says "in steps of", since matchesNumberStep counts the steps from the field's minimum. The Minimal mode description says only what the Japanese says.
docs/design/11-i18n.md asks each translation PR to add its new terms to docs/i18n/glossary.md. The rows link to docs/i18n/terms/settings.md for the rest.
@AliceSaikawa
AliceSaikawa merged commit c2a1ec8 into main Oct 22, 2026
7 checks passed
@AliceSaikawa
AliceSaikawa deleted the feat/issue-78-i18n-settings branch October 22, 2026 12:43
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