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(response.context["recent_room"], room)
|
||||||
self.assertEqual(len(response.context["recent_events"]), 1)
|
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):
|
def test_recent_room_is_none_when_no_events(self):
|
||||||
response = self.client.get("/billboard/")
|
response = self.client.get("/billboard/")
|
||||||
self.assertIsNone(response.context["recent_room"])
|
self.assertIsNone(response.context["recent_room"])
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def billboard(request):
|
|||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
recent_events = (
|
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 []
|
if recent_room else []
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class GameEvent(models.Model):
|
|||||||
}
|
}
|
||||||
code = d.get("role", "?")
|
code = d.get("role", "?")
|
||||||
role = d.get("role_display") or _role_names.get(code, code)
|
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:
|
if self.verb == self.ROLES_REVEALED:
|
||||||
return "All roles assigned"
|
return "All roles assigned"
|
||||||
return self.verb
|
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 ────────────────────────────────────────────────────────
|
// ── My Scrolls list ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
#id_applet_billboard_my_scrolls {
|
#id_applet_billboard_my_scrolls {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load lyric_extras %}
|
||||||
<section
|
<section
|
||||||
id="id_applet_billboard_most_recent"
|
id="id_applet_billboard_most_recent"
|
||||||
style="--applet-cols: {{ entry.applet.grid_cols }}; --applet-rows: {{ entry.applet.grid_rows }};"
|
style="--applet-cols: {{ entry.applet.grid_cols }}; --applet-rows: {{ entry.applet.grid_rows }};"
|
||||||
@@ -5,10 +6,29 @@
|
|||||||
<h2>Most Recent</h2>
|
<h2>Most Recent</h2>
|
||||||
{% if recent_room %}
|
{% if recent_room %}
|
||||||
<a href="{% url 'billboard:scroll' recent_room.id %}" class="most-recent-room-link">{{ recent_room.name }}</a>
|
<a href="{% url 'billboard:scroll' recent_room.id %}" class="most-recent-room-link">{{ recent_room.name }}</a>
|
||||||
{% with events=recent_events %}
|
<section id="id_drama_scroll" class="drama-scroll">
|
||||||
{% include "core/_partials/_scroll.html" %}
|
<a href="{% url 'billboard:scroll' recent_room.id %}" class="most-recent-load-more">Load more….</a>
|
||||||
{% endwith %}
|
{% 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 %}
|
{% else %}
|
||||||
<p><small>No recent activity.</small></p>
|
<p><small>No recent activity.</small></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var scroll = document.getElementById('id_drama_scroll');
|
||||||
|
if (scroll) scroll.scrollTop = scroll.scrollHeight;
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user