tray: Tray.placeSig analogue of placeCard for SIG SELECT exit; rename arc-in → fade-in — TDD
After all 3 gamers in a polarity room confirm TAKE SIG and the 12s countdown
expires, sig-select.js's room:polarity_room_done handler now plays the same
tray-open / fade-in / tray-close sequence the role-select uses, then
dismisses the sig overlay & shows the waiting msg ("Gravity settling…" /
"Levity appraising…") on Tray.placeSig's completion callback. Visual order:
sig stage → tray slides in → sig fades into the second tray cell → tray
slides out → table hex w. waiting msg. Cross-polarity events (other room
finishing while we're still in our overlay) are no-op as before.
- tray.js: new Tray.placeSig(sourceEl, onComplete). Mutates the SECOND
.tray-cell in place (sig slot), copies aria-label / data-energies /
data-operations / corner-rank + suit-icon markup from the source
.sig-stage-card, then runs the shared open → fade-in → close sequence.
Extracted _runFadeInSequence helper so placeCard + placeSig share the
same animation glue. reset() now also clears .tray-sig-card from cells.
- _tray.scss: .tray-sig-card.fade-in > .sig-stage-card animates via the
existing tray-role-fade-in keyframes.
- sig-select.js polarity_room_done handler: Tray.placeSig(stageCard,
_settle); _settle runs the existing _dismissSigOverlay + _showWaitingMsg.
Falls back to immediate dismiss when Tray is undefined (test environments
without the tray).
- arc-in → fade-in rename across tray.js, role-select.js, _tray.scss
(incl. @keyframes tray-role-arc-in → tray-role-fade-in), TraySpec.js
spec descriptions + assertions, & test_room_role_select.py docstrings.
The original "arc-in" name suggested a curved-path animation; the actual
behaviour is a 1s opacity fade, so fade-in is the accurate label.
- TraySpec: 10 new placeSig specs mirroring placeCard (second-cell mutation,
data + markup copy, tabIndex, fade-in class, animationend-triggered close,
onComplete callback, landscape parity, reset cleanup).
- SigSelectSpec: 3 new specs (Tray.placeSig called w. stageCard on own
polarity; not called on other polarity; overlay dismiss deferred to the
Tray.placeSig completion callback).
344 specs / 4 pending green; RoleSelectTrayTest FT still green.
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -809,4 +809,63 @@ describe("SigSelect", () => {
|
||||
expect(takeSigBtn.classList.contains("btn-cancel")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ── polarity_room_done → tray sequence ─────────────────────────────────── //
|
||||
//
|
||||
// After all 3 gamers in the user's polarity confirm TAKE SIG and the
|
||||
// 12s countdown expires, the server fires room:polarity_room_done. The
|
||||
// sig-select handler should: (1) play the tray sequence — Tray.placeSig
|
||||
// with the user's selected stage card; (2) on Tray.placeSig's completion
|
||||
// callback, dismiss the overlay and show the waiting message. Tray runs
|
||||
// FIRST, while the overlay is still up, so the slide is visually anchored
|
||||
// to the sig stage's exit.
|
||||
//
|
||||
// Cross-polarity events (the OTHER room finishing while we're still
|
||||
// selecting) must NOT trigger the sequence.
|
||||
|
||||
describe("polarity_room_done → tray sequence", () => {
|
||||
beforeEach(() => {
|
||||
// .table-center is appended to by _showWaitingMsg in the dismiss
|
||||
// path; provide one so dismissal doesn't error.
|
||||
const center = document.createElement("div");
|
||||
center.className = "table-center";
|
||||
document.body.appendChild(center);
|
||||
makeFixture({ polarity: "levity", userRole: "PC" });
|
||||
spyOn(Tray, "placeSig");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.querySelectorAll(".table-center, #id_hex_waiting_msg")
|
||||
.forEach((el) => el.remove());
|
||||
});
|
||||
|
||||
it("calls Tray.placeSig with the stage card when own polarity finishes", () => {
|
||||
window.dispatchEvent(new CustomEvent("room:polarity_room_done", {
|
||||
detail: { polarity: "levity" },
|
||||
}));
|
||||
expect(Tray.placeSig).toHaveBeenCalled();
|
||||
const arg = Tray.placeSig.calls.mostRecent().args[0];
|
||||
expect(arg).toBe(stageCard);
|
||||
});
|
||||
|
||||
it("does NOT call Tray.placeSig when the OTHER polarity finishes", () => {
|
||||
window.dispatchEvent(new CustomEvent("room:polarity_room_done", {
|
||||
detail: { polarity: "gravity" },
|
||||
}));
|
||||
expect(Tray.placeSig).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("dismisses the overlay only AFTER Tray.placeSig's callback fires", () => {
|
||||
window.dispatchEvent(new CustomEvent("room:polarity_room_done", {
|
||||
detail: { polarity: "levity" },
|
||||
}));
|
||||
// Overlay still mounted — dismissal deferred to tray callback.
|
||||
expect(document.querySelector(".sig-overlay")).not.toBe(null);
|
||||
|
||||
const cb = Tray.placeSig.calls.mostRecent().args[1];
|
||||
cb();
|
||||
expect(document.querySelector(".sig-overlay")).toBe(null);
|
||||
expect(document.getElementById("id_hex_waiting_msg")).not.toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user