Files
python-tdd/src/templates/apps/gameboard/_partials
Disco DeDisco b2f1511c2d my-scrolls / my-games applet rows: prepend actor display_name to the body cell — the latest event's to_prose returns the action alone ("deposits a Carte Blanche…") because scroll.html splits the row across <strong>{{ event.actor|display_name }}</strong> + adjacent {{ to_prose|safe }}; the applet rows have a single middle column (<title> | <body> | <ts>) so they need both halves concatenated into .row-body; ROOM_CREATED welcome events (actor=None) keep rendering prose alone since to_prose already reads "Welcome to <name>!" — the {% if item.latest_event.actor %} guard skips the prefix, mirroring the same actor-guarded <strong> we added to _partials/_scroll.html + _applet-most-recent-scroll.html on c03fb2b so welcome lines don't carry a bogus empty actor; 2 ITs added — BillboardViewTest.test_my_scrolls_applet_row_body_includes_actor_display_name + GameboardViewTest.test_my_games_row_body_includes_actor_display_name — scoped to <span class="row-body">...stuart...deposits...</span> (regex match on the .row-body cell content) so the assertion can't pass on actor renders outside the row (the Most Recent Scroll applet on /billboard/ renders the same actor too, separately — initial pass missed this and assertIn("acto", body) matched there instead, hiding the bug); BillboardViewTest also gains test_my_scrolls_applet_row_body_no_actor_prefix_for_welcome to lock in the no-empty-prefix contract for ROOM_CREATED welcome events; 931 ITs green; settings.local.json fix-up — Bash(git add *) (literal * would only match the exact string "git add *", not git add -u) → Bash(git add:*) + companion read-only git patterns (status / diff / log / show) so the in-session commit flow stops prompting — TDD
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 00:13:33 -04:00
..
applet feed unification — My Buds + My Notes drop the [Feature forthcoming] / empty placeholders for live top-3 feeds, mirroring the long-standing My Posts pattern; all five in-grid list applets (My Posts / My Buds / My Notes / My Scrolls / My Games) now route their <ul> through a single shared partial _applet-grid-list.html (newly extracted) so item rendering + empty-state row + scroll-buffer all live in one place — _applet-list-shell.html (the dedicated billbuds/billposts page shell) now internally includes the same grid-list partial for its inner <ul>, so the dedicated-page and in-grid lists share the same skeleton; new per-applet item partials _my_buds_applet_item.html (mirrors _my_buds_item.html w. data-bud-id + display_name), _my_notes_item.html (links to billboard:my_notes; uses display_name), _my_posts_applet_item.html (Post link + title), _my_scrolls_item.html (Room link to billboard:scroll), _my_games_item.html (Room link to epic:gatekeeper); view-side _billboard_context gains _recent_buds(user) — sorts the User.buds auto-through table by -id so newest-added-first w.o. an explicit through model w. timestamps (manage [r.to_user for r in rows]) — + _recent_notes(user) (user.notes.order_by('-earned_at')[:limit]); same two helpers threaded into new_post's GET-with-form-errors branch (line 270-274) so the rerender keeps the new applet content visible; 7 ITs added to BillboardViewTest covering recent_buds ordering / cap / empty + recent_notes ordering / cap / cross-user isolation / empty; SCSS — .applet-list / .applet-list-entry / .applet-list-buffer lifted from .applet-list-page .applet-scroll scope to top level so they apply in both surfaces; in-grid applets get display: flex; flex-direction: column; .applet-list { flex: 1 } so the list scrolls within the applet box; #id_applet_my_games ul-centring + .scroll-list + #id_applet_notes h2 { writing-mode: vertical-rl ... } overrides removed (centring was an empty-state-only behaviour, scroll-list + vertical-rl redundant w. the new shared rule + the %applet-box > h2 rule); My Games items now left-aligned by default; empty-state row recovers the centred-italic-dim treatment via .applet-list-entry--empty { flex: 1; display: flex; align-items: center; justify-content: center; opacity: 0.6; font-style: italic } + .applet-list:has(> .applet-list-entry--empty) { display: flex; flex-direction: column } — so "No buds yet" / "No notes yet" / "No games yet" / "No scrolls yet" / "No posts yet" all centre in their applet aperture, reverting to the left-aligned stack the moment a real item lands; Most Recent Scroll's outer empty <p><small>No recent activity.</small></p> adopts the same .applet-list-entry .applet-list-entry--empty classes (section is already flex-column from existing rule) so it picks up the unified centred-italic-dim treatment
2026-05-12 22:48:32 -04:00
my-scrolls / my-games applet rows: prepend actor display_name to the body cell — the latest event's to_prose returns the action alone ("deposits a Carte Blanche…") because scroll.html splits the row across <strong>{{ event.actor|display_name }}</strong> + adjacent {{ to_prose|safe }}; the applet rows have a single middle column (<title> | <body> | <ts>) so they need both halves concatenated into .row-body; ROOM_CREATED welcome events (actor=None) keep rendering prose alone since to_prose already reads "Welcome to <name>!" — the {% if item.latest_event.actor %} guard skips the prefix, mirroring the same actor-guarded <strong> we added to _partials/_scroll.html + _applet-most-recent-scroll.html on c03fb2b so welcome lines don't carry a bogus empty actor; 2 ITs added — BillboardViewTest.test_my_scrolls_applet_row_body_includes_actor_display_name + GameboardViewTest.test_my_games_row_body_includes_actor_display_name — scoped to <span class="row-body">...stuart...deposits...</span> (regex match on the .row-body cell content) so the assertion can't pass on actor renders outside the row (the Most Recent Scroll applet on /billboard/ renders the same actor too, separately — initial pass missed this and assertIn("acto", body) matched there instead, hiding the bug); BillboardViewTest also gains test_my_scrolls_applet_row_body_no_actor_prefix_for_welcome to lock in the no-empty-prefix contract for ROOM_CREATED welcome events; 931 ITs green; settings.local.json fix-up — Bash(git add *) (literal * would only match the exact string "git add *", not git add -u) → Bash(git add:*) + companion read-only git patterns (status / diff / log / show) so the in-session commit flow stops prompting — TDD
2026-05-13 00:13:33 -04:00
bud panels duplicate-add guard: server-side already_present flag + client-side error Brief w. FYI flash highlight on the existing entry — for each of the three #id_bud_btn panels (My Buds / post-share / gatekeeper-invite), the JSON response from add_bud / share_post / invite_gamer now carries {already_present, recipient_display, recipient_user_id}; bud-btn.js branches on already_present → calls new Brief.showDuplicateBanner({display_name, target_selector}) instead of the normal onSuccess append; banner title reads @<username> is already present, NVM dismisses, FYI dismisses AND eases in the .bud-duplicate-flash class (color: var(--terUser); text-shadow: 0 0 .5em var(--ninUser); transition: 600ms) onto the existing element (.bud-entry .bud-name / .post-recipient[data-user-id=…] / .gate-slot.filled[data-user-id=…]); gatekeeper "already present" = recipient is either GateSlot.FILLED + gamer OR has TableSeat OR has a pending RoomInvite (highlight target only set when seated — pending invites have no visible slot); .post-recipient chips + .gate-slot.filled cells gain data-user-id so the FYI selector can find them; my_buds.html now loads note.js via the {% block scripts %} pattern (Brief module is required by the duplicate banner path); bonus: latent test_jasmine.py bug fixed — "0 failures" in result.text matched "10 failures" / "20 failures" / etc, silently passing up to 99 failed specs; replaced w. re.search(r"(?<!\d)0 failures\b", …) (caught my new red specs, would've caught any prior Jasmine regression); 18 new ITs + 10 new Jasmine specs + 3 new FTs (one per panel) — TDD
2026-05-12 16:40:15 -04:00