You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0100d98
Browse filesBrowse the repository at this point in the historyBrowse files
refactor!: call Channel.watch(), which replaces ensureWatched() in stream-chat (#3346)
BREAKING CHANGE: channel.watch() resolves with the channel instance to use (the channel, or the instance that superseded it), not the server response: read channel.data, channel.state and channel.messagePaginator instead.
- channel.watch() sends no query for a channel already watched and loaded unless it asks for options the current watch was not sent with, so it no longer refreshes one: refresh with channel.reload(), load other messages through channel.messagePaginator.
- A channel.watch() while another with the same options is in flight joins it instead of sending a request.
Copy file name to clipboardExpand all lines: AGENTS.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,7 +123,7 @@ Each is a `StateStore`. Components read them with `useStateStore(store, selector
123
123
└─ <MessageComposer>
124
124
```
125
125
126
-
`Channel` takes a single `channel` prop (`src/components/Channel/Channel.tsx`). It activates the channel on mount, deactivates it on unmount, seeds the paginator's unread snapshot, and re-queries on `user.deleted` — nothing else. It does not query the channel for you: initialize it first (`channel.ensureWatched()` sends one watch for overlapping calls, and none for a channel already watched). There is no `Window` component in v15; compose layout yourself or through `ChatView` slots.
126
+
`Channel` takes a single `channel` prop (`src/components/Channel/Channel.tsx`). It activates the channel on mount, deactivates it on unmount, seeds the paginator's unread snapshot, and re-queries on `user.deleted` — nothing else. It does not query the channel for you: initialize it first (`channel.watch()` sends one watch for overlapping calls, and none for a channel already watched and loaded). There is no `Window` component in v15; compose layout yourself or through `ChatView` slots.
127
127
128
128
Read the bound channel with `useChannel()` (`src/context/useChannel.ts`, thread's channel first, then the `Channel` subtree's) and the active message list with `useMessagePaginator()` (`src/hooks/useMessagePaginator.ts`, thread first, then channel). `useMessagePaginator()` is also exported from the package root, so integrator-facing docs and examples can use it too.
129
129
@@ -282,7 +282,7 @@ const {
282
282
// Manual setup when you need control over the API responses
Copy file name to clipboardExpand all lines: ai-docs/v15-breaking-changes.md
+12-17Lines changed: 12 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -842,7 +842,7 @@ A threads view is declared the same way (a `{ id: 'threads', slots: [...] }` lay
842
842
- Without `ChatView`: hold the open channel in your own state and provide `WorkspaceNavigationProvider` (main entry) with an object built from `defaultWorkspaceNavigation`, overriding at least `openChannel`, `isChannelActive` and `openChannels` (and `openThread` / `openThreads` / `isThreadActive` if you render threads). Alternatively pass `onSelect` to `ChannelListItem` / search result items.
843
843
- Reading "the active channel": inside the channel subtree use `useChannel()`; elsewhere `useWorkspaceNavigation().openChannels` (main entry) or `useSlotChannel({ slot })` (`slot-layout`).
844
844
- Opening a channel programmatically: `useWorkspaceNavigation().openChannel(channel)`; to also list it without a re-query, `client.channelManager.ingestChannel(channel)` (stream-chat).
845
-
- The `watchers` argument: query the channel yourself (`channel.ensureWatched({ watchers: { limit } })` or `channel.query(...)`, stream-chat) before opening it.
845
+
- The `watchers` argument: query the channel yourself (`channel.watch({ watchers: { limit } })` or `channel.query(...)`, stream-chat) before opening it.
- Replacement: initialize the channel before handing it to `Channel`. App code that already calls `await channel.watch(options)` on a channel created by id needs no change (`client.channel()` and `channel.watch()` keep their roles; `client.channel()` is shorthand for `client.channelManager.ensure({ type, id, data })`). A members-only channel (`client.channel(type, { members })`) must be rendered from the instance `ensureWatched()` resolves with: the created instance can be superseded by a stored instance for the server-assigned cid (`supersededBy`, `watchStatus: NotWatching`, no events). Code that relied on `Channel` to watch adds the call: `channel.watch(options)`, or `await channel.ensureWatched(options)` (stream-chat; sends nothing for an already-watched channel and joins an in-flight watch with the same options). Channels delivered by `ChannelList` arrive watched. v10 also changed the input shape (`members` as `{ user_id }` objects, custom fields under `custom`); that part is a type change only.
1163
+
- Replacement: initialize the channel before handing it to `Channel`. App code that already calls `await channel.watch(options)` on a channel created by id needs no change (`client.channel()` and `channel.watch()` keep their roles; `client.channel()` is the public way to get a channel; it calls the internal `channelManager.ensure()`). A members-only channel (`client.channel(type, { members })`) must be rendered from the instance `watch()` resolves with: the created instance can be superseded by a stored instance for the server-assigned cid (`supersededBy`, `watchStatus: NotWatching`, no events). Code that relied on `Channel` to watch adds the call: `await channel.watch(options)` (stream-chat; sends nothing for a channel alreadywatched and loaded and joins an in-flight watch with the same options). Channels delivered by `ChannelList` arrive watched. v10 also changed the input shape (`members` as `{ user_id }` objects, custom fields under `custom`); that part is a type change only.
-`master:src/components/Channel/Channel.tsx:17-23` (prop doc: "Initialize it before passing it in; `Channel` does not query"); `master:src/utils/getChannel.ts` removed
- stream-chat v10 queries channel results (and the channels message search fetches) with `watch: false`. The SDK result items watch on open (`ensureWatched()`, or `jumpToMessage(id, { watchChannel: true })` for messages). A custom search result component that only opened the channel now opens an unwatched channel (no events, possibly empty).
1931
+
- stream-chat v10 queries channel results (and the channels message search fetches) with `watch: false`. The SDK result items watch on open (`watch()`, or `jumpToMessage(id, { watchChannel: true })` for messages). A custom search result component that only opened the channel now opens an unwatched channel (no events, possibly empty).
1937
1932
- default result items call `openChannel` (workspace navigation: no-op outside `ChatView`, BC-013) and `client.channelManager.ingestChannel(channel)` instead of `setActiveChannel` + `ChannelListContext.setChannels`.
1938
1933
- selecting a message result jumps with `channel.messagePaginator.jumpToMessage(...)`; `Channel` no longer performs the jump (BC-027). The "jumped here" marker reads `messagePaginator.messageFocusSignal`, not `SearchController._internalState.focusedMessage`.
- Replacement: in a custom result component, call `channel.ensureWatched()` (or `jumpToMessage(id, { watchChannel: true })`) when opening; open via `useWorkspaceNavigation().openChannel(channel, { event })`. The default items gained an optional `onSelect` prop that replaces their selection handler.
1936
+
- Replacement: in a custom result component, call `channel.watch()` (or `jumpToMessage(id, { watchChannel: true })`) when opening; open via `useWorkspaceNavigation().openChannel(channel, { event })`. The default items gained an optional `onSelect` prop that replaces their selection handler.
- commit: `a41eed56f` (PR #3310; "BREAKING CHANGE: channel search results ... are no longer watched; a custom search result component watches the channel when it is opened"); `088c795c1` (PR #3286)
-`<ChannelActionProvider><ChannelStateProvider><Message … /></…></…>`, or `<Message>` with no channel context
2592
2587
- implicit `highlighted` from `useChannelStateContext().highlightedMessageId`
2593
-
- Replacement: wrap it in `<ChannelInstanceProvider value={{ channel }}>` (any real `stream-chat``Channel`, e.g. `client.channelManager.ensure({ id, type })`), or render it inside `<Channel channel={…}>` / `<Thread thread={…}>`. Pass `highlighted` explicitly when needed (`MessageProps.highlighted?: boolean`).
2588
+
- Replacement: wrap it in `<ChannelInstanceProvider value={{ channel }}>` (any real `stream-chat``Channel`, e.g. `client.channel(type, id)`), or render it inside `<Channel channel={…}>` / `<Thread thread={…}>`. Pass `highlighted` explicitly when needed (`MessageProps.highlighted?: boolean`).
2594
2589
- Evidence:
2595
2590
-`master:src/context/useChannel.ts` throws when neither a thread nor `ChannelInstanceContext` supplies a channel
2596
2591
-`master:src/components/Message/hooks/useOpenThreadHandler.ts:16` and `master:src/components/Message/hooks/useRetryHandler.ts:11` call `useChannel()` during every `Message` render
Copy file name to clipboardExpand all lines: examples/ai-chatbot/implementation.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -344,7 +344,7 @@ examples/ai-chatbot/
344
344
345
345
### 18. **useSendAIMessage.ts**
346
346
347
-
- The send path shared by `MessageInputBar` and voice mode: creates a new conversation with `channel.ensureWatched()`, starts the AI agent when it is not watching yet, sends through `composer.send()` (with attachments), records the message against the rate limit and summarizes a new conversation in the background (the summary never delays or fails the send)
347
+
- The send path shared by `MessageInputBar` and voice mode: creates a new conversation with `channel.watch()`, starts the AI agent when it is not watching yet, sends through `composer.send()` (with attachments), records the message against the rate limit and summarizes a new conversation in the background (the summary never delays or fails the send)
348
348
- Also holds `availableModels`, `defaultPlatformModel` and `isWatchedByAI`
0 commit comments