styled more of Most Recent applet, allowing for scrolling of 36 most recent events and Load More link
This commit is contained in:
@@ -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"])
|
||||
|
||||
@@ -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 []
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user