feat(i18n): 接入 @huanlin/dsh-plugin-better-locale 支持 ja 覆盖
新增 ja 词典(src/client/locales-ja.ts,326 keys,与 zh key-set-equal),
通过可选 peer @huanlin/dsh-plugin-better-locale 接入第三语言覆盖:
- locales.ts: 新增 attachBetterLocale(store) + ja dict export;t() 先查
store.getOverride(active, 'betterSidebar', key),命中则返回覆盖文本,
否则走原 zh/en 链;isZh() 在 override 激活时返回 false
- client/index.tsx: apply 中 ctx.get('betterLocale') 取得 override store
(optional,未安装时为 undefined),attachBetterLocale 注入 t();同时
register('betterSidebar', { ja }) 把 ja 词典注册进 better-locale 的
store,让外部 ctx.locale.lookup 调用者也能拿到 ja 文本
- Sidebar.tsx: 新增 betterLocaleActive uSES 订阅 store.subscribe,覆盖
切换时全树重渲染(DSH locale 的 active 字段不变,既有 localeRevision
uSES 不会触发)
- package.json: @huanlin/dsh-plugin-better-locale 加为 optional peer
+ devDep link
- tests/locales.spec.ts: 新增 7 个 better-locale override 测试(命中/
fallback/detach/interpolate/ja dict 完整性 smoke check)
未安装 better-locale 时 ctx.get 返回 undefined,整段为 no-op,zh/en
行为完全不变。
This commit is contained in:
+32
-1
@@ -24,7 +24,7 @@ import { registerSettingsNavIcon } from './settings-nav-icon.ts'
|
||||
import { loadExternalDisable, loadPrefs } from './prefs.ts'
|
||||
import { SideCardSection } from './SideCardSection.tsx'
|
||||
import { api } from './api.ts'
|
||||
import { LOCALE_NS, attachLocale, t, zh, en } from './locales.ts'
|
||||
import { LOCALE_NS, attachLocale, attachBetterLocale, t, zh, en, ja } from './locales.ts'
|
||||
import css from './sidebar.module.css'
|
||||
import './layout.css'
|
||||
|
||||
@@ -57,6 +57,37 @@ export function apply(ctx: Context): void {
|
||||
const offEn = ctx.locale.register(LOCALE_NS, 'en', en)
|
||||
return () => { offZh(); offEn() }
|
||||
}, 'dsh-better-sidebar: dictionaries')
|
||||
|
||||
// Opt-in third-language support through @huanlin/dsh-plugin-better-locale.
|
||||
// When that plugin is installed, it publishes `ctx.betterLocale` (the
|
||||
// override store) and patches LocaleRuntime.prototype.lookup to consult
|
||||
// it. We mirror the same override awareness into the sidebar's own `t()`:
|
||||
// attachBetterLocale() makes t() consult the store's getOverride first,
|
||||
// so the sidebar's chrome (which bypasses ctx.locale and calls t()
|
||||
// directly) also switches to the override language. We also register
|
||||
// the ja dict with the better-locale store so external callers of
|
||||
// ctx.locale.lookup('betterSidebar', key) get the override text too.
|
||||
// Optional peer: ctx.get returns undefined when better-locale is absent,
|
||||
// in which case the whole block is a no-op and the zh/en chain runs.
|
||||
const betterLocale = ctx.get('betterLocale') as
|
||||
| {
|
||||
readonly active: string | undefined
|
||||
getOverride(dshActive: string, ns: string, key: string): string | undefined
|
||||
register(ns: string, dicts: Record<string, Record<string, string>>): () => void
|
||||
subscribe(listener: () => void): () => void
|
||||
}
|
||||
| undefined
|
||||
attachBetterLocale(betterLocale)
|
||||
if (betterLocale !== undefined) {
|
||||
ctx.effect(() => {
|
||||
// Register the ja dict for the betterSidebar namespace. Better-locale's
|
||||
// patched lookup consults this when the user has selected the ja
|
||||
// override; the dict stays owned by better-sidebar (the namespace
|
||||
// owner), so a single source of truth covers both ctx.locale callers
|
||||
// and the internal t().
|
||||
return betterLocale.register(LOCALE_NS, { ja })
|
||||
}, 'dsh-better-sidebar: better-locale ja dict')
|
||||
}
|
||||
// One store instance per activation: production code creates it only here,
|
||||
// then hands it to the mounted panel and closes over it in the slot
|
||||
// registrations (the official createXXXStore() factory rule — no
|
||||
|
||||
Reference in New Issue
Block a user