wired PICK SKY server-side polarity countdown via threading.Timer (tasks.py); fixed polarity_done overlay gating on refresh; cleared sig-select floats on overlay dismiss; filtered Redact events from Most Recent applet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-04-13 00:34:05 -04:00
parent df421fb6c0
commit 32d8d97360
22 changed files with 1028 additions and 88 deletions

View File

@@ -10,9 +10,9 @@
<a href="{% url 'billboard:scroll' recent_room.id %}" class="most-recent-load-more">Load more….</a>
{% for event in recent_events %}
<div class="drama-event {% if event.actor == viewer %}mine{% else %}theirs{% endif %}">
<span class="drama-event-body">
<span class="drama-event-body{% if event.struck %} struck{% endif %}">
<strong>{{ event.actor|display_name }}</strong>
{{ event.to_prose }}
{{ event.to_prose|safe }}
</span>
<time class="drama-event-time" datetime="{{ event.timestamp|date:'c' }}">
{{ event.timestamp|relative_ts }}

View File

@@ -6,6 +6,76 @@
{% block content %}
{% csrf_token %}
<div class="billscroll-page">
{% include "apps/applets/_partials/_gear.html" with menu_id="id_billscroll_menu" %}
<div id="id_billscroll_menu" style="display:none;">
<form id="id_scroll_filter_form">
<label><input type="checkbox" name="labels" value="frame" checked> Frame</label>
<label><input type="checkbox" name="labels" value="redact" checked> Redact</label>
<div class="menu-btns">
<button type="submit" class="btn btn-confirm">OK</button>
<button type="button" class="btn btn-cancel applet-menu-cancel">NVM</button>
</div>
</form>
</div>
{% include "apps/billboard/_partials/_applet-billboard-scroll.html" %}
</div>
<script>
(function () {
var STORAGE_KEY = 'billscroll-labels-{{ room.id }}';
var ALL_LABELS = ['frame', 'redact'];
function applyFilter(checked) {
document.querySelectorAll(
'#id_drama_scroll .drama-event[data-label]'
).forEach(function (el) {
el.style.display = checked.indexOf(el.dataset.label) !== -1 ? '' : 'none';
});
}
function saveFilter(checked) {
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(checked)); } catch (_) {}
}
function loadFilter() {
try {
var raw = localStorage.getItem(STORAGE_KEY);
return raw ? JSON.parse(raw) : null;
} catch (_) { return null; }
}
function syncCheckboxes(checked) {
var form = document.getElementById('id_scroll_filter_form');
if (!form) return;
form.querySelectorAll('input[name="labels"]').forEach(function (cb) {
cb.checked = checked.indexOf(cb.value) !== -1;
});
}
// Restore saved filter on page load
var saved = loadFilter();
if (saved) {
applyFilter(saved);
syncCheckboxes(saved);
}
// Apply + save on OK
var form = document.getElementById('id_scroll_filter_form');
if (!form) return;
form.addEventListener('submit', function (e) {
e.preventDefault();
var checked = Array.from(
form.querySelectorAll('input[name="labels"]:checked')
).map(function (cb) { return cb.value; });
applyFilter(checked);
saveFilter(checked);
// Close the menu (mirror applets.js close logic)
var menu = document.getElementById('id_billscroll_menu');
if (menu) menu.style.display = 'none';
var gear = document.querySelector(
'.gear-btn[data-menu-target="id_billscroll_menu"]'
);
if (gear) gear.classList.remove('active');
});
}());
</script>
{% endblock %}

View File

@@ -8,6 +8,9 @@ Context: sig_cards, user_polarity, user_seat, sig_reserve_url, sig_reservations_
data-polarity="{{ user_polarity }}"
data-user-role="{{ user_seat.role }}"
data-reserve-url="{{ sig_reserve_url }}"
data-ready-url="{% url 'epic:sig_ready' room.id %}"
data-ready="{{ user_ready|yesno:'true,false' }}"
data-reservations="{{ sig_reservations_json }}">
<div class="sig-modal">

View File

@@ -36,6 +36,11 @@
{% endif %}
{% if room.table_status == "SKY_SELECT" %}
<button id="id_pick_sky_btn" class="btn btn-primary">PICK<br>SKY</button>
{% elif room.table_status == "SIG_SELECT" %}
<button id="id_pick_sky_btn" class="btn btn-primary" style="display:none">PICK<br>SKY</button>
{% if polarity_done %}
<p id="id_hex_waiting_msg">{% if user_polarity == "levity" %}Gravity settling . . .{% else %}Levity appraising . . .{% endif %}</p>
{% endif %}
{% endif %}
</div>
</div>
@@ -57,8 +62,8 @@
</div>
</div>
{# Sig Select overlay — only shown to seated gamers in this polarity #}
{% if room.table_status == "SIG_SELECT" and user_polarity %}
{# Sig Select overlay — suppressed once this gamer's polarity sigs are assigned #}
{% if room.table_status == "SIG_SELECT" and user_polarity and not polarity_done %}
{% include "apps/gameboard/_partials/_sig_select_overlay.html" %}
{% endif %}

View File

@@ -1,10 +1,10 @@
{% load lyric_extras %}
<section id="id_drama_scroll" class="drama-scroll" data-scroll-position="{{ scroll_position|default:0 }}">
{% for event in events %}
<div class="drama-event {% if event.actor == viewer %}mine{% else %}theirs{% endif %}">
<span class="drama-event-body">
<div class="drama-event {% if event.actor == viewer %}mine{% else %}theirs{% endif %}" data-label="{% if event.struck %}redact{% else %}frame{% endif %}">
<span class="drama-event-body{% if event.struck %} struck{% endif %}">
<strong>{{ event.actor|display_name }}</strong>
{{ event.to_prose }}
{{ event.to_prose|safe }}
</span>
<time class="drama-event-time" datetime="{{ event.timestamp|date:'c' }}">
{{ event.timestamp|relative_ts }}