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
+27
-26
@@ -16,23 +16,24 @@ import { useEffect, useMemo, useRef, useState } from '../../vendor/hooks.module.
|
||||
import { html, Icon, MicroLabel, Button, Spinner } from './components.js';
|
||||
import { createStore, useStore } from '../store.js';
|
||||
import { data, useData, artUrls, nextArtUrl } from '../data.js';
|
||||
import { t, N_ } from '../../../shared/i18n.js';
|
||||
|
||||
const cx = (...p) => p.flat().filter(Boolean).join(' ');
|
||||
|
||||
/** Page catalogue in reading order (titles transcribed from the pages). */
|
||||
export const GUIDE_CHAPTERS = [
|
||||
{ id: 'home', name: '基础规则', micro: 'BASICS', pages: [
|
||||
['autochess_home_1', '卫戍协议已运行'], ['autochess_home_2', '攻防战'], ['autochess_home_3', '休整期 · 区域'],
|
||||
['autochess_home_4', '休整期 · 资金与调度'], ['autochess_home_5', '机变阶段'], ['autochess_home_6', '限时战斗'],
|
||||
['autochess_home_7', '作战期'], ['autochess_home_8', '协同战斗'], ['autochess_home_9', '盟约'],
|
||||
{ id: 'home', name: N_('基础规则'), micro: 'BASICS', pages: [
|
||||
['autochess_home_1', N_('卫戍协议已运行')], ['autochess_home_2', N_('攻防战')], ['autochess_home_3', N_('休整期 · 区域')],
|
||||
['autochess_home_4', N_('休整期 · 资金与调度')], ['autochess_home_5', N_('机变阶段')], ['autochess_home_6', N_('限时战斗')],
|
||||
['autochess_home_7', N_('作战期')], ['autochess_home_8', N_('协同战斗')], ['autochess_home_9', N_('盟约')],
|
||||
] },
|
||||
{ id: 'shop', name: '调度手册', micro: 'HANDBOOK', pages: [
|
||||
['autochess_shop_1', '调度手册'], ['autochess_shop_2', '干员晋级'], ['autochess_shop_3', '加成情况'],
|
||||
['autochess_shop_4', '卫戍能力'], ['autochess_shop_5', '盟约'], ['autochess_shop_6', '助战及自选编队'],
|
||||
{ id: 'shop', name: N_('调度手册'), micro: 'HANDBOOK', pages: [
|
||||
['autochess_shop_1', N_('调度手册')], ['autochess_shop_2', N_('干员晋级')], ['autochess_shop_3', N_('加成情况')],
|
||||
['autochess_shop_4', N_('卫戍能力')], ['autochess_shop_5', N_('盟约')], ['autochess_shop_6', N_('助战及自选编队')],
|
||||
] },
|
||||
{ id: 'handbook', name: '进阶图鉴', micro: 'ADVANCED', pages: [
|
||||
['autochess_handbook_1', '敌人类型'], ['autochess_handbook_2', '盟约激活与叠加'], ['autochess_handbook_3', '追加盟约'],
|
||||
['autochess_handbook_4', '策略与轮选'],
|
||||
{ id: 'handbook', name: N_('进阶图鉴'), micro: 'ADVANCED', pages: [
|
||||
['autochess_handbook_1', N_('敌人类型')], ['autochess_handbook_2', N_('盟约激活与叠加')], ['autochess_handbook_3', N_('追加盟约')],
|
||||
['autochess_handbook_4', N_('策略与轮选')],
|
||||
] },
|
||||
];
|
||||
|
||||
@@ -78,9 +79,9 @@ export function openGuide(page = 0) {
|
||||
export const closeGuide = () => guideStore.set({ open: false });
|
||||
|
||||
/** Standard 玩法说明 trigger button. */
|
||||
export function GuideButton({ class: cls, size = 'sm', variant = 'ghost', label = '玩法说明', square = false }) {
|
||||
export function GuideButton({ class: cls, size = 'sm', variant = 'ghost', label = t('玩法说明'), square = false }) {
|
||||
return html`<${Button} variant=${variant} size=${size} icon="book" square=${square} class=${cx('guide-btn', cls)}
|
||||
onClick=${() => openGuide(0)} title="玩法说明" aria-label="玩法说明">${square ? null : label}<//>`;
|
||||
onClick=${() => openGuide(0)} title=${t('玩法说明')} aria-label=${t('玩法说明')}>${square ? null : label}<//>`;
|
||||
}
|
||||
|
||||
function preload(url) {
|
||||
@@ -95,9 +96,9 @@ function preload(url) {
|
||||
function TipsFallback() {
|
||||
const tips = (Array.isArray(data.get('config')?.tips) ? data.get('config').tips : []).map((t) => t?.tip).filter(Boolean);
|
||||
return html`<div class="guide__tips">
|
||||
<${MicroLabel} tone="mint">TIPS // 模拟要点</${MicroLabel}>
|
||||
<${MicroLabel} tone="mint">${t('TIPS // 模拟要点')}</${MicroLabel}>
|
||||
<ol>${tips.map((t, i) => html`<li key=${i}>${t}</li>`)}</ol>
|
||||
${!tips.length ? html`<p class="t-lo">暂无说明内容</p>` : null}
|
||||
${!tips.length ? html`<p class="t-lo">${t('暂无说明内容')}</p>` : null}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -146,42 +147,42 @@ export function GuideHost() {
|
||||
const src = stage.kind === 'image' ? stage.src : null;
|
||||
const isLoaded = !!src && loaded.has(src);
|
||||
return html`<div class="guide" role="presentation" onMouseDown=${(e) => { if (e.target === e.currentTarget) closeGuide(); }}>
|
||||
<div class="guide__box brackets" role="dialog" aria-modal="true" aria-label="玩法说明" tabindex="-1" ref=${boxRef}>
|
||||
<div class="guide__box brackets" role="dialog" aria-modal="true" aria-label=${t('玩法说明')} tabindex="-1" ref=${boxRef}>
|
||||
<header class="guide__head">
|
||||
<div class="guide__titles">
|
||||
<${MicroLabel} tone="mint">HOW TO PLAY // STRONGHOLD PROTOCOL</${MicroLabel}>
|
||||
<h2 class="guide__title">玩法说明</h2>
|
||||
<h2 class="guide__title">${t('玩法说明')}</h2>
|
||||
</div>
|
||||
${n ? html`<nav class="guide__chapters" aria-label="章节">
|
||||
${n ? html`<nav class="guide__chapters" aria-label=${t('章节')}>
|
||||
${GUIDE_CHAPTERS.map((ch, ci) => {
|
||||
const at = firstOf(ci);
|
||||
if (at < 0) return null;
|
||||
return html`<button key=${ch.id} type="button" class=${cx('guide__chapter', cur?.chapter === ci && 'is-on')} onClick=${() => go(at)}>
|
||||
<span class="guide__chname">${ch.name}</span><span class="guide__chmicro">${ch.micro}</span>
|
||||
<span class="guide__chname">${t(ch.name)}</span><span class="guide__chmicro">${ch.micro}</span>
|
||||
</button>`;
|
||||
})}
|
||||
</nav>` : null}
|
||||
<button type="button" class="guide__close" aria-label="关闭" title="关闭 (Esc)" onClick=${closeGuide}><${Icon} name="close" /></button>
|
||||
<button type="button" class="guide__close" aria-label=${t('关闭')} title=${t('关闭 (Esc)')} onClick=${closeGuide}><${Icon} name="close" /></button>
|
||||
</header>
|
||||
|
||||
${src ? html`<div class="guide__stage">
|
||||
<button type="button" class="guide__nav guide__prev" aria-label="上一页" onClick=${() => go(i - 1)}><${Icon} name="chevronLeft" /></button>
|
||||
<button type="button" class="guide__nav guide__prev" aria-label=${t('上一页')} onClick=${() => go(i - 1)}><${Icon} name="chevronLeft" /></button>
|
||||
<div class=${cx('guide__page', isLoaded && 'is-loaded')}>
|
||||
<img key=${src} src=${src} alt=${cur.title} draggable=${false}
|
||||
<img key=${src} src=${src} alt=${t(cur.title)} draggable=${false}
|
||||
onLoad=${() => setLoaded((s) => new Set(s).add(src))}
|
||||
onError=${() => setFailed((s) => new Set(s).add(src))} />
|
||||
${!isLoaded ? html`<span class="guide__loading"><${Spinner} size="md" /></span>` : null}
|
||||
</div>
|
||||
<button type="button" class="guide__nav guide__next" aria-label="下一页" onClick=${() => go(i + 1)}><${Icon} name="chevronRight" /></button>
|
||||
<button type="button" class="guide__nav guide__next" aria-label=${t('下一页')} onClick=${() => go(i + 1)}><${Icon} name="chevronRight" /></button>
|
||||
</div>` : html`<div class="guide__stage guide__stage--text"><${TipsFallback} /></div>`}
|
||||
|
||||
${n ? html`<footer class="guide__foot">
|
||||
<div class="guide__label">
|
||||
<span class="guide__chtag">${chapter?.name || ''}</span>
|
||||
<b class="guide__ptitle">${cur?.title || ''}</b>
|
||||
<span class="guide__chtag">${t(chapter?.name || '')}</span>
|
||||
<b class="guide__ptitle">${t(cur?.title || '')}</b>
|
||||
</div>
|
||||
<div class="guide__dots" role="tablist" aria-label="页码">
|
||||
${pages.map((p, k) => html`<button key=${p.key} type="button" role="tab" aria-selected=${k === i ? 'true' : 'false'} title=${p.title}
|
||||
<div class="guide__dots" role="tablist" aria-label=${t('页码')}>
|
||||
${pages.map((p, k) => html`<button key=${p.key} type="button" role="tab" aria-selected=${k === i ? 'true' : 'false'} title=${t(p.title)}
|
||||
class=${cx('guide__dot', k === i && 'is-on', k > 0 && pages[k - 1].chapter !== p.chapter && 'is-first')} onClick=${() => go(k)}></button>`)}
|
||||
</div>
|
||||
<span class="guide__count num">${i + 1} / ${n}</span>
|
||||
|
||||
Reference in new issue
Block a user