feat: migrate components from ChannelActionContext, ChannelStateContext to StateStore instances - #3237
Merged
Merged
Conversation
# Conflicts: # src/components/MessageList/MessageList.tsx # src/components/MessageList/renderMessages.tsx
…d Resolver Registry and Built-in Strategies
…rops) and Header Toggle Wiring for Entity List Pane
…reserving Hide/Unhide
…ependent of Channel contexts
… and Remove Entity Semantics from LayoutController (Slot-Only Controller)
…eSlotEntity and ChannelSlot
…read-on-mount, search-focused jump for Channel and rewrite Channel tests
…tton when irrelevant
…ges arrive in MessageList
The reducer-era state management is gone from src (channelState.ts, makeChannelReducer, useReducer, copyStateFromChannelOnEvent, useCreateChannelStateContext, and the ChannelStateContext / ChannelActionContext layers). Rewrite the stale sections: - Context Layers: drop ChannelStateContext / ChannelActionContext; add ChannelInstanceContext + useChannel() / useMessagePaginator(); note the removed context/hook builders. - State Management: no reducer; Channel holds only UI flags (isBootstrapping / bootstrapError); message state lives on the LLC paginators, consumed via useStateStore (useSyncExternalStore). - Optimistic Updates: handled by the LLC (channel.sendMessage -> messagePaginator.ingestItem), not React state; conflict resolution is in the paginator. - WebSocket Event Processing: no throttled copyStateFromChannelOnEvent; handleEvent does side effects only; re-renders come from StateStore subscriptions. - Performance: memoization via useStateStore selectors + areMessageUIPropsEqual; the old throttles and string-serialization memoization are gone. - Module Boundaries: update the coupling/risk notes accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…3244) ### 🎯 Goal Unify how the Avatar/AvatarStack information is being constructed through the common and replaceable utility `extractDisplayInfo` function. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an `initials` prop override for avatars. * Introduced a context-overridable display-info extractor to customize avatar rendering across messages, threads, polls, reactions, search results, typing indicators, and channel/member/pinned views. * **Bug Fixes** * Improved consistency for avatar display data by trimming usernames and using the trimmed name for avatar `alt` text, with the explicit `initials` override taking priority. * **Tests** * Updated component-context mocks to support the new context-driven avatar customization. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## [14.10.0](v14.9.0...v14.10.0) (2026-07-22) ### Features * introduce extractDisplayInfo for Avatar/AvatarStack components ([#3244](#3244)) ([1068e79](1068e79))
…ws based on message paginator
Reconcile PR #3245 (unread indicators) onto feat/message-paginator-master-merge and fix duplicate mark-read on channel open. Channel.tsx: - useMarkRead is now the sole mark-read owner on open. Removed the redundant mount-time markChannelRead and the markReadOnMount prop; a second, unthrottled mark-read used to fire alongside useMarkRead (up to 4 /read requests per open under StrictMode, 2 in production) — now a single request. - Guard seedUnreadSnapshot() so it does not run when the channel is already flagged unread (firstUnreadMessageId set); re-seeding would clear a deliberate "mark as unread" on reopen. useMarkRead.ts: - shouldMarkRead now gates on messagePaginator.isViewingLive (tab foregrounded AND scrolled to the bottom AND no newer messages beyond the loaded window) for the active collection. Adds the "not caught up while newer messages exist" guard and removes the dead scrolled-back-to-bottom tracking. MessageList.tsx / VirtualizedMessageList.tsx: - Wire hasMoreNewer into useMarkRead (the non-superseded half of PR #3245's message-list changes; the focus-signal hunks were dropped — the branch already implements message-focus clearing). UnreadMessagesNotification.tsx: - clearUnreadSnapshot() on the mark-read button. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… floating above it
Reconcile release-v15 (OpenAPI-era master, incl. the a11y overhaul) with the message-paginator architecture. Conflicts resolved to keep our paginator/MessageComposer/workspace-navigation model while adopting release-v15's improvements, adapted where the APIs diverged: - a11y: AriaLive announcements via Chat's shared outlet (no per-list AriaLiveRegion); ChannelList keyboard-nav listbox, now per-list on each scroll container; composed accessible labels + interaction announcements for channel/thread rows; ChatView navigation-landmark model. - TypingIndicator ported to the state-store layer and wired into MessageList/VirtualizedMessageList (isMessageListScrolledToBottom/scrollToBottom). - extractDisplayInfo/AvatarStack, doUploadRequest capability, exposed internal contexts. - ChatView context: dropped the redundant activeChatView alias in favour of activeView. Known-pending (tracked separately): 211 OpenAPI Event-union type adaptations and the mock-builder _setupConnection breakage. Committed with --no-verify. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## release-v15 #3237 +/- ##
==============================================
Coverage ? 83.90%
==============================================
Files ? 523
Lines ? 15905
Branches ? 5050
==============================================
Hits ? 13345
Misses ? 2560
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on
GetStream/stream-chat-js#1795
Summary
This PR is a major architecture migration, not just message pagination.
It moves chat/thread runtime behavior from React-owned channel contexts to instance APIs in
stream-chat-js, introduces a slot-based ChatView layout controller, and rewires navigation/state to reactiveStateStore-driven sources (messagePaginator,configState,threads.state, etc.).Scope
ChannelActionContextandChannelStateContextruntime usage with instance APIs fromstream-chat-js.messagePaginatorand client instance APIs.configState.requestHandlers.What Changed
1) New ChatView Layout Control API
LayoutControllerstate model for slot topology, bindings, visibility, and per-slot history.ChatViewNavigationAPI:openView(view, { slot? })openChannel(channel, { slot? })closeChannel({ slot? })openThread(threadOrTarget, { slot? })closeThread({ slot? })hideChannelList({ slot? })unhideChannelList({ slot? })ChannelSlotThreadSlotChannelListSlotThreadListSlotuseSlotEntity,useSlotChannel,useSlotThreadserializeLayoutStaterestoreLayoutStatelayoutSlotResolversfor deterministic slot targeting.2) Channel/Thread Ownership Moved to stream-chat-js Instances
messagePaginatorand thread manager state.StateStore.useChatViewNavigation()(with legacy fallback deactivation inThread).3) Context Removal and Replacement
ChannelActionContextChannelStateContextTypingContextprovider path from Channel runtimeChannelInstanceContext+useChannel()as the channel resolution contract.useChannel()resolves from:ChannelInstanceContext4) Message Pagination + Unread/Focus Migration
useMessagePaginator()messagePaginator.jumpToMessage(...)messagePaginator.jumpToTheFirstUnreadMessage(...)messagePaginator.jumpToTheLatestMessage()messagePaginator.toHead()/toTail()messagePaginator.ingestItem(...)messagePaginator.removeItem(...)messagePaginator.unreadStateSnapshotclient.messageDeliveryReporterinstead of context actions.5) Request Handler Customization Moved to Instance Config
channel.configState.requestHandlersthread.configState.requestHandlersAPI Changes and Migration Guide
Navigation:
setActiveChannel/context actions -> ChatView navigationMessage jump/pagination: context methods -> paginator methods
Channel access: ChannelState/Action context -> useChannel()
Slot-based rendering (new recommended pattern)
Behavioral Notes
Testing
Breaking/Important for Integrators
🎨 UI Changes
No planned UI changes