feedback5 W5S: i18n phase 2, match texts the server sends — a 机变 card's and an effect entry's name and description, the draft's name, a reward offer's label and the result title are shown from the localized data when the server's Chinese text is the data record's own (data.lookupRaw + ui/lang.js sentText; names through tName), a text the server reworded (a multi-round 悬赏) stays as sent; Chinese output unchanged by construction (in Chinese the localized record is the raw one); test/i18n-server.test.js covers it
This commit is contained in:
1 parent
7697b4ff40
commit
0025ceac16
7 files changed
+111
-15
No files matched your search
@@ -6,7 +6,8 @@ import { html, Tooltip, MicroLabel } from './components.js';
|
||||
import { Img, RichText, GIcon } from './gameComponents.js';
|
||||
import { effectIconUrl } from './assetUrls.js';
|
||||
import { data } from '../data.js';
|
||||
import { t, N_ } from '../../../shared/i18n.js';
|
||||
import { t, tName, N_ } from '../../../shared/i18n.js';
|
||||
import { sentText } from './lang.js';
|
||||
|
||||
const KIND = { band: N_('策略'), choice: N_('机变'), team: N_('团队增益'), item: N_('道具'), garrison: N_('特质') };
|
||||
|
||||
@@ -17,6 +18,31 @@ const KIND = { band: N_('策略'), choice: N_('机变'), team: N_('团队增益'
|
||||
*/
|
||||
export const bountyCounterText = (e) => (e.counter == null ? t('之后的每场作战') : t('还剩 {left} 场作战', { left: e.counter }));
|
||||
|
||||
/** Data files whose records an effect entry copies its name / description from (by its id or icon id). */
|
||||
const SOURCES = ['effects', 'bands', 'items', 'garrisons'];
|
||||
|
||||
/**
|
||||
* An effect entry's description in the current language (the server copies a record's Chinese text: an effect's, a
|
||||
* strategy's, an item's, a 特质's — sentText; a reworded one, such as a multi-round 悬赏's, stays as sent).
|
||||
* @param {{ id?: string, iconId?: string, desc?: string }} e
|
||||
*/
|
||||
export function effectDesc(e) {
|
||||
const desc = e.desc || '';
|
||||
if (!desc) return desc;
|
||||
for (const file of SOURCES) {
|
||||
for (const id of [e.id, e.iconId]) {
|
||||
const raw = typeof id === 'string' && id ? data.lookupRaw(file, id) : null;
|
||||
if (!raw) continue;
|
||||
const loc = data.lookup(file, id) || raw;
|
||||
for (const k of ['descRaw', 'desc']) {
|
||||
const v = sentText(desc, raw[k], loc[k]);
|
||||
if (v !== desc) return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
/** @param {{ effects: any[] }} props */
|
||||
export function EffectsList({ effects }) {
|
||||
const list = (Array.isArray(effects) ? effects : []).filter((e) => e && (e.name || e.desc));
|
||||
@@ -25,8 +51,8 @@ export function EffectsList({ effects }) {
|
||||
return html`<div class="effects" aria-label=${t('生效中的效果')}>
|
||||
<${MicroLabel}>EFFECTS</${MicroLabel}>
|
||||
${list.slice(0, 10).map((e, i) => html`<${Tooltip} key=${e.id ?? i} placement="bottom" text=${html`<div class="efftip">
|
||||
<b>${e.name || t('效果')}</b><span class="efftip__kind">${t(KIND[e.iconKind] || '')}${e.counterText ? ` · ${bountyCounterText(e)}` : e.counter != null ? ` · ${e.counter}` : ''}</span>
|
||||
<${RichText} as="p" text=${e.desc || ''} />
|
||||
<b>${tName(e.name) || t('效果')}</b><span class="efftip__kind">${t(KIND[e.iconKind] || '')}${e.counterText ? ` · ${bountyCounterText(e)}` : e.counter != null ? ` · ${e.counter}` : ''}</span>
|
||||
<${RichText} as="p" text=${effectDesc(e)} />
|
||||
</div>`}>
|
||||
<span class=${`effect effect--${e.iconKind || 'x'}`}>
|
||||
<${Img} src=${effectIconUrl(m, e)} fallback=${html`<${GIcon} name="bolt" />`} />
|
||||
|
||||
Reference in new issue
Block a user