added type='button' to both guard portal btns so firefox won't normalize to type='submit'; fixed several FTs for new click-guard functionality on Role card select & room gear menu DEL & BYE btns; several restorations to landscape breakpoint incl. logged-ion display_name, copyright info; provided title to room_scroll.html; a slurry of other minor fixes
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Disco DeDisco
2026-03-23 19:31:57 -04:00
parent eecb6c2be6
commit 5607f70852
15 changed files with 365 additions and 65 deletions

View File

@@ -1,6 +1,7 @@
{% extends "core/base.html" %}
{% block title_text %}{{ room.name }} — Drama Log{% endblock %}
{% block title_text %}{{ room.name }} — Billscroll{% endblock %}
{% block header_text %}<span>Bill</span>scroll{% endblock header_text %}
{% block content %}
<div class="billboard-page">

View File

@@ -1,27 +1,4 @@
{% include "apps/gameboard/_partials/_applet_menu.html" %}
<div id="id_game_applets_container">
<div id="id_game_applet_menu" style="display:none;">
<form
hx-post="{% url "toggle_game_applets" %}"
hx-target="#id_game_applets_container"
hx-swap="outerHTML"
>
{% csrf_token %}
{% for entry in applets %}
<label>
<input
type="checkbox"
name="applets"
value="{{ entry.applet.slug }}"
{% if entry.visible %}checked{% endif %}
>
{{ entry.applet.name }}
</label>
{% endfor %}
<div class="menu-btns">
<button type="submit" class="btn btn-confirm">OK</button>
<button type="button" id="id_game_applet_menu_cancel" class="btn btn-cancel applet-menu-cancel">NVM</button>
</div>
</form>
</div>
{% include "apps/applets/_partials/_applets.html" %}
</div>

View File

@@ -3,12 +3,12 @@
{% if request.user == room.owner %}
<form method="POST" action="{% url 'epic:delete_room' room.id %}">
{% csrf_token %}
<button type="submit" class="btn btn-danger">DEL</button>
<button type="submit" class="btn btn-danger" data-confirm="Delete this room?">DEL</button>
</form>
{% else %}
<form method="POST" action="{% url 'epic:abandon_room' room.id %}">
{% csrf_token %}
<button type="submit" class="btn btn-abandon">BYE</button>
<button type="submit" class="btn btn-abandon" data-confirm="Leave this room?">BYE</button>
</form>
{% endif %}
</div>

View File

@@ -11,6 +11,6 @@
</a>
</nav>
<div class="footer-container">
<small>&copy;{% now "Y" %} Dis Co.</small>
<small>&copy;{% now "Y" %} <br>Dis&nbsp;Co.</small>
</div>
</footer>

View File

@@ -15,7 +15,7 @@
</div>
<form method="POST" action="{% url "logout" %}">
{% csrf_token %}
<button id="id_logout" class="btn btn-primary btn-xl" type="submit">
<button id="id_logout" class="btn btn-primary btn-xl" type="submit" data-confirm="Log out?">
Log Out
</button>
</form>

View File

@@ -57,8 +57,91 @@
{% endif %}
<dialog id="id_kit_bag_dialog"></dialog>
<div id="id_guard_portal">
<span class="guard-message"></span>
<div class="guard-actions">
<button class="btn btn-confirm guard-yes" type="button">OK</button>
<button class="btn btn-cancel guard-no" type="button">NVM</button>
</div>
</div>
{% block scripts %}
{% endblock scripts %}
<script>
(function () {
var portal = null;
var _cb = null;
var _onDismiss = null;
function show(anchor, message, callback, onDismiss) {
if (!portal) return;
_cb = callback;
_onDismiss = onDismiss || null;
portal.querySelector('.guard-message').innerHTML = message;
portal.classList.add('active');
var rect = anchor.getBoundingClientRect();
var pw = portal.offsetWidth;
var rawLeft = rect.left + rect.width / 2;
var cleft = Math.max(pw / 2 + 8, Math.min(rawLeft, window.innerWidth - pw / 2 - 8));
portal.style.left = Math.round(cleft) + 'px';
if (rect.top > 120) {
portal.style.top = Math.round(rect.top) + 'px';
portal.style.transform = 'translate(-50%, calc(-100% - 0.5rem))';
} else {
portal.style.top = Math.round(rect.bottom) + 'px';
portal.style.transform = 'translate(-50%, 0.5rem)';
}
}
function dismiss() {
if (!portal) return;
var od = _onDismiss;
portal.classList.remove('active');
_cb = null;
_onDismiss = null;
if (od) od();
}
function doConfirm() {
var cb = _cb;
portal.classList.remove('active');
_cb = null;
_onDismiss = null;
if (cb) cb();
}
document.addEventListener('DOMContentLoaded', function () {
portal = document.getElementById('id_guard_portal');
if (!portal) return;
portal.querySelector('.guard-yes').addEventListener('click', doConfirm);
portal.querySelector('.guard-no').addEventListener('click', dismiss);
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') dismiss();
});
// Outside-click to dismiss — capture phase + stopPropagation
// prevents the click from cascading to backdrop listeners (e.g. closeFan)
document.addEventListener('click', function (e) {
if (!portal.classList.contains('active')) return;
if (portal.contains(e.target)) return;
e.stopPropagation();
dismiss();
}, true);
// Intercept [data-confirm] buttons (capture phase, before form submits)
document.addEventListener('click', function (e) {
var btn = e.target.closest('[data-confirm]');
if (!btn) return;
e.preventDefault();
e.stopImmediatePropagation();
var form = btn.closest('form');
show(btn, btn.dataset.confirm, function () {
if (form) form.submit();
});
}, true);
});
window.showGuard = show;
}());
</script>
<script src="{% static "vendor/htmx.min.js" %}"></script>
<script src="{% static "apps/applets/applets.js" %}"></script>
<script src="{% static "apps/dashboard/game-kit.js" %}"></script>