feedback1 draft-info: the strategy draft shows the briefing's disabled bonds and banned operators again (GitHub issue #8 item 1)
One component, public/js/ui/matchInfo.js: matchInfoModel (the drawn set D and the mode's inactive bonds via disabledBondSets, the briefing's bond order, banned operators by tier, bannedPerBond) and the briefing's bond rows, legend and banned-operator grid. The briefing renders it; the band draft opens it read-only in a dialog (查看禁用盟约与干员 under the order list; 关闭, a tap outside or Esc close it; its footer repeats the turn and the countdown; a turn change closes it, the end of the draft unmounts it); the in-game 本局信息 tab reads the same model, so its banned operators are listed by tier too. In the dialog every size has a px floor, so phones keep readable text and a scrollable body. Tests: test/ui/match-info.test.js; opt-in test/ui/match-info.e2e.test.js (SP_E2E=1: solo 标准 on desktop, co-op 绝境 with a desktop and a phone).
This commit is contained in:
1 parent
842e1e13c4
commit
7188e0af89
8 files changed
+847
-56
No files matched your search
@@ -1,44 +1,22 @@
|
||||
// Briefing — INFO_CHECK "1/2 确认本局信息" (research 06 §4.1, D1): enemy leader (silhouette, name,
|
||||
// abilities), stage (+ its pool: 战场固定 / 战场随机(共N张)), 特训敌人 factions (icon, name, description), 核心盟约 / 附加盟约 rows of bond discs
|
||||
// (disabled bonds greyed with the banned-member badge), 本局禁用干员 avatars, difficulty tag, the ready
|
||||
// count x/N with person pips, the 准备就绪 button (g.infoReady) and the countdown.
|
||||
// abilities), stage (+ its pool: 战场固定 / 战场随机(共N张)), 特训敌人 factions (icon, name, description), the difficulty
|
||||
// tag, the ready count x/N with person pips, the 准备就绪 button (g.infoReady) and the countdown. The right column — 核心盟约
|
||||
// / 附加盟约 rows of bond discs (disabled bonds greyed with the banned-member badge), the legend and the 本局禁用干员
|
||||
// avatars — is ui/matchInfo.js MatchInfo, the same blocks the strategy draft's 本局信息 dialog shows (screens/bandDraft.js).
|
||||
|
||||
import { useState } from '../../vendor/hooks.module.js';
|
||||
import { html, Button, Icon, MicroLabel, BondDisc, Tooltip } from '../ui/components.js';
|
||||
import { useGameData, Img, UnitThumb, RichText } from '../ui/gameComponents.js';
|
||||
import { html, Button, Icon, MicroLabel } from '../ui/components.js';
|
||||
import { useGameData, Img, RichText } from '../ui/gameComponents.js';
|
||||
import { StepHeader, ExitModal } from '../ui/matchChrome.js';
|
||||
import { MatchInfo, matchInfoModel } from '../ui/matchInfo.js';
|
||||
import { LoadoutButton } from './loadout.js';
|
||||
import { actions } from '../ui/gameActions.js';
|
||||
import { factionTypes, bannedPerBond, sortedPlayers, phaseTotalSeconds, disabledBondSets, briefingBondTip } from '../ui/gameLogic.js';
|
||||
import { bondIconUrl, enemyIconUrl, factionIconUrl } from '../ui/assetUrls.js';
|
||||
import { factionTypes, sortedPlayers, phaseTotalSeconds } from '../ui/gameLogic.js';
|
||||
import { enemyIconUrl, factionIconUrl } from '../ui/assetUrls.js';
|
||||
import { useStore } from '../store.js';
|
||||
import { data } from '../data.js';
|
||||
|
||||
const cx = (...p) => p.flat().filter(Boolean).join(' ');
|
||||
|
||||
function BondRow({ title, micro, bonds, sets, perBond }) {
|
||||
const m = data.get('assets');
|
||||
return html`<div class="brief-bonds">
|
||||
<h3 class="brief-h"><span>${title}</span><${MicroLabel}>${micro}</${MicroLabel}></h3>
|
||||
<div class="brief-bonds__row">
|
||||
${bonds.map((b) => {
|
||||
// greyed: the drawn set D (still activatable, roster incomplete) and the mode's static inactive bonds
|
||||
const state = sets.off.has(b.bondId) ? 'off' : sets.drawn.has(b.bondId) ? 'drawn' : null;
|
||||
const off = !!state;
|
||||
const bannedN = perBond.get(b.bondId) || 0;
|
||||
const tip = briefingBondTip(b.name, state, bannedN);
|
||||
return html`<${Tooltip} key=${b.bondId} text=${tip}>
|
||||
<div class=${cx('brief-bond', off && 'is-off', state === 'drawn' && 'is-incomplete', !off && bannedN > 0 && 'is-partial')}>
|
||||
<${BondDisc} name=${b.name} icon=${bondIconUrl(m, b.bondId)} active=${!off} disabled=${off} tier=${off ? 0 : (b.thresholds?.length || 1)}
|
||||
maxTier=${Math.max(1, b.thresholds?.length || 1)} size="md" />
|
||||
${bannedN > 0 ? html`<span class="brief-bond__ban num"><${Icon} name="user" />${bannedN}</span>` : null}
|
||||
</div>
|
||||
<//>`;
|
||||
})}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/** INFO_CHECK screen. */
|
||||
export function BriefingScreen() {
|
||||
const pub = useStore((s) => s.match.public);
|
||||
@@ -53,13 +31,7 @@ export function BriefingScreen() {
|
||||
const me = players.find((p) => p.playerId === myId);
|
||||
const readyN = players.filter((p) => p.ready).length;
|
||||
const mode = gd.config?.modes?.[pub.modeId];
|
||||
const sets = disabledBondSets(pub, mode?.inactiveBondIds);
|
||||
const bonds = gd.list('bonds').sort((a, b) => (a.bondOrder ?? 0) - (b.bondOrder ?? 0) || (a.identifier ?? 0) - (b.identifier ?? 0));
|
||||
const core = bonds.filter((b) => b.isCore);
|
||||
const addon = bonds.filter((b) => !b.isCore);
|
||||
const banned = (Array.isArray(pub.bannedChess) ? pub.bannedChess : []).filter((id) => gd.chess(id));
|
||||
banned.sort((a, b) => (gd.chess(a)?.tier ?? 0) - (gd.chess(b)?.tier ?? 0));
|
||||
const perBond = bannedPerBond(bonds, banned);
|
||||
const info = matchInfoModel(pub, { bonds: gd.list('bonds'), chess: gd.chess, mode });
|
||||
const boss = pub.bossId ? gd.boss(pub.bossId) : null;
|
||||
const bossEnemy = boss ? gd.enemy(boss.enemyKey) : null;
|
||||
const stage = pub.stageId ? gd.stage(pub.stageId) : null;
|
||||
@@ -111,15 +83,7 @@ export function BriefingScreen() {
|
||||
</div>
|
||||
</section>
|
||||
<section class="brief__right">
|
||||
<${BondRow} title="核心盟约" micro="CORE BONDS" bonds=${core} sets=${sets} perBond=${perBond} />
|
||||
<${BondRow} title="附加盟约" micro="ADD-ON BONDS" bonds=${addon} sets=${sets} perBond=${perBond} />
|
||||
<p class="brief-legend"><span class="brief-legend__off"></span>灰色:部分盟约所含干员阵容不完整(仍可通过其他盟约的干员或装备激活)${sets.off.size ? ',或本模式禁用' : ''} · <span class="brief-legend__ban"><${Icon} name="user" /></span>该盟约中无法出现的干员数</p>
|
||||
<div class="brief-banned">
|
||||
<h3 class="brief-h"><span>本局禁用干员</span><${MicroLabel}>BANNED OPERATORS</${MicroLabel}><b class="num brief-banned__n">${banned.length}</b></h3>
|
||||
${banned.length ? html`<div class="brief-banned__grid">
|
||||
${banned.map((id) => html`<${UnitThumb} key=${id} kind="chess" id=${id} size="sm" dim=${true} />`)}
|
||||
</div>` : html`<p class="t-dim">本局没有禁用干员</p>`}
|
||||
</div>
|
||||
<${MatchInfo} model=${info} />
|
||||
</section>
|
||||
</main>
|
||||
<footer class="brief__foot">
|
||||
|
||||
Reference in new issue
Block a user