styled more of Most Recent applet, allowing for scrolling of 36 most recent events and Load More link

This commit is contained in:
Disco DeDisco
2026-03-24 17:19:09 -04:00
parent 189d329e76
commit c71f4eb68c
5 changed files with 94 additions and 5 deletions

View File

@@ -53,6 +53,30 @@ class BillboardViewTest(TestCase):
self.assertEqual(response.context["recent_room"], room)
self.assertEqual(len(response.context["recent_events"]), 1)
def test_recent_events_capped_at_36(self):
room = Room.objects.create(name="Test Room", owner=self.user)
for i in range(40):
record(
room, GameEvent.SLOT_FILLED, actor=self.user,
slot_number=1, token_type="coin",
token_display="Coin-on-a-String", renewal_days=7,
)
response = self.client.get("/billboard/")
self.assertEqual(len(response.context["recent_events"]), 36)
def test_recent_events_in_chronological_order(self):
room = Room.objects.create(name="Test Room", owner=self.user)
for _ in range(3):
record(
room, GameEvent.SLOT_FILLED, actor=self.user,
slot_number=1, token_type="coin",
token_display="Coin-on-a-String", renewal_days=7,
)
response = self.client.get("/billboard/")
events = response.context["recent_events"]
timestamps = [e.timestamp for e in events]
self.assertEqual(timestamps, sorted(timestamps))
def test_recent_room_is_none_when_no_events(self):
response = self.client.get("/billboard/")
self.assertIsNone(response.context["recent_room"])

View File

@@ -27,7 +27,7 @@ def billboard(request):
.first()
)
recent_events = (
recent_room.events.select_related("actor").order_by("-timestamp")[:10]
list(recent_room.events.select_related("actor").order_by("-timestamp")[:36])[::-1]
if recent_room else []
)

View File

@@ -73,7 +73,7 @@ class GameEvent(models.Model):
}
code = d.get("role", "?")
role = d.get("role_display") or _role_names.get(code, code)
return f"starts as {role}"
return f"elects to start as {role}"
if self.verb == self.ROLES_REVEALED:
return "All roles assigned"
return self.verb

View File

@@ -71,6 +71,51 @@ body.page-billscroll {
}
}
// ── Billboard applet placement ─────────────────────────────────────────────
// Explicit placement: My Scrolls + Contacts stack left, Most Recent fills right.
// Portrait override (container query) restores stacked full-width layout.
#id_billboard_applets_container {
#id_applet_billboard_my_scrolls { grid-column: 1 / span 4; grid-row: 1 / span 3; }
#id_applet_billboard_my_contacts { grid-column: 1 / span 4; grid-row: 4 / span 3; }
#id_applet_billboard_most_recent { grid-column: 5 / span 8; grid-row: 1 / span 6; }
@container (max-width: 550px) {
#id_applet_billboard_my_scrolls,
#id_applet_billboard_my_contacts,
#id_applet_billboard_most_recent {
grid-column: 1 / span 12;
grid-row: span var(--applet-rows, 3);
}
}
}
// ── Most Recent applet — scrollable drama feed ─────────────────────────────
#id_applet_billboard_most_recent {
display: flex;
flex-direction: column;
.most-recent-room-link {
flex-shrink: 0;
margin-bottom: 0.25rem;
font-weight: bold;
}
#id_drama_scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
}
.most-recent-load-more {
display: block;
padding-bottom: 0.5rem;
font-size: 0.8rem;
text-align: center;
}
}
// ── My Scrolls list ────────────────────────────────────────────────────────
#id_applet_billboard_my_scrolls {

View File

@@ -1,3 +1,4 @@
{% load lyric_extras %}
<section
id="id_applet_billboard_most_recent"
style="--applet-cols: {{ entry.applet.grid_cols }}; --applet-rows: {{ entry.applet.grid_rows }};"
@@ -5,10 +6,29 @@
<h2>Most Recent</h2>
{% if recent_room %}
<a href="{% url 'billboard:scroll' recent_room.id %}" class="most-recent-room-link">{{ recent_room.name }}</a>
{% with events=recent_events %}
{% include "core/_partials/_scroll.html" %}
{% endwith %}
<section id="id_drama_scroll" class="drama-scroll">
<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="event-body">
<strong>{{ event.actor|display_name }}</strong>
{{ event.to_prose }}<br>
<time class="event-time" datetime="{{ event.timestamp|date:'c' }}">
{{ event.timestamp|date:"N j, g:i a" }}
</time>
</span>
</div>
{% empty %}
<p class="event-empty"><small>No events yet.</small></p>
{% endfor %}
</section>
{% else %}
<p><small>No recent activity.</small></p>
{% endif %}
</section>
<script>
(function() {
var scroll = document.getElementById('id_drama_scroll');
if (scroll) scroll.scrollTop = scroll.scrollHeight;
})();
</script>