feat(ui): collapse long messages with Show more / Show less (LC-256) #306

Merged
longjacksonle merged 1 commit from feat/lc-256-collapse-long-messages into main 2026-06-14 03:37:43 +02:00

What

Folds messages whose rendered body overflows a height threshold behind a "Show more" / "Show less" toggle (LC-256), so a pasted log or wall of text no longer takes over the viewport.

How

  • server/templates/room/message.html: the full Markdown body still renders; it just gains a data-lc-collapse marker and a hidden data-lc-collapse-toggle button (with localized data-lc-more / data-lc-less). No clamp is applied server-side.
  • server/assets/main.css: .lc-collapsible clamps max-height to 20rem with overflow:hidden and a non-interactive bottom fade to --surface.
  • server/templates/partials/auto_scroll.html: a processCollapse(scope) pass measures each unprocessed body's natural scrollHeight; only when it exceeds 420px does it add the clamp and reveal the toggle (which toggles the class + label). Runs on initial paint (before scroll anchoring, so clamped heights settle), on htmx:afterSwap (edited re-render, re-measured), and on htmx:oobAfterSwap (live append folded before re-anchoring). Idempotent via a -done marker; the body-level listener is torn down with the existing autoscroll teardown.
  • server/locales/{en,es}/room.ftl: room-msg-show-more / room-msg-show-less.

Progressive enhancement: with JS off the full body renders (nothing hidden from no-JS clients or crawlers). Collapse applies to the Markdown body only, not attachments / polls / reactions.

The four LC-77 golden render fixtures are regenerated for the new body markup (diff is exactly the added marker + toggle).

Pure front-end: no route, DB, or env change. Not operator-visible.

Tests

routes_drafts::message_body_ships_collapse_markup asserts a seeded message ships the marker + toggle. just test and just test-saas pass.

QA note

The fold is JS-measured and the toggle is JS-driven, so they want a quick manual click-through before merge: post a very long message (confirm it clamps with a fade + "Show more"); expand/collapse it; confirm a short message shows no toggle; confirm a long message arriving live over the WS folds while you are scrolled to the bottom; confirm an edit that makes a message long/short updates the fold. Tune the 420px threshold if it fires on normal multi-line messages.

## What Folds messages whose rendered body overflows a height threshold behind a "Show more" / "Show less" toggle (LC-256), so a pasted log or wall of text no longer takes over the viewport. ## How - `server/templates/room/message.html`: the full Markdown body still renders; it just gains a `data-lc-collapse` marker and a `hidden` `data-lc-collapse-toggle` button (with localized `data-lc-more` / `data-lc-less`). No clamp is applied server-side. - `server/assets/main.css`: `.lc-collapsible` clamps `max-height` to `20rem` with `overflow:hidden` and a non-interactive bottom fade to `--surface`. - `server/templates/partials/auto_scroll.html`: a `processCollapse(scope)` pass measures each unprocessed body's natural `scrollHeight`; only when it exceeds `420px` does it add the clamp and reveal the toggle (which toggles the class + label). Runs on initial paint (before scroll anchoring, so clamped heights settle), on `htmx:afterSwap` (edited re-render, re-measured), and on `htmx:oobAfterSwap` (live append folded before re-anchoring). Idempotent via a `-done` marker; the body-level listener is torn down with the existing autoscroll teardown. - `server/locales/{en,es}/room.ftl`: `room-msg-show-more` / `room-msg-show-less`. Progressive enhancement: with JS off the full body renders (nothing hidden from no-JS clients or crawlers). Collapse applies to the Markdown body only, not attachments / polls / reactions. The four LC-77 golden render fixtures are regenerated for the new body markup (diff is exactly the added marker + toggle). Pure front-end: no route, DB, or env change. Not operator-visible. ## Tests `routes_drafts::message_body_ships_collapse_markup` asserts a seeded message ships the marker + toggle. `just test` and `just test-saas` pass. ## QA note The fold is JS-measured and the toggle is JS-driven, so they want a quick manual click-through before merge: post a very long message (confirm it clamps with a fade + "Show more"); expand/collapse it; confirm a short message shows no toggle; confirm a long message arriving live over the WS folds while you are scrolled to the bottom; confirm an edit that makes a message long/short updates the fold. Tune the `420px` threshold if it fires on normal multi-line messages.
feat(ui): collapse long messages with Show more / Show less (LC-256)
All checks were successful
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Nosey parker (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / TruffleHog (pull_request) Successful in 5s
check-secrets / Nosey parker (pull_request) Successful in 5s
check-secrets / Kingfisher (pull_request) Successful in 5s
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 2m52s
4d919f85d3
Folds messages whose rendered body overflows a height threshold behind a Show more / Show less toggle so the timeline stays scannable. Progressive enhancement: the full body always renders, and auto_scroll.html measures it on render, adding the clamp and revealing the toggle only when it actually overflows. With JS off nothing is hidden.

The processCollapse pass runs on initial paint (before scroll anchoring, so the clamped heights settle), on htmx:afterSwap (an edited message re-renders and is re-measured), and on htmx:oobAfterSwap (a live arrival is folded before re-anchoring so a pinned viewer lands at the clamped bottom). It is idempotent via a -done marker and tears its body-level listener down with the existing autoscroll teardown. Collapse applies to the Markdown body only, never attachments / polls / reactions.

The clamp + bottom fade live in main.css (.lc-collapsible, fading to --surface, non-interactive). Strings localized in en + es. The four LC-77 golden render fixtures are regenerated for the new body markup. Test asserts a non-empty message ships the collapse marker + toggle.

#LC-256
#LC-257

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/lc-256-collapse-long-messages 2026-06-14 03:37:43 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!306
No description provided.