feat(client): adopt the locale seat in theme, sidebar, question, and model

Each package ships its zh/en dictionaries as satisfies-typed pairs (zh is
the key-set source of truth; en is checked complete against it), merges its
namespace into LocaleNamespaceMap, and declares locale: NS at register —
components read the framework-injected typed t seat instead of a
hand-carried inject member. Overlapping verbatim words (retry, submit,
submitting) drop out of package dictionaries in favor of the shared common
vocabulary; the question composer stores validation feedback as dictionary
keys so shown feedback follows a locale switch.
This commit is contained in:
imccyu
2026-07-30 01:04:58 +08:00
parent c317fbc489
commit 2c5114c060
11 changed files with 58 additions and 44 deletions
@@ -238,13 +238,13 @@ export function ModelSelect(
{state.error !== null && (
<div className={css.error}>
<span>{t('error.action', { message: state.error })}</span>
<button type="button" className={css.retry} onClick={() => { load() }}>{t('action.retry')}</button>
<button type="button" className={css.retry} onClick={() => { load() }}>{t('retry')}</button>
</div>
)}
{state.failures.map(failure => (
<div className={css.warning} key={failure.id}>
<span>{t('warning.groupLoad', { name: failure.name, message: failure.message })}</span>
<button type="button" className={css.retry} onClick={() => { load() }}>{t('action.retry')}</button>
<button type="button" className={css.retry} onClick={() => { load() }}>{t('retry')}</button>
</div>
))}
<div className={clsx(css.groups, 'scrollable')}>
@@ -14,7 +14,6 @@ export const zh = {
'effort.providerDefault': '服务商默认',
'status.loading': '正在刷新模型列表…',
'error.action': '模型操作失败:{message}',
'action.retry': '重试',
'action.reload': '重新加载',
'warning.groupLoad': '{name} 加载失败:{message}',
'option.currentUnlisted': '当前模型 · 未列入目录',
@@ -26,7 +25,7 @@ export const zh = {
export type ModelKey = keyof typeof zh
/** English dictionary, checked complete against the zh key set. */
export const en: Record<ModelKey, string> = {
export const en = {
'command.description': 'Select the model for this conversation',
'option.unlisted': '{group} · Not in catalog',
'option.loadError': 'Catalog failed to load: {message}',
@@ -39,10 +38,9 @@ export const en: Record<ModelKey, string> = {
'effort.providerDefault': 'Provider default',
'status.loading': 'Refreshing model list…',
'error.action': 'Model operation failed: {message}',
'action.retry': 'Retry',
'action.reload': 'Reload',
'warning.groupLoad': '{name} failed to load: {message}',
'option.currentUnlisted': 'Current model · Not in catalog',
'empty.models': 'No models available.',
'empty.efforts': 'This model provides no reasoning effort levels.',
}
} satisfies Record<ModelKey, string>