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:
1 parent
5741dc129b
commit
7e262dc809
5 files changed
+20
-13
No files matched your search
+4
-1
@@ -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}"
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>`;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user