role-select UX: tray timing delays, seat/circle state polish, 394 ITs green
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- _animationPending set before fetch (not in .then()) — blocks WS turn advance during in-flight request
- _placeCardDelay (3s) + _postTrayDelay (3s) give gamer time to see each step; both zeroed by _testReset()
- .role-confirmed class: full-opacity chair after placeCard completes; server-rendered on reload
- Slot circles disappear in join order (slot 1 first) via count-based logic, not role-label matching
- data-active-slot on card-stack; handleTurnChanged writes it for selectRole() to read
- #id_tray_wrap not rendered during gate phase ({% if room.table_status %})
- Tray slide/arc-in slowed to 1s for diagnostics; wobble kept at 0.45s
- Obsolete test_roles_revealed_simultaneously FT removed; T8 tray FT uses ROLE_SELECT room
- Jasmine macrotask flush pattern: await new Promise(r => setTimeout(r, 0)) after fetch .then()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,43 +44,6 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="gate-slots row">
|
||||
{% for slot in slots %}
|
||||
<div
|
||||
class="gate-slot{% if slot.status == 'EMPTY' %} empty{% elif slot.status == 'FILLED' %} filled{% elif slot.status == 'RESERVED' %} reserved{% endif %}"
|
||||
data-slot="{{ slot.slot_number }}"
|
||||
>
|
||||
<span class="slot-number">{{ slot.slot_number }}</span>
|
||||
{% if slot.gamer %}
|
||||
<span class="slot-gamer">{{ slot.gamer.email }}</span>
|
||||
{% else %}
|
||||
<span class="slot-gamer">empty</span>
|
||||
{% endif %}
|
||||
{% if slot.status == 'RESERVED' and slot.gamer == request.user %}
|
||||
<form method="POST" action="{% url 'epic:confirm_token' room.id %}">
|
||||
{% csrf_token %}
|
||||
{% if is_last_slot %}
|
||||
<button type="submit" class="btn btn-primary btn-xl">PICK ROLES</button>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn-confirm">OK</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% elif carte_active and slot.status == 'EMPTY' and slot.slot_number == carte_next_slot_number %}
|
||||
<form method="POST" action="{% url 'epic:confirm_token' room.id %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="slot_number" value="{{ slot.slot_number }}">
|
||||
<button type="submit" class="drop-token-btn btn btn-confirm" aria-label="Fill slot {{ slot.slot_number }}">OK</button>
|
||||
</form>
|
||||
{% elif carte_active and slot.status == 'FILLED' and slot.slot_number == carte_nvm_slot_number %}
|
||||
<form method="POST" action="{% url 'epic:release_slot' room.id %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="slot_number" value="{{ slot.slot_number }}">
|
||||
<button type="submit" class="slot-release-btn btn btn-cancel">NVM</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if room.gate_status == 'OPEN' %}
|
||||
<form method="POST" action="{% url 'epic:pick_roles' room.id %}" style="display:contents">
|
||||
{% csrf_token %}
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
{% for pos in gate_positions %}
|
||||
<div class="table-position" data-slot="{{ pos.slot.slot_number }}" data-role-label="{{ pos.role_label }}">
|
||||
<div class="position-body">
|
||||
<i class="fa-solid fa-chair"></i>
|
||||
<span class="position-role-label">{{ pos.role_label }}</span>
|
||||
<div class="token-tooltip">
|
||||
<h4>{% if pos.slot.gamer %}@{{ pos.slot.gamer.username|default:pos.slot.gamer.email }}{% else %}Empty Seat{% endif %}</h4>
|
||||
<div class="position-strip">
|
||||
{% for pos in gate_positions %}
|
||||
<div class="gate-slot{% if pos.slot.status == 'EMPTY' %} empty{% elif pos.slot.status == 'FILLED' %} filled{% elif pos.slot.status == 'RESERVED' %} reserved{% endif %}{% if pos.role_assigned %} role-assigned{% endif %}"
|
||||
data-slot="{{ pos.slot.slot_number }}">
|
||||
<span class="slot-number">{{ pos.slot.slot_number }}</span>
|
||||
<span class="slot-gamer">{% if pos.slot.gamer %}{{ pos.slot.gamer.email }}{% else %}empty{% endif %}</span>
|
||||
{% if pos.slot.status == 'RESERVED' and pos.slot.gamer == request.user %}
|
||||
<form method="POST" action="{% url 'epic:confirm_token' room.id %}">
|
||||
{% csrf_token %}
|
||||
{% if is_last_slot %}
|
||||
<button type="submit" class="btn btn-primary btn-xl">PICK ROLES</button>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn-confirm">OK</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% elif carte_active and pos.slot.status == 'EMPTY' and pos.slot.slot_number == carte_next_slot_number %}
|
||||
<form method="POST" action="{% url 'epic:confirm_token' room.id %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="slot_number" value="{{ pos.slot.slot_number }}">
|
||||
<button type="submit" class="drop-token-btn btn btn-confirm" aria-label="Fill slot {{ pos.slot.slot_number }}">OK</button>
|
||||
</form>
|
||||
{% elif carte_active and pos.slot.status == 'FILLED' and pos.slot.slot_number == carte_nvm_slot_number %}
|
||||
<form method="POST" action="{% url 'epic:release_slot' room.id %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="slot_number" value="{{ pos.slot.slot_number }}">
|
||||
<button type="submit" class="slot-release-btn btn btn-cancel">NVM</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<i class="position-status-icon fa-solid {% if pos.slot.gamer %}fa-circle-check{% else %}fa-ban{% endif %}"></i>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
{% if room.table_status == "ROLE_SELECT" and card_stack_state %}
|
||||
<div class="card-stack" data-state="{{ card_stack_state }}"
|
||||
data-starter-roles="{{ starter_roles|join:',' }}"
|
||||
data-user-slots="{{ user_slots|join:',' }}">
|
||||
data-user-slots="{{ user_slots|join:',' }}"
|
||||
data-active-slot="{{ active_slot }}">
|
||||
{% if card_stack_state == "ineligible" %}
|
||||
<i class="fa-solid fa-ban"></i>
|
||||
{% endif %}
|
||||
@@ -35,18 +36,19 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for slot in room.gate_slots.all %}
|
||||
<div class="table-seat{% if slot.slot_number == active_slot %} active{% endif %}"
|
||||
data-slot="{{ slot.slot_number }}">
|
||||
<div class="seat-portrait">{{ slot.slot_number }}</div>
|
||||
<div class="seat-card-arc"></div>
|
||||
<span class="seat-label">
|
||||
{% if slot.gamer %}@{{ slot.gamer.username|default:slot.gamer.email }}{% endif %}
|
||||
</span>
|
||||
{% for pos in gate_positions %}
|
||||
<div class="table-seat{% if pos.role_label in starter_roles %} role-confirmed{% endif %}"
|
||||
data-slot="{{ pos.slot.slot_number }}" data-role="{{ pos.role_label }}">
|
||||
<i class="fa-solid fa-chair"></i>
|
||||
<span class="seat-role-label">{{ pos.role_label }}</span>
|
||||
{% if pos.role_label in starter_roles %}
|
||||
<i class="position-status-icon fa-solid fa-circle-check"></i>
|
||||
{% else %}
|
||||
<i class="position-status-icon fa-solid fa-ban"></i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% include "apps/gameboard/_partials/_table_positions.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -74,10 +76,14 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if room.gate_status != "RENEWAL_DUE" and room.table_status != "SIG_SELECT" %}
|
||||
{% include "apps/gameboard/_partials/_table_positions.html" %}
|
||||
{% endif %}
|
||||
{% if not room.table_status and room.gate_status != "RENEWAL_DUE" %}
|
||||
{% include "apps/gameboard/_partials/_gatekeeper.html" %}
|
||||
{% endif %}
|
||||
<div id="id_tray_wrap">
|
||||
{% if room.table_status %}
|
||||
<div id="id_tray_wrap"{% if room.table_status == "ROLE_SELECT" %} class="role-select-phase"{% endif %}>
|
||||
<div id="id_tray_handle">
|
||||
<div id="id_tray_grip"></div>
|
||||
<button id="id_tray_btn" aria-label="Open seat tray">
|
||||
@@ -86,6 +92,7 @@
|
||||
</div>
|
||||
<div id="id_tray" style="display:none"><div id="id_tray_grid">{% for i in "12345678" %}<div class="tray-cell"></div>{% endfor %}</div></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% include "apps/gameboard/_partials/_room_gear.html" %}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
Reference in New Issue
Block a user