feedback5 W5S: i18n phase 2, ui — HUD, shop bar, detail card, bond strip and popup, 机变 overlay, enemy drawer, team panel, under-frame, guide, emotes, match chrome, connection banner, components, the loadout / roster models, the store, net and observe texts through t() / tParts() (whole sentences where a number or a name sat inside), msgid tables marked N_() and translated where shown, the shop's refusal reasons compared through t(); tools/i18n.mjs reads aliased imports (t as tr); English for the 59 new msgids; Chinese output unchanged (zh render proof; five rewrites checked by hand, listed in the notes)
This commit is contained in:
1 parent
166c4fbbfb
commit
647bd23ef2
33 files changed
+530
-427
No files matched your search
+11
-11
@@ -194,12 +194,12 @@ export function tierChipUrl(t) {
|
||||
* @param {{ tier: number, golden?: boolean, size?: 'sm'|'md'|'lg', class?: string }} props
|
||||
*/
|
||||
export function TierChip({ tier, golden = false, size = 'md', class: cls }) {
|
||||
const t = Math.max(1, Math.min(6, Number(tier) | 0 || 1));
|
||||
const src = tierChipUrl(t);
|
||||
const n = Math.max(1, Math.min(6, Number(tier) | 0 || 1));
|
||||
const src = tierChipUrl(n);
|
||||
const [bad, setBad] = useState(null);
|
||||
const img = !!src && bad !== src;
|
||||
return html`<span class=${cx('tier', `tier--${t}`, `tier--${size}`, golden && 'tier--golden', img && 'tier--img', cls)} aria-label=${`${t}阶`}>
|
||||
${img ? html`<img src=${src} alt="" draggable=${false} onError=${() => setBad(src)} />` : roman(t)}
|
||||
return html`<span class=${cx('tier', `tier--${n}`, `tier--${size}`, golden && 'tier--golden', img && 'tier--img', cls)} aria-label=${t('{tier}阶', { tier: n })}>
|
||||
${img ? html`<img src=${src} alt="" draggable=${false} onError=${() => setBad(src)} />` : roman(n)}
|
||||
</span>`;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ export function BondDisc({
|
||||
: html`<span class="bond__glyph">${glyph}</span>`}
|
||||
</span>
|
||||
${stack != null ? html`<span class="bond__count">${stack}</span>` : null}
|
||||
${disabled ? html`<span class="bond__ban" aria-label="禁用"><${Icon} name="close" /></span>` : null}
|
||||
${disabled ? html`<span class="bond__ban" aria-label=${t('禁用')}><${Icon} name="close" /></span>` : null}
|
||||
</span>
|
||||
${showName && name ? html`<span class="bond__name">${name}</span>` : null}
|
||||
<//>`;
|
||||
@@ -373,7 +373,7 @@ export function Countdown({ deadline, seconds, total, warnAt = 10, label = 'COUN
|
||||
|
||||
// untimed phase: no timer on screen (hooks above run unconditionally, so the component may toggle freely)
|
||||
if (remain == null) return null;
|
||||
return html`<div class=${cx('countdown', `countdown--${size}`, warn && 'is-warn', cls)} role="timer" aria-label=${remain == null ? '无倒计时' : `剩余${remain}秒`}>
|
||||
return html`<div class=${cx('countdown', `countdown--${size}`, warn && 'is-warn', cls)} role="timer" aria-label=${remain == null ? t('无倒计时') : t('剩余{remain}秒', { remain })}>
|
||||
<div class="countdown__main">
|
||||
<${SevenSeg} text=${text} tone=${warn ? 'orange' : 'mint'} flicker=${warn && remain > 0} />
|
||||
${label ? html`<span class="countdown__label">${label}</span>` : null}
|
||||
@@ -489,7 +489,7 @@ export function DialogHost() {
|
||||
}, []);
|
||||
const d = dialogs[0];
|
||||
if (!d) return null;
|
||||
const { title = '确认', text, okText = '确认', cancelText = '取消', tone, danger, micro = 'CONFIRMATION' } = d.opts;
|
||||
const { title = t('确认'), text, okText = t('确认'), cancelText = t('取消'), tone, danger, micro = 'CONFIRMATION' } = d.opts;
|
||||
const isConfirm = d.kind === 'confirm';
|
||||
// Enter confirms unless a specific button has focus (then the native click decides).
|
||||
const onKey = (e) => {
|
||||
@@ -670,7 +670,7 @@ export function Spinner({ size = 'md', label, tone = 'mint', class: cls }) {
|
||||
<polygon class="spinner__track" points="25,3 44,14 44,36 25,47 6,36 6,14" />
|
||||
<polygon class="spinner__arc" points="25,3 44,14 44,36 25,47 6,36 6,14" />
|
||||
</svg>
|
||||
${label ? html`<span class="spinner__label">${label}</span>` : html`<span class="sr-only">加载中</span>`}
|
||||
${label ? html`<span class="spinner__label">${label}</span>` : html`<span class="sr-only">${t('加载中')}</span>`}
|
||||
</span>`;
|
||||
}
|
||||
|
||||
@@ -695,8 +695,8 @@ export function AvatarFrame({ name = '', src, size = 'md', seat = 0, host, bot,
|
||||
: bot ? html`<${Icon} name="robot" class="avatar__bot" />`
|
||||
: html`<span class="avatar__glyph">${glyph}</span>`}
|
||||
</div>
|
||||
${host ? html`<span class="avatar__badge avatar__badge--host" title="创建者"><${Icon} name="crown" /></span>` : null}
|
||||
${self ? html`<span class="avatar__badge avatar__badge--self" title="你"><${Icon} name="user" /></span>` : null}
|
||||
${host ? html`<span class="avatar__badge avatar__badge--host" title=${t('创建者')}><${Icon} name="crown" /></span>` : null}
|
||||
${self ? html`<span class="avatar__badge avatar__badge--self" title=${t('你')}><${Icon} name="user" /></span>` : null}
|
||||
${bot && !empty ? html`<span class="avatar__tag">AI</span>` : null}
|
||||
</div>`;
|
||||
}
|
||||
@@ -755,7 +755,7 @@ export function doctorNo(id) {
|
||||
export function PingPill({ ms, online = true, class: cls }) {
|
||||
const ok = online && Number.isFinite(ms);
|
||||
const tier = !ok ? 'off' : ms < 60 ? 'low' : ms < 200 ? 'medium' : 'high';
|
||||
return html`<span class=${cx('ping', `ping--${tier}`, cls)} title=${ok ? `当前延迟 ${ms}ms` : '未连接'}>
|
||||
return html`<span class=${cx('ping', `ping--${tier}`, cls)} title=${ok ? t('当前延迟 {ms}ms', { ms }) : t('未连接')}>
|
||||
<${Icon} name=${ok ? 'signal' : 'wifiOff'} class="ping__icon" />
|
||||
<span class="ping__value">${ok ? Math.min(9999, Math.round(ms)) : '--'}</span><span class="ping__unit">ms</span>
|
||||
</span>`;
|
||||
|
||||
Reference in new issue
Block a user