my-sea: seated chairs settle to --secUser; owner sees all seated members; gear menu column; visit hex scales — TDD

Four my-sea / my_sea_visit fixes from user feedback.

1. Seated-chair snap-back: `.my-sea-landing .table-seat.seated .fa-chair`
   forced PERMANENT --terUser + --ninUser glow, out-specifying _room.scss's
   --secUser settle — so a seated chair eased in (the .seat-just-seated flare)
   then SNAPPED back to the glow. Removed it; the steady look is now the
   _room.scss --secUser as spec'd. The viewer's --self marker moves off the
   chair onto the position label so the chair can rest at --secUser.

2. Owner multi-seat: my_sea.html's landing rendered a hardcoded 1C-only seat
   loop, so the owner only ever saw herself even after refresh. It now renders
   the shared `_my_sea_seats(request.user)` ring — owner 1C + present visitors
   2C-6C — the same list the spectator + broadcasts use. (Live owner-side push
   is a follow-on; this fixes the on-refresh case.)

3. Gear sea menu: NVM + BYE laid out in a ROW because the BYE form is
   display:contents + applets.js force-sets the menu to display:block on open
   (can't flex the menu itself). Wrap them in the shared `.menu-btns` flex
   container and override it to a COLUMN in portrait / ROW in landscape (DRY —
   same container the room/applet menus use).

4. Visit hex scale: my_sea_visit didn't load room.js, so scaleTable() never ran
   and the table-hex rendered unscaled (unlike the owner's my_sea). Load room.js
   on the visit page too.

62 gameboard ITs (gear NVM + owner-seat + visit) green.

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-30 00:04:04 -04:00
parent 0693a422d2
commit 877e0f544a
7 changed files with 72 additions and 42 deletions

View File

@@ -39,18 +39,23 @@ window.mySeaGuardedNav = window.mySeaGuardedNav || function (e, url) {
};
</script>
<div id="id_my_sea_menu" style="display:none">
<button type="button" class="btn btn-cancel" onclick="mySeaGuardedNav(event, '{{ nvm_url }}')">NVM</button>
{# Spectator-only BYE (Phase B) — drops presence (status=LEFT, frees seat #}
{# 2C, kills voice). Rendered below NVM only when the caller passes a #}
{# `leave_url`; the owner's pages never do, so their menu is unchanged. #}
{% if leave_url %}
<form method="POST" action="{{ leave_url }}" style="display:contents">
{% csrf_token %}
{# BYE is an explicit leave — forget the room so the destination page #}
{# (and any return to my_sea) doesn't auto-rejoin the dropped call. #}
<button type="submit" id="id_my_sea_bye_btn" class="btn btn-abandon"
onclick="if(window.mySeaVoiceForget)window.mySeaVoiceForget()">BYE</button>
</form>
{% endif %}
{# `.menu-btns` is the flex container the shared %applet-menu styles — #}
{# column in portrait / row in landscape (the menu itself can't be flexed #}
{# since applets.js force-sets display:block on open). #}
<div class="menu-btns">
<button type="button" class="btn btn-cancel" onclick="mySeaGuardedNav(event, '{{ nvm_url }}')">NVM</button>
{# Spectator-only BYE (Phase B) — drops presence (status=LEFT, frees seat #}
{# 2C, kills voice). Rendered below NVM only when the caller passes a #}
{# `leave_url`; the owner's pages never do, so their menu is unchanged. #}
{% if leave_url %}
<form method="POST" action="{{ leave_url }}" style="display:contents">
{% csrf_token %}
{# BYE is an explicit leave — forget the room so the destination page #}
{# (and any return to my_sea) doesn't auto-rejoin the dropped call. #}
<button type="submit" id="id_my_sea_bye_btn" class="btn btn-abandon"
onclick="if(window.mySeaVoiceForget)window.mySeaVoiceForget()">BYE</button>
</form>
{% endif %}
</div>
</div>
{% include "apps/applets/_partials/_gear.html" with menu_id="id_my_sea_menu" %}

View File

@@ -86,19 +86,26 @@
</div>
</div>
</div>
{% for n in "123456" %}
{# Chair-position labels (1C-6C). No roles in #}
{# my-sea (this is the solo draw flow); using #}
{# `.seat-position-label` instead of the room's #}
{# `.seat-role-label` to keep the no-role #}
{# semantics clean. `.position-status-icon` + #}
{# `.fa-ban` are unchanged — already role- #}
{# agnostic in _room.scss. #}
<div class="table-seat{% if n == '1' and seat1_seated %} seated{% endif %}" data-slot="{{ n }}"{% if n == '1' and seat1_seated %} data-seat-token="owner-{{ request.user.id }}-{{ active_draw.id }}"{% endif %}>
<i class="fa-solid fa-chair"></i>
<span class="seat-position-label">{{ n }}C</span>
<i class="position-status-icon fa-solid {% if n == '1' and seat1_seated %}fa-circle-check{% else %}fa-ban{% endif %}"></i>
</div>
{# Owner 1C + present visitors 2C-6C — the shared #}
{# `_my_sea_seats` ring, so the owner sees who's #}
{# seated at her table, not just herself. The FREE #}
{# DRAW client-side transition still targets #}
{# `.table-seat[data-slot="1"]`. `.position-status- #}
{# icon` / `.fa-ban` are role-agnostic in _room.scss. #}
{% for seat in seats %}
{% if seat.present %}
<div class="table-seat seated" data-slot="{{ seat.n }}" data-seat-token="{{ seat.token }}">
<i class="fa-solid fa-chair"></i>
<span class="seat-position-label">{{ seat.label }}</span>
<i class="position-status-icon fa-solid fa-circle-check"></i>
</div>
{% else %}
<div class="table-seat" data-slot="{{ seat.n }}">
<i class="fa-solid fa-chair"></i>
<span class="seat-position-label">{{ seat.label }}</span>
<i class="position-status-icon fa-solid fa-ban"></i>
</div>
{% endif %}
{% endfor %}
</div>
</div>

View File

@@ -81,6 +81,10 @@
{% endblock content %}
{% block scripts %}
{# room.js's scaleTable() fits the table-hex scene to the aperture — #}
{# same as the owner's my_sea (which loads it too); without it the visit #}
{# hex renders unscaled. #}
<script src="{% static 'apps/epic/room.js' %}"></script>
<script src="{% static 'apps/gameboard/my-sea-seats.js' %}"></script>
<script src="{% static 'apps/epic/burger-btn.js' %}"></script>
{# Voice-affordance glow/pulse machine — keys on the voice sub-btn's #}