diff --git a/ai-docs/ai-migration-v14-v15.md b/ai-docs/ai-migration-v14-v15.md index f7f3508ce..235508e66 100644 --- a/ai-docs/ai-migration-v14-v15.md +++ b/ai-docs/ai-migration-v14-v15.md @@ -266,6 +266,7 @@ Old → new for the most common changes. Ctrl-F the v14 name; the section has th | `client.setMessageComposerSetupFunction(fn)` | `client.config.setSetupFunction('messageComposer', fn)` | [13](#setmessagecomposersetupfunction-is-deprecated) | | `new Date(message.created_at)`, `dayjs(created_at)` | `convertTimestampToDate(created_at)` from `stream-chat` (may return `undefined`) | [16](#16-dates-on-response-types-are-unix-nanosecond-numbers) | | `channel.data?.name` / `.image` | `channel.data?.custom?.name` / `.image` | [17](#17-other-stream-chat-v10-data-shapes) | +| `channel.sendMessage({ text, priority })`, `message.priority`, `priority` set in `doSendMessageRequest` | `channel.sendMessage({ message: { text, custom: { priority } } })`; read `message.custom?.priority`; augment `CustomMessageData` | [17](#17-other-stream-chat-v10-data-shapes) | | `handleDelete({ deleteForMe, hardDelete })` | `handleDelete({ delete_for_me, hard })` | [17](#17-other-stream-chat-v10-data-shapes) | | `DefaultCommandData` import, `declare module 'stream-chat' { interface CustomCommandData … }` | Delete both; `Command['name']` is `string` | [17](#17-other-stream-chat-v10-data-shapes) | | `client.flagMessage(id)` / `channel.addMembers(ids)` / `client.getThread(id, options)` | `client.moderation.flagMessage({ message_id })` / `channel.addMembers({ members: ids })` / `client.getThreadAndHydrate({ message_id }, { watch: true })` | [17](#17-other-stream-chat-v10-data-shapes) | @@ -291,6 +292,7 @@ These compile cleanly, or are ignored in plain JS, and change behavior at runtim | A thread renders below the channel instead of beside it, or a panel collapses to a narrow column | The channel no longer contains a flex row, and `ChatView` slots are `flex: 1 1 0` siblings | Make your container a row; size panels by slot ([section 19](#panel-layout)) | ``, the channel list or thread list fills the view, the channel or thread beside it is not visible and the page scrolls horizontally | `--str-chat__channel-list-width` and `--str-chat__thread-list-width` default to `100%`, and the lists do not shrink | Set both widths on the `ChatView` root ([section 19](#panel-layout)) | `views=` with `ChannelNavigation` / `ChannelList` / `ThreadList`, and no `--str-chat__channel-list-width` (`styles`) | | A channel name or image renders empty | `name` / `image` are custom data in `stream-chat` v10: `channel.data.custom.name` | Read `custom` ([section 17](#17-other-stream-chat-v10-data-shapes)) | `.data?.name`, `.data.name`, `.data?.image` | +| A field of the app's own reads `undefined` on a message, user or member, or a field set on an outgoing message is not where the app reads it back | Custom fields are under `custom`, on reads and writes. TypeScript rejects a top-level field only in an inline object literal | Read and write them under `custom` ([section 17](#17-other-stream-chat-v10-data-shapes)); `updateUsersPartial` and the other partial updates keep flat keys in `set` / `unset` | Reads and writes of the app's own fields; `sendMessage(`; `sendMessageRequest`, `updateMessageRequest` | | A held channel throws "pending disposal" after logout or a user switch | `disconnectUser()` disposes the user's channels | Drop held channels on disconnect ([section 4](#without-chatview)) | `disconnectUser`, `useState`. - `MessageSearchResultItem` / `ChannelByMessageSearchResultItemProps.item`: `MessageResponse & { channel?: ChannelResponse }`. +- **Your own fields are custom data on every object.** In `stream-chat` v10 the fields an app adds to a message, user, member, reaction, attachment or event live in that object's `custom`, not at the top level, both in what the server returns and in what the app sends. Read `message.custom?.priority`, not `message.priority`. Send them wrapped in the request's `message`: `channel.sendMessage({ message: { text, custom: { priority } } })` (`stream-chat` v9's `channel.sendMessage({ text })` no longer takes the message at the top level), and in a send handler as `{ ...params, message: { ...params.message, custom: { ...params.message?.custom, priority } } }` ([section 14](#14-request-handlers)). A retry resends the payload cached before any handler changed it, through `retrySendMessageRequest` when one is registered, so set the field in that handler too, or set it on the message before sending. Type the fields by augmenting `CustomMessageData` (and the other `Custom*Data` interfaces), not by widening `MessageRequest` or `LocalMessage`. Filters on them use `'custom.'`. `updateUsersPartial` and the other partial updates keep the flat shape. The full rules are under [Custom data moves under `custom`](https://github.com/GetStream/stream-chat-js/blob/release-v10/ai-docs/v10-breaking-changes.md#custom-data) in stream-chat-js. + **Messages:** - **Reaction sort:** `reactionDetailsSort` (on `Message`, `MessageList`, `VirtualizedMessageList`, `MessageContext`, `MessageReactions`, `MessageReactionsDetail`, `VirtuosoContext`) and the `sort` argument of `handleFetchReactions` / `useReactionsFetcher`: `ReactionSort` → `SortParamRequest[]`. `MessageReactionsDetail.sort` is removed; use `reactionDetailsSort` ([section 12](#messagereactionsreverse-and-messagereactionsdetailsort--dialogid-are-removed)) (`[{ field: 'created_at', direction: -1 }]`).