feedback5 W5S: a language switch in the middle of a screen re-reads the game texts — useGameData(), the 干员调配 / 干员持有 rosters, the strategy list and the open detail card list data.locale() among their memo dependencies (they kept the records of the language they were built in); docs/I18N.md
This commit is contained in:
1 parent
c2e77c7fe9
commit
250ad254a6
6 files changed
+8
-6
No files matched your search
+2
-1
@@ -40,7 +40,8 @@ html`<span>${tParts('第 {r} 回合 · 最终攻势', { r: html`<b class="num">$
|
||||
current language (§2). Do not wrap them in `t()`.
|
||||
- **Re-rendering**: `main.js` App subscribes with `useLang()` (`public/js/ui/lang.js`), so the whole tree re-renders on a
|
||||
switch. A component that caches text outside rendering (a `useMemo` returning text, a module-level string) must
|
||||
depend on the language (`useLang()`) or move the `t()` call into rendering.
|
||||
depend on the language (`useLang()`) or move the `t()` call into rendering; a memo over data records (the roster, the
|
||||
strategy list, `useGameData()`) lists `data.locale()` among its dependencies, so the game texts follow the switch.
|
||||
- Font samples, data keys and other Chinese that is not UI text can carry `// i18n-ignore` on the line.
|
||||
|
||||
### Translating
|
||||
|
||||
@@ -179,7 +179,7 @@ export function BandDraftScreen() {
|
||||
const mode = gd.config?.modes?.[pub?.modeId];
|
||||
const offBonds = modeOffBonds(mode); // the bonds this mode never activates (标准: 10 of 23)
|
||||
const solo = roomSolo || mode?.type === 'SINGLE' || String(pub?.modeId || '').includes('single');
|
||||
const bands = useMemo(() => allowedBands(gd.list('bands'), mode?.type || (solo ? 'SINGLE' : 'MULTI')), [gd.ready, mode?.type, solo]);
|
||||
const bands = useMemo(() => allowedBands(gd.list('bands'), mode?.type || (solo ? 'SINGLE' : 'MULTI')), [gd.ready, mode?.type, solo, data.locale()]);
|
||||
const players = sortedPlayers(pub);
|
||||
const draft = normalizeDraft(pub?.draft, players);
|
||||
const myPick = draft.picks.get(myId) || priv?.bandId || null;
|
||||
|
||||
@@ -1044,7 +1044,7 @@ function MatchScreen() {
|
||||
const u = (Array.isArray(field?.units) ? field.units : []).find((x) => x && x.id === detail.unitId);
|
||||
return u ? { ...detail, unit: u } : detail;
|
||||
}, [detail, field]);
|
||||
const resolved = useMemo(() => resolveDetail(detailTarget, placeCtx.pieces, { priv, backups: gd.backups }), [detailTarget, placeCtx, gd.ready]);
|
||||
const resolved = useMemo(() => resolveDetail(detailTarget, placeCtx.pieces, { priv, backups: gd.backups }), [detailTarget, placeCtx, gd.ready, data.locale()]);
|
||||
useEffect(() => { if (detail && !resolved && detail.kind === 'piece') setDetail(null); }, [resolved]);
|
||||
const snapHp = (() => {
|
||||
const id = resolved?.unitId;
|
||||
|
||||
@@ -403,7 +403,7 @@ function LoadoutScreen({ st }) {
|
||||
const m = data.get('assets');
|
||||
const getChess = (id) => data.lookup('chess', id);
|
||||
const getBond = (id) => data.lookup('bonds', id);
|
||||
const roster = useMemo(() => rosterOf(data.list('chess')), [ready]);
|
||||
const roster = useMemo(() => rosterOf(data.list('chess')), [ready, data.locale()]); // (names follow a language switch)
|
||||
const bonds = useMemo(() => {
|
||||
const used = new Set(roster.flatMap((c) => c.bonds || []));
|
||||
return (data.list('bonds') || []).filter((b) => b && used.has(b.bondId))
|
||||
|
||||
@@ -23,7 +23,7 @@ const ROMAN = ['', 'I', 'II', 'III', 'IV', 'V', 'VI'];
|
||||
|
||||
/** The roster of the tab (data.list('chess'), memoised on the data being ready). */
|
||||
export function useOwnershipRoster(ready) {
|
||||
return useMemo(() => ownershipRoster(data.list('chess')), [ready]);
|
||||
return useMemo(() => ownershipRoster(data.list('chess')), [ready, data.locale()]);
|
||||
}
|
||||
|
||||
/** One chess: the operator → its stand-in, and the 持有 switch (the whole card is the switch). */
|
||||
|
||||
@@ -24,7 +24,8 @@ export const GAME_FILES = ['config', 'assets', 'chess', 'bonds', 'items', 'bands
|
||||
*/
|
||||
export function useGameData() {
|
||||
const ready = useData(...GAME_FILES);
|
||||
return useMemo(() => makeLookups(ready), [ready]);
|
||||
// (config / factions / choices are read once per memo: a language switch reads them again in the new locale)
|
||||
return useMemo(() => makeLookups(ready), [ready, data.locale()]);
|
||||
}
|
||||
|
||||
/** A 自选 operator's summon record (data/backups.json `tokens`, 0.2.0), or null. */
|
||||
|
||||
Reference in new issue
Block a user