room gate-view: mid-game renewal area (room_gate) + renew_token endpoint + _room_gear nvm_url — TDD
Phase 4 of the room GATE VIEW + seat-renewal sprint. The 3rd-person
mirror of my_sea_gate: a gate-view a seated gamer can open at any time
to check token TIME REMAINING or RENEW, reachable even mid-game (the
gatekeeper redirects to the table once table_status is set — this view
does not).
- `room_gate` view + `room/<uuid>/gate/view/` URL — renders the viewer's
own seat/position circle, a live time-remaining ticker (counts down to
cost_current_until, then to grace_expires_at in renewal grace), and a
RENEW affordance. page_class carries `page-room` (drives the navbar
GATE VIEW in Phase 0). No seat → "no seat" copy, no RENEW btn.
- `renew_token` view + `room/<uuid>/gate/renew` URL — re-deposits a token
into the viewer's already-FILLED slot via the existing `debit_token`
(resets filled_at=now → restarts the cost-current window). Reuses
select_token / debit_token wholesale; distinct from confirm_token,
which needs a RESERVED slot. 402 when token-depleted; no-op redirect
when the user holds no filled slot (already auto-BYE'd).
- `room_gate.html` — reuses the gatekeeper's .gate-overlay/.gate-modal
chrome (hand-rolled like my_sea_gate, inner content differs) + an
inline countdown ticker mirroring the status-dots IIFE.
- DRY: `_room_gear.html` now takes an `nvm_url` param (default the
gameboard listing — room.html's own gear unchanged); the gate-view
passes the table-hex URL so NVM returns to the hex, mirroring
_my_sea_gear's contract.
Tests: RoomGateViewTest (7) + RoomRenewTokenTest (6) — renders mid-game,
own seat circle, data-cost-until, RENEW posts to renew_token, NVM→hex,
page-room marker, no-seat render; renew resets filled_at + consumes FREE
+ records SLOT_FILLED, no-slot/GET redirects, 402 when depleted. 504
epic tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:55:17 -04:00
|
|
|
{# `nvm_url` lets a caller redirect NVM elsewhere (the room gate-view passes #}
|
|
|
|
|
{# the table-hex URL so NVM returns to the hex, not out to /gameboard/). #}
|
|
|
|
|
{# Defaults to the gameboard listing — room.html's own gear menu is unchanged.#}
|
|
|
|
|
{% if not nvm_url %}{% url 'gameboard' as nvm_url %}{% endif %}
|
2026-03-14 00:10:40 -04:00
|
|
|
<div id="id_room_menu" style="display:none">
|
room gate-view: mid-game renewal area (room_gate) + renew_token endpoint + _room_gear nvm_url — TDD
Phase 4 of the room GATE VIEW + seat-renewal sprint. The 3rd-person
mirror of my_sea_gate: a gate-view a seated gamer can open at any time
to check token TIME REMAINING or RENEW, reachable even mid-game (the
gatekeeper redirects to the table once table_status is set — this view
does not).
- `room_gate` view + `room/<uuid>/gate/view/` URL — renders the viewer's
own seat/position circle, a live time-remaining ticker (counts down to
cost_current_until, then to grace_expires_at in renewal grace), and a
RENEW affordance. page_class carries `page-room` (drives the navbar
GATE VIEW in Phase 0). No seat → "no seat" copy, no RENEW btn.
- `renew_token` view + `room/<uuid>/gate/renew` URL — re-deposits a token
into the viewer's already-FILLED slot via the existing `debit_token`
(resets filled_at=now → restarts the cost-current window). Reuses
select_token / debit_token wholesale; distinct from confirm_token,
which needs a RESERVED slot. 402 when token-depleted; no-op redirect
when the user holds no filled slot (already auto-BYE'd).
- `room_gate.html` — reuses the gatekeeper's .gate-overlay/.gate-modal
chrome (hand-rolled like my_sea_gate, inner content differs) + an
inline countdown ticker mirroring the status-dots IIFE.
- DRY: `_room_gear.html` now takes an `nvm_url` param (default the
gameboard listing — room.html's own gear unchanged); the gate-view
passes the table-hex URL so NVM returns to the hex, mirroring
_my_sea_gear's contract.
Tests: RoomGateViewTest (7) + RoomRenewTokenTest (6) — renders mid-game,
own seat circle, data-cost-until, RENEW posts to renew_token, NVM→hex,
page-room marker, no-seat render; renew resets filled_at + consumes FREE
+ records SLOT_FILLED, no-slot/GET redirects, 402 when depleted. 504
epic tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:55:17 -04:00
|
|
|
<a href="{{ nvm_url }}" class="btn btn-cancel">NVM</a>
|
2026-03-14 00:10:40 -04:00
|
|
|
{% if request.user == room.owner %}
|
|
|
|
|
<form method="POST" action="{% url 'epic:delete_room' room.id %}">
|
|
|
|
|
{% csrf_token %}
|
2026-03-23 19:31:57 -04:00
|
|
|
<button type="submit" class="btn btn-danger" data-confirm="Delete this room?">DEL</button>
|
2026-03-14 00:10:40 -04:00
|
|
|
</form>
|
|
|
|
|
{% else %}
|
|
|
|
|
<form method="POST" action="{% url 'epic:abandon_room' room.id %}">
|
|
|
|
|
{% csrf_token %}
|
2026-03-23 19:31:57 -04:00
|
|
|
<button type="submit" class="btn btn-abandon" data-confirm="Leave this room?">BYE</button>
|
2026-03-14 00:10:40 -04:00
|
|
|
</form>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
2026-03-14 13:28:31 -04:00
|
|
|
{% include "apps/applets/_partials/_gear.html" with menu_id="id_room_menu" %}
|
|
|
|
|
|