feedback7 R22-VOICES: review fixes — a 选中 tap no longer restarts the battle-voice gap, and the second shop / reward card of one operator says its 选中 line too; the package switch's comment quotes the measured JP size; golden: unchanged
1. VoiceGate.start no longer moves lastAt for VOICE_TAP_SLOTS: a tap still skips the 1.2 s gap but starts none, so a 部署 / 技能 / 接敌 the battle asks for once after a short 选中 line has ended plays where the last battle line's gap ends (a 部署 at 0, a tap at 500: a 作战中 at 1300 was dropped, now plays; inside the 部署 gap it still waits). 2. Shop / reward cards hand only the chess id to the detail, so two cards of one operator (the pool deals duplicates) had one 选中 key and the second tap said nothing nor replaced the first line: game.js numbers every card it opens (`tap`, cardTap), resolveDetail keeps it, and detailPanel's new selectVoiceKey() includes it (a re-render of the same tap keeps its key; pieces / units unchanged). Checked in the mock match: the second card of 歌蕾蒂娅 now calls voice() (it made no call on the parent). 3. tools/package.mjs FULL_ZIP_JP_VOICE comment: 89,388,041 bytes = 85.2 MiB on disk, about 76 MB zipped (as ASSETS / DEPLOY), not "~93 MB, barely compresses". Tests: test/ui/audio.test.js (the tap-gap case; one earlier assertion that encoded the old gap after a tap replaced), test/feedback7-voices.test.js (new: the card tap in resolveDetail / selectVoiceKey / game.js) — both fail on the parent. §21.30's 0.2.2 note updated.
This commit is contained in:
1 parent
ddf8c39ed0
commit
bcee737f40
7 files changed
+79
-11
No files matched your search
@@ -137,3 +137,40 @@ test('package: the full zip ships the JP dub by default; FULL_ZIP_JP_VOICE off h
|
||||
const src = fs.readFileSync(path.join(ROOT, 'tools/package.mjs'), 'utf8');
|
||||
assert.match(src, /removable: \(rel\) => !removalProblem\(rel\) && !heldBack\.has\(rel\)/);
|
||||
});
|
||||
|
||||
test('选中干员 on every card tap (review of fb7-voices): two shop / reward cards of one operator are two taps, a re-render is none', async () => {
|
||||
// shop / reward cards hand only the chess id to the detail target (no piece, no unit): game.js numbers every card it opens
|
||||
// (`tap`), resolveDetail keeps it, and the panel's 选中 key (selectVoiceKey) includes it — the second 斯卡蒂 card spoke
|
||||
// nothing before, nor replaced the first card's line (the pool deals duplicates)
|
||||
const origFetch = globalThis.fetch;
|
||||
globalThis.fetch = async (url) => {
|
||||
const name = String(url).split('/').pop();
|
||||
let body;
|
||||
try { body = readJson(`data/${name}`); } catch { return { ok: false, status: 404, json: async () => ({}) }; }
|
||||
return { ok: true, status: 200, json: async () => body };
|
||||
};
|
||||
try {
|
||||
const { resolveDetail, selectVoiceKey } = await import('../public/js/ui/detailPanel.js');
|
||||
const { data } = await import('../public/js/data.js');
|
||||
await data.loadAll('chess', 'backups');
|
||||
const id = Object.values(readJson('data/chess.json')).find((c) => c.charId === 'char_263_skadi' && !c.isGolden).chessId;
|
||||
const card = (tap) => resolveDetail({ kind: 'chess', id, hint: null, tap }, new Map(), { priv: null });
|
||||
const a = card(1), b = card(2);
|
||||
assert.equal(a.chess.charId, 'char_263_skadi');
|
||||
assert.deepEqual([a.tap, b.tap], [1, 2], 'the tap rides along');
|
||||
assert.notEqual(selectVoiceKey(a), selectVoiceKey(b), 'the second card of the same operator is a new opening');
|
||||
assert.equal(selectVoiceKey(card(1)), selectVoiceKey(a), 'the same tap resolved again (a re-render) says nothing more');
|
||||
assert.equal(resolveDetail({ kind: 'chess', id }, new Map(), { priv: null }).tap, undefined, 'no tap, no field');
|
||||
// pieces and battle units keep their own identity; a non-operator card has no key
|
||||
assert.equal(selectVoiceKey({ type: 'chess', chess: { chessId: 'x' }, piece: { uid: 4 } }), 'x:4:');
|
||||
assert.equal(selectVoiceKey({ type: 'chess', chess: { chessId: 'x' }, unitId: 9 }), 'x:9:');
|
||||
assert.equal(selectVoiceKey({ type: 'item' }), null);
|
||||
assert.equal(selectVoiceKey(null), null);
|
||||
// the panel keys its 选中 effect on it, and the game screen numbers every operator card it opens
|
||||
assert.match(fs.readFileSync(path.join(ROOT, 'public/js/ui/detailPanel.js'), 'utf8'), /const selectKey = voice && detail\?\.type === 'chess' \? selectVoiceKey\(detail\) : null;/);
|
||||
const game = fs.readFileSync(path.join(ROOT, 'public/js/screens/game.js'), 'utf8');
|
||||
assert.match(game, /onDetail=\$\{\(id, kind, hint\) => setDetail\(\{ kind: kind === 'item' \? 'item' : 'chess', id, hint: hint \|\| null, tap: \+\+cardTap\.current \}\)\}/);
|
||||
} finally {
|
||||
globalThis.fetch = origFetch;
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user