feat(dm): system-event rows, grouping window, header icons, call end-state feedback (LC-433) #437
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/dm-view-call-feedback"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
DM conversation view UI/UX + a call end-state signaling fix (refs data/ref-dm.png, data/ref-call-modal.png). Closes LC-433 (sub-tasks LC-434..LC-438).
1+2 - Call/system events as timeline rows (LC-434)
is_system messages ("started a call.", "Call transcript saved") were rendered with
{{ message.body }}raw, so the transcript link showed literal markdown and the rows floated as plain right-aligned text. They now render as a centered, muted event row (icon + actor + event + time, like the day divider). The transcript body is parsed inline (newMessageView::system_html/render_system_inline) into a real anchor; only internal/pathsare linkified and both parts are HTML-escaped.3 - Grouping window 15 -> 5 min (LC-435)
MESSAGE_GROUPING_WINDOW_SECONDS900 -> 300, the sharedis_follow_up_ofpredicate used by both room + DM. Same-author messages sent minutes/hours apart now break into a fresh block (header + avatar + timestamp); rapid bursts still group tightly (py-0within a group,py-2between). Grouping tests updated.4 - DM header consistency (LC-436)
Mute + Block now match the call/video/devices icon-button treatment. Mute is a bell / slashed-bell toggle (the sr-only checkbox keeps the existing hx-post mute wiring;
:has(input:checked)swaps the icon and tints it); Block is a ban icon button with a tooltip.5 - Incoming-call modal polish (LC-437)
Caller avatar above the name, theme-token surfaces + Accept/Decline (works in dark), and Escape now declines the ring (keyboard-dismissable) in addition to the existing focus trap. No overhaul.
6 - Call end-states no longer silent (LC-438)
reject; cancel already signaledcancel; both now have feedback + a record on both sides.New i18n: js-call-declined-by / js-call-missed-from / js-call-no-answer (en + es). New tests:
render_system_inline(transcript link parse, escaping, external-link rejection) + the 5-min grouping window.just check,just test,just test-saaspass; call.js syntax-checked; Tailwind rebuilt. (Dev server is SSO-gated, so a click-through on the PR build - light + dark - is worthwhile, especially the call decline/cancel/no-answer paths.)🤖 Generated with Claude Code
DM conversation polish + a call end-state signaling fix. LC-434 - Call/system events render as a centered, muted timeline row (icon + actor + event + time, like the day divider) instead of right-floating plain text. The transcript-saved "[label](url)" body is parsed inline (new MessageView::system_html / render_system_inline) into a real anchor instead of literal markdown; only internal /paths are linkified and everything is escaped. LC-435 - Message grouping window narrowed 15 min -> 5 min (MESSAGE_GROUPING_WINDOW_SECONDS=300, shared by room + DM). Same-author messages sent far apart now break into a fresh block with header + avatar + timestamp; rapid bursts still group tightly (py-0 within a group, py-2 between). Grouping tests updated. LC-436 - DM header Mute + Block now match the call/video/devices icon buttons. Mute is a bell/slashed-bell toggle (sr-only checkbox keeps the hx-post wiring, :has(input:checked) swaps the icon + tints); Block is a ban icon button with a tooltip. LC-437 - Incoming-call dialog: caller avatar above the name, theme-token surfaces/buttons (works in dark), and Escape now declines (keyboard-dismissable) on top of the existing focus trap. LC-438 - No call end-state is silent anymore. The server logs decline/cancel as call-event rows ("declined the call." / "cancelled the call.") so both parties keep a thread record (mirrors "started a call."). The caller gets a toast "{peer} declined the call" on reject; the callee gets "Missed call from {peer}" when the caller cancels while ringing; and a 45s no-answer timeout ends a ringing outgoing call with "No answer" (signals cancel, so the callee still gets the missed-call record). New i18n: js-call-declined-by / -missed-from / -no-answer (en + es). New tests: render_system_inline (transcript link, escaping, external-link rejection) + the updated grouping window. just check, just test, just test-saas pass; call.js syntax-checked; Tailwind rebuilt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>