feedback5 W5S: i18n phase 2, render labels — the battlefield canvas label, the 2D fallback field (bench label, piece names, empty enemy pen), the facing wheel (prompt, cancel hints, the four directions) through t(); English for the 3 new msgids; Chinese output unchanged (zh render proof)

This commit is contained in:
sganggs committed 2026-10-06 18:14:08 +08:00
1 parent 5741dc129b
commit 7e262dc809
5 files changed
+20 -13

No files matched your search

+4 -1
View File
@@ -1075,5 +1075,8 @@
"联防:{names}": "Unite: {names}",
"剩余资金": "Funds Left",
"继续整备": "Keep Preparing",
"还有 {funds} 资金未使用。休整期结束时,本回合的剩余资金将清零。确定准备就绪吗?": "You still have {funds} unspent Funds. The round's leftover Funds are cleared when the Rest Phase ends. Ready anyway?"
"还有 {funds} 资金未使用。休整期结束时,本回合的剩余资金将清零。确定准备就绪吗?": "You still have {funds} unspent Funds. The round's leftover Funds are cleared when the Rest Phase ends. Ready anyway?",
"选择「{name}」的朝向": "Choose {name}'s facing",
"选择朝向": "Choose a facing",
"朝向:{dir}": "Facing: {dir}"
}
+2 -1
View File
@@ -134,6 +134,7 @@ import { CAMERA_MS, BOARD3D_STABLE_MS, BOARD3D_RETRY_MS, PEN_CAMERA_MS, RANGE_GR
import { boardPreference, switchableBox, bandFor, fieldRows, boardArea, viewKind, penShown, leaderShown } from './app/view.js';
import { renderInfo, FORCED_EXIT, showsDeathFx } from './app/info.js';
import { resolveAssets, makeData, withTimeout, QUALITY_RES, BOARD_RES, releaseGl } from './app/host.js';
import { t } from '../../../shared/i18n.js';
export { ensurePixi } from './app/pixi.js';
export { PEN_CAMERA_MS, LEADER_HIT_STYLE, DRAG_HOLD_TILES } from './app/tune.js';
@@ -185,7 +186,7 @@ export async function createFieldView(host, options = {}) {
canvas.style.height = '100%';
canvas.style.touchAction = 'none';
canvas.style.userSelect = 'none';
canvas.setAttribute('aria-label', '战场');
canvas.setAttribute('aria-label', t('战场'));
canvas.style.position = 'relative';
canvas.style.zIndex = '1';
host.appendChild(canvas);
+2 -1
View File
@@ -14,6 +14,7 @@
import { GEO } from '../../../shared/constants.js';
import { attackRangeGrid } from '../../../shared/loadoutRecord.js';
import { N_ } from '../../../shared/i18n.js';
export const DIRS = Object.freeze(['UP', 'RIGHT', 'DOWN', 'LEFT']);
export const DEFAULT_DIR = 'RIGHT';
@@ -29,7 +30,7 @@ export const DIR_VEC = Object.freeze({
});
/** Chinese label (for aria / tooltips). */
export const DIR_LABEL = Object.freeze({ UP: '上', RIGHT: '右', DOWN: '下', LEFT: '左' });
export const DIR_LABEL = Object.freeze({ UP: N_('上'), RIGHT: N_('右'), DOWN: N_('下'), LEFT: N_('左') });
/** Normalise any direction spelling ('up', 'Right', 1/−1 facing) to UP|RIGHT|DOWN|LEFT; unknown → `fallback`. */
export function normDir(d, fallback = DEFAULT_DIR) {
+6 -5
View File
@@ -25,6 +25,7 @@ import { useEffect, useLayoutEffect, useRef, useState } from '../../vendor/hooks
import { html } from './components.js';
import { LocalSprite } from './gameComponents.js';
import { DIRS, DIR_LABEL, DEAD_ZONE_TILES, dirFromDelta, dirFromKey, rangeTiles, normDir, boardDir, viewMirrored } from './facing.js';
import { t } from '../../../shared/i18n.js';
const cx = (...p) => p.flat().filter(Boolean).join(' ');
const rawOf = (view) => (view && view.raw) || view || null;
@@ -249,7 +250,7 @@ export function FacingWheel({ view, row, col, grid, name = '', onPreview, onComm
const outside = !!drag && !!dir;
const box = half * 2;
return html`<div class=${cx('fwheel', drag && 'is-pressed', dir && `is-${dir.toLowerCase()}`)} role="dialog" aria-label=${`选择${name ? `「${name}」的` : ''}朝向`}
return html`<div class=${cx('fwheel', drag && 'is-pressed', dir && `is-${dir.toLowerCase()}`)} role="dialog" aria-label=${name ? t('选择「{name}」的朝向', { name }) : t('选择朝向')}
onPointerDown=${onDown} onPointerMove=${onMove} onPointerUp=${onUp} onPointerCancel=${onPointerCancel}
onContextMenu=${(e) => { e.preventDefault(); onCancel(); }}>
${g ? html`<${Stripes} tiles=${tiles} view=${view} row=${row} col=${col} />` : null}
@@ -264,12 +265,12 @@ export function FacingWheel({ view, row, col, grid, name = '', onPreview, onComm
${DIRS.map((d) => html`<${Chevron} key=${d} dir=${d} on=${dir === d} />`)}
</svg>
<button type="button" class="fwheel__cancel" onPointerDown=${(e) => e.stopPropagation()}
onClick=${(e) => { e.stopPropagation(); onCancel(); }} aria-label="点击取消">
onClick=${(e) => { e.stopPropagation(); onCancel(); }} aria-label=${t('点击取消')}>
<${LocalSprite} name="cancel_icon" class="fwheel__x" fallback=${html`<span class="fwheel__x fwheel__x--txt">✕</span>`} />
<span>点击取消</span>
<span>${t('点击取消')}</span>
</button>
${outside ? html`<span class="fwheel__tip" role="status">拖回中心区域取消</span>` : null}
<span class="fwheel__sr" aria-live="polite">${dir ? `朝向:${DIR_LABEL[dir]}` : ''}</span>
${outside ? html`<span class="fwheel__tip" role="status">${t('拖回中心区域取消')}</span>` : null}
<span class="fwheel__sr" aria-live="polite">${dir ? t('朝向:{dir}', { dir: t(DIR_LABEL[dir]) }) : ''}</span>
</div>` : null}
</div>`;
}
+6 -5
View File
@@ -24,6 +24,7 @@ import { html, TierChip } from './components.js';
import { GEO } from '../../../shared/constants.js';
import { chessAvatarUrl, itemIconUrl, tokenAvatarUrl, enemyIconUrl } from './assetUrls.js';
import { tileKey, hasFlag, UF, penPlacement, PEN, fieldTile, ownStandIn, ownDiyRecord } from './gameLogic.js';
import { t } from '../../../shared/i18n.js';
const DRAG_PX = 6;
const DMG_TTL = 900;
@@ -137,10 +138,10 @@ export function createFallbackView(host, opts = {}) {
return chess ? ownDiyRecord(chess, st.priv, { chess: dataStore?.get?.('chess') ?? null, backups: dataStore?.get?.('backups') ?? null }) : null;
}
function pieceName(p) {
if (p.kind === 'item') return lookup('items', p.id)?.name || '道具';
if (p.kind === 'token') return lookup('tokens', p.id)?.name || '召唤物';
if (p.kind === 'item') return lookup('items', p.id)?.name || t('道具');
if (p.kind === 'token') return lookup('tokens', p.id)?.name || t('召唤物');
const chess = lookup('chess', p.id);
return (ownSi(chess) || ownDiy(chess) || chess)?.name || '干员';
return (ownSi(chess) || ownDiy(chess) || chess)?.name || t('干员');
}
function Piece({ p, x, y, L, area }) {
@@ -303,7 +304,7 @@ export function createFallbackView(host, opts = {}) {
});
return html`<div class="ff-board ff-board--pen" style=${`left:${left}px;top:${top}px;width:${bw}px;height:${tile * rows}px;--tile:${tile}px`}>
${cells}${figs}
${models.length ? null : html`<p class="ff-pen__empty">暂无敌方情报</p>`}
${models.length ? null : html`<p class="ff-pen__empty">${t('暂无敌方情报')}</p>`}
</div>`;
}
@@ -372,7 +373,7 @@ export function createFallbackView(host, opts = {}) {
})() : null;
if (st.camera === 'pen') { render(html`${penView()}<div class="ff-badge">SIMPLIFIED VIEW</div>`, root); return; }
render(html`<div class=${cx('ff-board', `ff-board--${st.mode}`, `ff-cam--${st.camera}`)} style=${`left:${L.left}px;top:${L.top}px;width:${L.bw}px;height:${L.bh}px;--tile:${L.tile}px`}>
${st.mode === 'prep' ? html`<div class="ff-hand-label" style=${`top:${(L.rows + 0.18) * L.tile}px`}><span>整备区</span><i></i></div>` : null}
${st.mode === 'prep' ? html`<div class="ff-hand-label" style=${`top:${(L.rows + 0.18) * L.tile}px`}><span>${t('整备区')}</span><i></i></div>` : null}
${tiles}${hand}${units}${pieces}${floats}
</div>${ghost}
<div class="ff-badge">SIMPLIFIED VIEW</div>`, root);