Skip to content

Add unread toast to room list sections#33961

Open
langleyd wants to merge 8 commits into
developfrom
langleyd/room-list-section-unread-toast
Open

Add unread toast to room list sections#33961
langleyd wants to merge 8 commits into
developfrom
langleyd/room-list-section-unread-toast

Conversation

@langleyd

@langleyd langleyd commented Jun 24, 2026

Copy link
Copy Markdown
Member

Resolves #31340

Unread activity toast

Adds an "Unread messages" toast to the bottom of the new room list. It appears when a room with a notification count is scrolled below the visible area; clicking it scrolls that room into view.

Details

  • Trigger is count-only: fires on hasUnreadCount (greencount), not activity dots or marked-unread.
  • Fold detection: VirtualizedRoomListView reports the last genuinely visible item index (via IntersectionObserver, excluding Virtuoso's overscan) to the view model, which decides what's "below the fold".
  • Collapsed sections: if a collapsed section's header is below the fold and hides a notifying room, the toast targets the header.
  • Shared toast slot: the existing RoomListToast (chat moved / section created) takes precedence over this toast when both are active.
  • Requires compound-web 9.7.0 (clickable Toast variant).
  • Adds Playwright e2e (flat list, activity-dot negative case, collapsed-section) + storybook visual baselines.
Screen.Recording.2026-06-26.at.14.14.11.mov

langleyd added 4 commits June 26, 2026 12:30
The room list needs two things the generic list did not expose: the underlying
scroll container (to observe which items are genuinely visible) and the imperative
scroll handle (to scroll an item into view). Forward an optional scrollerRef from
useVirtualizedList and pass scrollHandleRef through FlatVirtualizedList, mirroring
what GroupedVirtualizedList already exposes. Both are additive and optional, so other
consumers are unaffected.

Signed-off-by: David Langley <langley.dave@gmail.com>
Show a clickable "You have unread activity" pill when there are unread rooms
scrolled below the visible fold, including unreads hidden inside collapsed sections
whose header is below the fold. Clicking it scrolls the next such unread into view.

The visible fold is tracked with an IntersectionObserver over the rendered item
elements, so the toast appears as soon as a room crosses the fold rather than only
once it leaves Virtuoso's overscan buffer. The toast click is wired through an
imperative scroll handle the view registers with the view model.

Signed-off-by: David Langley <langley.dave@gmail.com>
- Apply oxfmt to the room list view model and virtualized view.
- Refresh the RoomListToast/RoomListView story snapshots: compound-web
  9.7.0 moves the typography classes onto the toast .content element and
  rebuilds the Toast CSS module hashes.
- Add the missing UnreadActivityToast render snapshot baseline.
@langleyd langleyd force-pushed the langleyd/room-list-section-unread-toast branch from c1d4b02 to 515abe8 Compare June 26, 2026 12:06
Cover the unread-activity toast end to end:
- it appears for a notifying room scrolled below the fold and clicking it
  scrolls that room into view (then the toast clears);
- a room with only an unread-activity dot (no notification count) does not
  raise it;
- a collapsed section hiding a notifying room raises it, and clicking
  scrolls the section header into view.
Reviewer feedback: the unread-activity toast and the transient event toasts
(section_created / chat_moved) should share one mechanism, with toast
lifecycle and precedence owned by the view model rather than split across a
separate snapshot flag and a view-level ternary.

- RoomListViewModel now reconciles the transient event toast and the derived
  unread-activity state into a single snapshot.toast via recomputeToast(); the
  event toast still takes precedence and auto-dismisses, and the unread toast
  reappears once it clears. Drops hasUnreadActivityBelow from the snapshot.
- RoomListView renders a single RoomListToast driven by snapshot.toast; the
  ToastType union gains 'unread_activity'. The standalone UnreadActivityToast
  component is folded into RoomListToast (clickable arrow-down variant).
- Adds VM tests for the unread-activity toast and the event/unread precedence.

@gaelledel gaelledel left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as expected

The room-list suites (RoomListView, VirtualizedRoomListView,
RoomListItemMoreOptionsMenu) import a heavy @dnd-kit + react-virtuoso graph.
Only @dnd-kit/abstract was pinned in optimizeDeps.include; @dnd-kit/dom,
@dnd-kit/react, @dnd-kit/abstract/modifiers and react-virtuoso were left to
runtime discovery. Under CI load the browser-mode dep optimizer can discover
them late, re-bundle and reload the page, which fails the in-flight
setupTests.ts import for those suites. Pinning the whole graph forces it into
the initial optimize pass so no re-run happens while tests load.
@langleyd langleyd requested a review from t3chguy June 26, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Room list: sections - P10 Indicator that a new message appeared in a different part of the room list

3 participants