feat(room-nav): show topic and last-message preview for rooms in the sidebar#669
feat(room-nav): show topic and last-message preview for rooms in the sidebar#669Just-Insane wants to merge 10 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds room-topic and last-message previews to room entries in the sidebar (Home + Spaces) by introducing a new live-timeline scanning hook, and adjusts Sliding Sync list timeline limits so enough events are available to compute previews reliably.
Changes:
- Add
useRoomLastMessagehook to derive a sender-prefixed “last message” preview from the live timeline (including encrypted placeholder + decryption updates). - Wire new preview toggles through settings and into
RoomNavItemfor Home/Space/Direct sidebars. - Increase Sliding Sync
LIST_TIMELINE_LIMITfrom 1 → 5 to avoid empty timelines when only relations are returned.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
src/client/slidingSync.ts |
Raises list timeline limit to ensure previews can find a parent message when relations are present. |
src/app/state/settings.ts |
Adds settings flags for DM/room topic/message previews and defaults. |
src/app/pages/client/space/Space.tsx |
Passes room preview settings down to room nav items in Spaces. |
src/app/pages/client/home/Home.tsx |
Passes room preview settings down to room nav items in Home. |
src/app/pages/client/direct/Direct.tsx |
Adds DM message preview setting plumbing to DM list rendering. |
src/app/hooks/useRoomLastMessage.ts |
New hook computing last-message preview from live timeline with decryption updates. |
src/app/features/settings/cosmetics/Themes.tsx |
Adds UI toggles for DM message preview, room topic preview, and room message preview. |
src/app/features/room-nav/RoomNavItem.tsx |
Displays topic/last-message preview under room names based on new settings. |
.changeset/room-message-preview.md |
Changeset entry for the room-nav preview feature. |
.changeset/feat-dm-message-preview.md |
Changeset entry for DM preview feature (scope may not match PR metadata). |
test.txt |
Appears unrelated scratch file. |
run_diffs.sh |
Appears to be a local developer utility script. |
presence_info.txt |
Appears to be local debug/output data. |
output.txt |
Appears to be local debug/output data. |
branches.txt |
Appears to be local debug/output data. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function useRoomLastMessage( | ||
| room: Room | undefined, | ||
| mx: MatrixClient | undefined | ||
| ): string | undefined { | ||
| const [text, setText] = useState<string | undefined>(() => | ||
| room && mx ? getLastMessageText(room, mx) : undefined | ||
| ); | ||
|
|
||
| useEffect(() => { | ||
| if (!room || !mx) { | ||
| setText(undefined); | ||
| return undefined; | ||
| } | ||
| setText(getLastMessageText(room, mx)); | ||
|
|
||
| const update = () => setText(getLastMessageText(room, mx)); | ||
| room.on(RoomEventEnum.Timeline, update); | ||
| room.on(RoomEventEnum.LocalEchoUpdated, update); | ||
|
|
||
| // Re-check when any event in this room is decrypted (encrypted → plaintext). | ||
| const onDecrypted = (ev: MatrixEvent) => { | ||
| if (ev.getRoomId() === room.roomId) update(); | ||
| }; | ||
| mx.on(MatrixEventEvent.Decrypted, onDecrypted); | ||
|
|
||
| return () => { | ||
| room.off(RoomEventEnum.Timeline, update); | ||
| room.off(RoomEventEnum.LocalEchoUpdated, update); | ||
| mx.off(MatrixEventEvent.Decrypted, onDecrypted); | ||
| }; | ||
| }, [room, mx]); | ||
|
|
||
| return text; | ||
| } |
There was a problem hiding this comment.
This hook is new behavior that affects sidebar rendering and has several edge cases (replies, edits, redactions, encrypted→decrypted transitions). The repo already uses Vitest for hook-level tests; adding focused unit tests for useRoomLastMessage (e.g., skipping edits/reactions, trimming reply fallback, updating on decryption) would help prevent regressions.
6ded99e to
20376bf
Compare
27d4e9b to
fc1733d
Compare
- Test stripReplyFallback: plain text, quoted lines, no separator, multi-line - Test eventToPreviewText: all msg types, encrypted, sticker, reactions, edits, reply fallback - Test getLastMessageText: You prefix, display name, userId fallback, skip reactions, empty timeline - Test useRoomLastMessage hook: undefined room, initial render, Timeline event updates - Export pure functions for testability
Subscribe to Decrypted events before reading current state so events that decrypt between the initial render and listener mount are not missed. Explicitly request decryption for the last encrypted event on mount so rooms not yet opened (e.g. sliding-sync previews) resolve their preview text without requiring the user to visit the room. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…croll, fix eventId drag-to-bottom, increase list timeline limit - useTimelineSync: change auto-scroll recovery useEffect → useLayoutEffect to prevent one-frame flash after timeline reset - useTimelineSync: remove premature scrollToBottom from useLiveTimelineRefresh (operated on pre-commit DOM with stale scrollSize) - useTimelineSync: remove scrollToBottom + eventsLengthRef suppression from useLiveEventArrive; let useLayoutEffect handle scroll after React commits - RoomTimeline: init atBottomState to false when eventId is set, and reset it in the eventId useEffect, so auto-scroll doesn't drag to bottom on bookmark nav - RoomTimeline: change instant scrollToBottom to use scrollToIndex instead of scrollTo(scrollSize) — works correctly regardless of VList measurement state - slidingSync: increase DEFAULT_LIST_TIMELINE_LIMIT 1→3 to reduce empty previews when recent events are reactions/edits/state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Debounce useRoomLastMessage update handler (300ms) to avoid re-rendering every room preview on each timeline event - Debounce Direct.tsx activityCounter (500ms) to batch DM list re-sorts during rapid event bursts (reactions, edits, etc.) - Update test to account for debounced update timing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fc1733d to
7ac6750
Compare
Description
Extends the room navigation sidebar so that non-DM rooms also display a topic or last-message preview beneath the room name — mirroring the DM list preview added in #666.
useRoomLastMessage— new hook that scans the live timeline in reverse to find the most recent visible message event (skipping reactions, redactions, and state events) and returns a human-readable preview string. Handles encrypted events (updates when decryption resolves), sender prefixing, and common content types (text, attachments, stickers, polls, etc.).SpaceItemsand the home-room list pass the preview down to eachNavItemcomponent.LIST_TIMELINE_LIMITincreased from1to5. With only 1 event, the SDK'seventShouldLiveIn()drops reactions and edits from the live timeline (their parent event is absent in the single-event batch), leaving the timeline empty. Fetching 5 events ensures the parent is almost always present so previews work for unvisited rooms.Fixes #
Type of change
Checklist:
AI disclosure:
useRoomLastMessage.ts— the reverse-scan loop and event-type dispatch table were drafted with AI assistance and then reviewed against the Matrix spec and existing hook patterns in the codebase. The sliding-syncLIST_TIMELINE_LIMITdiagnosis and fix were done manually after investigating the SDK'seventShouldLiveIn()behaviour.