Repository navigation
Conversation
…5.0.0-rc.3 - stream-chat-react 15.0.0-rc.3, stream-chat 10.0.0-rc.26 - Node 22 in .nvmrc and the deploy workflow (stream-chat 10 requires >=22.18) - social-messenger-ts: ChatView slots, ChannelPaginator, workspace navigation - team-ts: app-owned WorkspaceNavigationProvider, paginator-driven channel lists - v15-migration-log.md: gaps found in the v15 / v10 migration guides
oliverlaz
added a commit
to GetStream/stream-chat-react
that referenced
this pull request
Oct 29, 2026
…3356) ## Goal Ticket: https://linear.app/stream/issue/REACT-1162 We migrated two demo apps from v14 to `15.0.0-rc.3` (`stream-chat@10.0.0-rc.26`) using only `ai-docs/ai-migration-v14-v15.md` and the stream-chat-js `v10-breaking-changes.md`, and logged every place the guides fell short. The findings and the migrated code are in GetStream/website-react-examples#138. Every compile error had an answer in the guides; the gaps are UI states that compile but behave differently, mostly because `ChatView` unmounts the inactive view, plus a few type-level holes. This PR fixes them in the guide. Docs only, and it describes the current rc API. ## Implementation details Each claim was checked against the source in this repo, and every new or changed snippet compiles against the installed `stream-chat-react@15.0.0-rc.3` / `stream-chat@10.0.0-rc.26` (strict, `noImplicitReturns`, `noUnusedLocals`). - **Section 3:** says the inactive `ChatView` view unmounts. Only the slot bindings survive; state, refs and effects inside a view start over on every switch. - **Section 6, `useOpenFirstChannel`:** the `useRef` guard reset on remount, so returning from the threads view re-opened the first channel over the one the user had open. The hook now guards on `useWorkspaceNavigation().openChannels.length === 0`. It also notes where to call it (the channels view, not an always-rendered `ChatView` child, where `openChannels` is empty in the threads view) and that it re-opens when nothing is open. - **Section 6, paginator example:** the paginator is created and registered once, above `ChatView` (`useChannelPaginator`), so it is not re-created and re-queried on every view switch. - **Section 4, "Without ChatView":** the override list is split into always / threads / default headers. It adds `isThreadDismissable` (the default `ThreadHeader` close button needs it, and its default is `() => false`), `isChannelDismissable` with `closeChannel`, and `canGoBack` with `goBack`. The example now overrides `isThreadDismissable`. - **Section 5:** a concrete stale-state example (`useState(channel.data?.custom?.name)` keeps the previous channel name) and its fix. - **Section 9:** reading `event.user` from the `typing` slice behind an `EventPayload<'typing.start'>` type guard (`Event` is a union, so the unguarded read fails with `TS2339`), plus a note that the guard can go if `stream-chat` narrows the slice type. - **Section 19:** a ready-to-run grep for the removed classes over `*.css` / `*.scss` / `*.sass` / `*.less`, which also matches them inside combinators (e.g. `.x + .str-chat__main-panel`) and skips `.str-chat__main-panel-inner` and `.str-chat__thread-container`, which still exist. - **Silent-break table:** new rows for the channel resetting after a view switch, the missing thread close button without `ChatView`, and state seeded from the channel going stale; the CSS row now points at the grep. - **Smaller fixes:** - Sections 7 and 10: warn that TypeScript's "Did you mean `ThreadHead`?" for a stale `ThreadHeader` key points at the parent-message slot. - Section 7: `useCloseThread` takes a `WorkspaceNavigationTriggerEvent`, narrower than v14's `BaseSyntheticEvent`. - Section 10: opens with "if your custom message UI calls `getMessageActions()`" so those apps know to switch to `useUserRole`. - Section 13: new subsection on `setMessageComposerSetupFunction` being deprecated in favour of `client.config.setSetupFunction('messageComposer', ...)`. - Section 18: the flow "string not in the key map, so app-owned, so `asDynamicKey`". - Section 6: a custom `ChannelListItemUI` receives the computed `active` prop. - Section 1: reads the `stream-chat` peer range from the installed `package.json` instead of a hard-coded rc, and lists the `stream-chat` type changes that are usually the first errors (`ChannelSort` to `SortParamRequest[]`, `queryChannels` raw vs `queryChannelsAndHydrate`, `queryUsers({ payload })`). - **Links:** the three links to stream-chat-js `master/ai-docs/v10-breaking-changes.md` returned 404, because the file lives on `release-v10` (GetStream/stream-chat-js#1919 merged there). They now point at `release-v10` and use that guide's explicit anchors. ## UI Changes None, documentation only. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Documentation** * Updated the v14-to-v15 migration guide with guidance on channel state during view changes and workspace navigation, thread-header dismissal, and custom channel-list setup. * Revised examples for pagination and channel opening, and clarified compatibility guidance, typing-event handling, CSS search, and references to earlier migration documentation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
…ct 15.0.0-rc.3 - stream-chat-react 15.0.0-rc.3, stream-chat 10.0.0-rc.26 - gaming-livestream: app-owned channel and thread state with WorkspaceNavigationProvider, thread shown in place of the channel, command notifications via a sendMessageRequest handler - virtual-event: ChannelWithThread per channel surface, paginator-driven DM list, v10 custom data, moderation, partial update and timestamp APIs - v15-migration-log.md: round 2 gaps found in the v15 / v10 migration guides
oliverlaz
added a commit
to GetStream/stream-chat-react
that referenced
this pull request
Oct 29, 2026
…rame (#3357) Ticket: https://linear.app/stream/issue/REACT-1469 ### Goal Every page load of a v15 app whose channel list grows with its content reports `ResizeObserver loop completed with undelivered notifications`. Under CRA / webpack-dev-server this becomes a full-screen "Uncaught runtime errors" overlay that blocks clicks. It was found while migrating the team-ts and social-messenger-ts demos in website-react-examples to 15.0.0-rc.3 (GetStream/website-react-examples#138), and does not happen on v14. ### Root cause `InfiniteScrollPaginator` observes its root with a ResizeObserver and checks the distance to the edges on every resize. #3342 changed that check from a trailing `debounce` (always async) to a leading `throttle`, so the observer's first callback now calls `loadNextOnScrollToBottom` synchronously. The page load updates a `StateStore`, and the `useSyncExternalStore` subscription renders synchronously in the callback's microtasks. When the root is sized by its content (team-ts's channel lists are), the root grows within the same ResizeObserver delivery. The browser cannot deliver that resize in the same frame and reports the loop error. ### How it was isolated I ran a copy of team-ts against the rc.3 build with `window.ResizeObserver` wrapped from a module imported first. The wrapper recorded every callback's targets per animation frame and which observed elements changed size during the callback and its microtasks. The error appeared on 2 of 2 loads. Only the paginator's callback ever resized an observed element: the channel list root went from 240x111 to 240x132 within its own callback, and the next frame delivered 240x132. The `MessageList` relayout observer, `useFloatingDateSeparatorMessageList` and `useScrollLocationLogic` never resized an observed element. ### Implementation details - The observer callback now schedules the check with `requestAnimationFrame`, at most once per frame, and the frame is cancelled on unmount. The resize the loaded page causes is then observed in the following frame instead of within the current delivery. - Scroll-triggered checks are unchanged and still run immediately. - New tests in `InfiniteScrollPaginator.test.tsx` cover: no check inside the observer callback (the check runs in the next frame), one check for several resizes in a frame, and a pending check dropped when the observer is replaced. Each fails when the code it covers is removed (the deferral, the per-frame guard, the cancel in the cleanup). Verified: with a local build of this branch in the same team-ts copy, there was no loop error on 5 of 5 loads, and no observer callback resized an observed element. `yarn lint`, `tsc -p tsconfig.lib.json --noEmit` and `yarn test` (3,300 tests) pass. Related: REACT-1439 (a content-height `ChannelList` loads every page on mount). This PR does not change that behavior; it only moves the load out of the observer callback. ### UI Changes None visible, apart from the dev-server error overlay no longer appearing. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Bug Fixes** * Improved infinite-scroll behavior when content is resized: edge checks now run on the next frame, and repeated resize events within that frame trigger only one check. * Pending checks are discarded when the observer configuration changes or the component is cleaned up. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This branch has not been deployed
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.
Upgrades the four TypeScript demo apps from stream-chat-react 14 to the v15 release candidate. The aim is to try the v15 / stream-chat v10 migration guides on real apps.
Changes
stream-chat-react@15.0.0-rc.3andstream-chat@10.0.0-rc.26in all four apps.stream-chat10 requires>=22.18, sosocial-messenger-ts/.nvmrcanddeploy.ymlmove to Node 22.ChatViewfromstream-chat-react/slot-layout, withviews,ChannelSlot/ThreadSlotand a thread slot renderer.ChannelPaginator, created once aboveChatViewso switching views doesn't re-query it. The first channel opens on load only when nothing is open.useChannel/useStateStore, andcustom.name. The thread header usesuseCloseThread.str-chat__main-panelto the slot selectors.ChatView. The active channel and thread now live in the existingWorkspaceController, which providesWorkspaceNavigationProvider.ChannelListUIis replaced by a wrapper around<ChannelList>.<Channel>, and.channel__containeris now a flex row.getInstanceconfig,queryChannelsAndHydrate,queryUsers({ payload })andaddMembers({ members }).WorkspaceNavigationProvider..str-chat__main-panelDOM toggle; it is now an app-owned wrapper, hidden while a thread is open./ban,/mute, … notifications moved fromoverrideSubmitHandlerto asendMessageRequesthandler.color,userRole) moved undercustom; timestamps go throughconvertTimestampToDate.ChannelWithThreadgives the event chat and the DM view each its own open thread. The thread replaces the channel in place, and switching channels drops it.ChannelPaginatorwith the list slots anduseChannelPaginatorStatefor errors.useMessagePaginator, workspace navigation for "Show in thread" (the parent now comes fromclient.getMessage), and Q&A upvotes viaupdateMessagePartial.custom,client.moderation.*,queryUsers({ payload })and members as{ user_id }.v15-migration-log.md: a log of where the migration guides fell short, in two rounds (one per pair of apps).Testing
tscandCI=true yarn buildpass for all four apps.master:messagingchannel:gaming:gaming-demodoesn't exist on staging and the test user can't create it.Notes for reviewers
client.moderation.mute/unmuteUser/flagUser) return 403 "this endpoint needs a feature flag". Production needs that flag enabled before this ships. The app's modal still reports success, as it did on v14 when a call failed.ResizeObserver loop completed with undelivered notificationsoverlay on load in social-messenger-ts and team-ts; v14 doesn't. It's dev-only and an SDK issue. Details are in the log.