PICK SEA Sprint A: async sky→sea transition via WS room:sky_confirmed — TDD
- natus_save: group_send room:sky_confirmed after confirm (carries seat_role) - consumer: sky_confirmed handler rebroadcasts to room group - _notify_sky_confirmed() helper mirrors _notify_pick_sky_available - sea_partial view: renders _sea_overlay.html partial for in-page injection (403 if not sky_confirmed) - epic:sea_partial URL registered - _natus_overlay.html: data-user-seat-role attr; _onSkyConfirmed() fetches sea partial, removes natus overlay + backdrop, injects sea HTML, toggles sea-open on html root; room:sky_confirmed WS listener calls _onSkyConfirmed only for matching seat role - user_seat_role added to SKY_SELECT context - FT: PickSeaAsyncTransitionTest (3 tests, ChannelsFunctionalTest) — sea overlay, natus gone, sea-open class — all green Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,9 @@
|
||||
<div class="natus-overlay"
|
||||
id="id_natus_overlay"
|
||||
data-preview-url="{% url 'epic:natus_preview' room.id %}"
|
||||
data-save-url="{% url 'epic:natus_save' room.id %}">
|
||||
data-save-url="{% url 'epic:natus_save' room.id %}"
|
||||
data-sea-partial-url="{% url 'epic:sea_partial' room.id %}"
|
||||
data-user-seat-role="{{ user_seat_role }}">
|
||||
|
||||
<div class="natus-modal-wrap">
|
||||
<div class="natus-modal">
|
||||
@@ -369,9 +371,11 @@
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
return r.json();
|
||||
})
|
||||
.then(() => {
|
||||
setStatus('Sky saved!');
|
||||
setTimeout(closeNatus, 1200);
|
||||
.then(data => {
|
||||
if (!data.confirmed) {
|
||||
setStatus('Sky saved!');
|
||||
}
|
||||
// Confirmed state is driven by the room:sky_confirmed WS event
|
||||
})
|
||||
.catch(err => {
|
||||
setStatus(`Save failed: ${err.message}`, 'error');
|
||||
@@ -379,6 +383,28 @@
|
||||
});
|
||||
});
|
||||
|
||||
// ── Sky confirmed → inject sea partial ───────────────────────────────────
|
||||
|
||||
const SEA_PARTIAL_URL = overlay.dataset.seaPartialUrl;
|
||||
|
||||
function _onSkyConfirmed() {
|
||||
fetch(SEA_PARTIAL_URL, { credentials: 'same-origin' })
|
||||
.then(r => r.text())
|
||||
.then(html => {
|
||||
// Remove natus overlay + backdrop; inject sea partial before body close
|
||||
var backdrop = document.querySelector('.natus-backdrop');
|
||||
if (backdrop) backdrop.remove();
|
||||
overlay.remove();
|
||||
document.documentElement.classList.remove('natus-open');
|
||||
document.body.insertAdjacentHTML('beforeend', html);
|
||||
document.documentElement.classList.add('sea-open');
|
||||
})
|
||||
.catch(() => {
|
||||
// Fallback: just close natus and let page refresh handle the transition
|
||||
closeNatus();
|
||||
});
|
||||
}
|
||||
|
||||
// ── CSRF ──────────────────────────────────────────────────────────────────
|
||||
|
||||
function _getCsrf() {
|
||||
@@ -391,6 +417,15 @@
|
||||
// openNatus() so the animation plays when the modal opens, not silently
|
||||
// in the background on page load.
|
||||
|
||||
// WS: server broadcasts sky_confirmed when any gamer confirms their sky.
|
||||
// Only act when the event's seat_role matches this browser's seat.
|
||||
const MY_SEAT_ROLE = overlay.dataset.userSeatRole;
|
||||
|
||||
window.addEventListener('room:sky_confirmed', function (e) {
|
||||
if (MY_SEAT_ROLE && e.detail.seat_role && e.detail.seat_role !== MY_SEAT_ROLE) return;
|
||||
_onSkyConfirmed();
|
||||
});
|
||||
|
||||
_restoreForm();
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user