# Upgrading to v8

## Changes in Message Composition

Message composition is now managed by `MessageComposer` instances. Each composition context has its own composer:

- `channel` - for main channel list message composition
- `thread` - for message composition in Thread view
- `legacy_thread` - for message composition in thread open next to the main channel list
- `message` - for editing a message in any message list

Get the composer via `useMessageComposer`.

`MessageComposer` introduces breaking changes described below.

The following hooks are introduced to access the `MessageComposer` state and methods:

- `useMessageComposer` - to access the `MessageComposer` instance.
- `useAttachmentManagerState` - to access the `AttachmentManager` state of the `MessageComposer`.
- `useMessageComposerHasSendableData` - to access the `hasSendable` data of the `MessageComposer` which determines whether the composed message is valid.
- `useCanCreatePoll` - to check if the user can create a poll in the current composition.
- `useAudioPreviewManager` - to manage audio play, pause and progress state of the audio upload files.

## Context Changes

### MessageInputContext Changes

Due to the usage of the new message composer, the following values are removed:

**1. Context Values Removed**

| Prop                            | Replacement                                                                                                                                                                                                                                                                     |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `uploadNewImage`                | Use `uploadNewFile` method from `useMessageInputContext` instead.                                                                                                                                                                                                               |
| `uploadFile`                    | Use `uploadNewFile` method from `useMessageInputContext` instead.                                                                                                                                                                                                               |
| `uploadImage`                   | Use `uploadNewFile` method from `useMessageInputContext` instead.                                                                                                                                                                                                               |
| `appendText`                    | Use `MessageComposer.textComposer.handleChange` instead.                                                                                                                                                                                                                        |
| `fileUploads`                   | Use `attachments` state from `MessageComposer.attachmentManager` instead. You can also get it from `useAttachmentManagerState`.                                                                                                                                                 |
| `imageUploads`                  | Use `attachments` state from `MessageComposer.attachmentManager` instead. You can also get it from `useAttachmentManagerState`.                                                                                                                                                 |
| `setFileUploads`                | We manage the state in the message composer instead. You can add a attachment using `MessageComposer.attachmentManager.upsertAttachment` method.                                                                                                                                |
| `setImageUploads`               | We manage the state in the message composer instead. You can add a attachment using `MessageComposer.attachmentManager.upsertAttachment` method.                                                                                                                                |
| `text`                          | Use `text` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                                               |
| `setText`                       | Use `MessageComposer.textComposer.handleChange` instead.                                                                                                                                                                                                                        |
| `showMoreOptions`               | This is handled locally within the `InputButtons` component so the need of the state is gone.                                                                                                                                                                                   |
| `setShowMoreOptions`            | This is handled locally within the `InputButtons` component so the need of the state setter is gone.                                                                                                                                                                            |
| `removeFile`                    | Use `MessageComposer.attachmentManager.removeAttachments` method. Pass the ids of the attachments you want to remove. The id is accessible from `attachment.localMetadata.id`.                                                                                                  |
| `removeImage`                   | Use `MessageComposer.attachmentManager.removeAttachments` method. Pass the ids of the attachments you want to remove. The id is accessible from `attachment.localMetadata.id`.                                                                                                  |
| `sendMessageAsync`              | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `isValidMessage`                | This is determined through the `hasSendable` data returned from the `MessageComposer.hasSendableData`. Alternatively, this can be accessed from the `useMessageComposerHasSendableData` hook.                                                                                   |
| `updateMessage`                 | This method was simply not used anywhere was a redundant export. If you were using it you can use `client.updateMessage` instead.                                                                                                                                               |
| `sendThreadMessageInChannel`    | This is deteremined and handled using the `showReplyInChannel` state of the `MessageComposer` state.                                                                                                                                                                            |
| `setSendThreadMessageInChannel` | This can be set using the `MessageComposer.toggleShowReplyInChannel()` function.                                                                                                                                                                                                |
| `numberOfUploads`               | This can be determined using the `attachments.length` or for a detailed count you can rely on `successfulUploadsCount`, `failedUploadsCount` or `failedUploadsCount` state from `MessageComposer.attachmentManager`. You can also get it from `useAttachmentManagerState`.      |
| `setNumberOfUploads`            | We manage the state of the attachments upload in the composer itself so this isn't needed.                                                                                                                                                                                      |
| `mentionedUsers`                | Use `mentionedUsers` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                                     |
| `setMentionedUsers`             | This is set within the `TextComposer` of the `MessageComposer` so this isn't needed anymore.                                                                                                                                                                                    |
| `giphyActive`                   | Determined by the `command` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                              |
| `setGiphyActive`                | This is set within the `TextComposer` of the `MessageComposer` so this isn't needed anymore.                                                                                                                                                                                    |
| `openFilePicker`                | We have `pickFile` exposed from the `useMessageInputContext` so there is not point of exporting same function using different name. Use `pickFile` instead.                                                                                                                     |
| `openCommandsPicker`            | Use `MessageComposer.textComposer.handleChange` instead with text as `/` and selection as `{ end: 1, start: 1 }`. Check [this](#commandsbutton).                                                                                                                                |
| `asyncIds`                      | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `asyncUploads`                  | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `giphyEnabled`                  | This is removed in favour of new way to add support for commands UI on message input. Refer [this](/chat/docs/sdk/react-native/v8/guides/handle-commands-ui/) guide.                                                                                                            |
| `onChange`                      | Use `MessageComposer.textComposer.handleChange` instead.                                                                                                                                                                                                                        |
| `onSelectItem`                  | Use `MessageComposer.textComposer.handleSelect` instead. Pass the selected item as a parameter to the function.                                                                                                                                                                 |
| `resetInput`                    | This was not needed as it is handled internally by the `sendMessage` method in the `MessageInputContext`. If you want to still clear the input use `messageComposer.clear()` instead and while editing message use `clearEditingState` from the `useMessageComposerAPIContext`. |
| `sending`                       | This was not needed in favour of the composer handling the message composer state.                                                                                                                                                                                              |
| `setAsyncIds`                   | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `setAsyncUploads`               | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `triggerSettings`               | The triggers in the message input are handled by the composer now. Both the searching of the suggestions and selecting them are a part of composer so we don't need it.                                                                                                         |

**2. Context value changed**

`sendMessage` no longer accepts `customMessageData`. Use middleware ([guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer-middleware/)) or set data directly:

```ts
messageComposer.customDataManager.setMessageData({ a: "b" });
```

### Removed `SuggestionsContext`

`SuggestionsContext` is removed. Suggestions now live in `MessageComposer.textComposer` state and are accessed via `useMessageComposer`.

The text composer searches for suggestions based on input and trigger characters. See [text composition middleware](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer-middleware/#text-composition-middleware).

```tsx
import { SearchSourceState, TextComposerState } from "stream-chat";
import { useMessageComposer, useStateStore } from "stream-chat-react-native";

const textComposerStateSelector = (state: TextComposerState) => ({
  suggestions: state.suggestions,
  text: state.text,
});

const searchSourceStateSelector = (nextValue: SearchSourceState) => ({
  items: nextValue.items,
});

// Inside the component
const messageComposer = useMessageComposer();
const { textComposer } = messageComposer;
const { suggestions } = useStateStore(
  textComposer.state,
  textComposerStateSelector,
);
const { items } =
  useStateStore(suggestions?.searchSource.state, searchSourceStateSelector) ??
  {};
const trigger = suggestions?.trigger;
const queryText = suggestions?.query;
```

The autocomplete list opens/closes automatically based on suggestions.

Also, the following component props are part of the `MessageInputContext` now as a part of the refactor:

- AutoCompleteSuggestionList
- AutoCompleteSuggestionItem
- AutoCompleteSuggestionHeader

### Moved the `AttachmentPickerContext` down

The `AttachmentPickerContext` is now moved **down** to the `Channel` wrapper component from the previously `OverlayProvider` component.

This means you can access `useAttachmentPickerContext` from `Channel` children.

If you previously set `topInset` and `bottomInset` on `OverlayProvider`, you may not need them if your `Channel` wrapper is correct.

If you still need them, pass them to `Channel`:

```tsx
<Channel channel={channel} topInset={topInset} bottomInset={bottomInset} />
```

Or set them via `useAttachmentPickerContext` below `Channel` in the tree.

```tsx
import { useAttachmentPickerContext } from "stream-chat-react-native";

const { setTopInset, setBottomInset } = useAttachmentPickerContext();

// Use this in an effect or a component that is below the Channel component
setTopInset(10);
setBottomInset(10);
```

<admonition type="info">

If your attachment picker bottom sheet is not appearing correctly or covering the `AttachmentPickerSelectionBar`, when your `AttachmentPicker` is opened on this release, make sure to unset the value of `topInset` and `bottomInset` or adjust it as per your bottom inset.

</admonition>

The context **no longer** provides/contains the following values:

- `maxNumberOfFiles`
- `setMaxNumberOfFiles`
- `selectedFiles`
- `setSelectedFiles`
- `selectedImages`
- `setSelectedImages`

Uploads for selected files/images now happen through `MessageComposer.attachmentManager`.

Access selected files/images via `AttachmentManager.attachments`. Example:

```tsx
import { useAttachmentManagerState } from "stream-chat-react-native";

const { attachments } = useAttachmentManagerState();

const selected = attachments.some(
  (attachment) => attachment.localMetadata.previewUri === asset.uri,
);
```

The `maxNumberOfFiles` is governed through the global config of the `MessageComposer` which can be set as per [this guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods).

Set `maxNumberOfFilesPerMessage` in `MessageComposer` config:

```tsx
client.setMessageComposerSetupFunction(({ composer }) => {
  composer.updateConfig({
    attachments: {
      maxNumberOfFilesPerMessage: 5,
    },
  });
});
```

### Introduction of `MessageComposerAPIContext`

The `MessageComposerAPIContext` is introduced to provide/handle the quoted message state and the edited message state.

The context provides these helpers for quoted/edited state:

- `setEditingState` - The setter for the edited message state. Accepts a `LocalMessage` object.
- `clearEditingState` - The function to clear the edited message state.
- `setQuotedMessage` - The function to set the quoted message state. Accepts a `LocalMessage` object.

If you used `MessagesContext` before, use `MessageComposerAPIContext` now.

```ts
const { setEditingState, clearEditingState, setQuotedMessage } =
  useMessageComposerAPIContext();
```

To clear the quoted message state, you can use the message composer as follows:

```ts
import { useMessageComposer } from "stream-chat-react-native";
const messageComposer = useMessageComposer();

const onPressHandler = () => {
  messageComposer.setQuotedMessage(null);
};
```

## Component Changes

### Message Input Components Changes

The following `MessageInput` props changed:

#### MessageInput

These props are now passed from the wrapper (previously from context):

- `bottomInset`
- `selectedPicker`
- `attachmentPickerBottomSheetHeight`
- `attachmentSelectionBarHeight`

These props are removed from `MessageInput`:

| Prop                      | Replacement                                                                                                                                                                                                                                                                     |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `asyncIds`                | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `asyncUploads`            | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `clearEditingState`       | Not needed in the component. Use `clearEditingState` from `useMessageComposerAPIContext` if you still need it.                                                                                                                                                                  |
| `clearQuotedMessageState` | Use `MessageComposer.setQuotedMessage(null)` instead.                                                                                                                                                                                                                           |
| `fileUploads`             | Use `attachments` state from `MessageComposer.attachmentManager` instead. You can also get it from `useAttachmentManagerState`.                                                                                                                                                 |
| `giphyActive`             | Determined by the `command` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                              |
| `imageUploads`            | Use `attachments` state from `MessageComposer.attachmentManager` instead. You can also get it from `useAttachmentManagerState`.                                                                                                                                                 |
| `InputGiphySearch`        | This is changed to [`CommandInput`](#commandinput) component. Use it instead.                                                                                                                                                                                                   |
| `isValidMessage`          | This is determined through the `hasSendable` data returned from the `MessageComposer.hasSendableData`. Alternatively, this can be accessed from the `useMessageComposerHasSendableData` hook.                                                                                   |
| `maxNumberOfFiles`        | Use the `maxNumberOfFilesPerMessage` config of the `AttachmentManager` of the `MessageComposer` instead. Refer to [the documentation](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods) for more details.            |
| `mentionedUsers`          | Use `mentionedUsers` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                                     |
| `numberOfUploads`         | Use `attachments.length` or `successfulUploadsCount`/`failedUploadsCount` from `MessageComposer.attachmentManager`. You can also get it from `useAttachmentManagerState`.                                                                                                       |
| `quotedMessage`           | Use `MessageComposer.quotedMessage` state instead.                                                                                                                                                                                                                              |
| `resetInput`              | This was not needed as it is handled internally by the `sendMessage` method in the `MessageInputContext`. If you want to still clear the input use `messageComposer.clear()` instead and while editing message use `clearEditingState` from the `useMessageComposerAPIContext`. |
| `sending`                 | No longer needed; the composer manages sending state.                                                                                                                                                                                                                           |
| `sendMessageAsync`        | Removed in favor of `sendImageAsync` prop no longer supported.                                                                                                                                                                                                                  |
| `showMoreOptions`         | This is handled locally within the `InputButtons` component so the need of the state is gone.                                                                                                                                                                                   |
| `setShowMoreOptions`      | This is handled locally within the `InputButtons` component so the need of the state is gone.                                                                                                                                                                                   |
| `setGiphyActive`          | This is set within the `TextComposer` of the `MessageComposer` so this isn't needed anymore.                                                                                                                                                                                    |
| `removeFile`              | Use `MessageComposer.attachmentManager.removeAttachments` method. Pass the ids of the attachments you want to remove. The id is accessible from `attachment.localMetadata.id`.                                                                                                  |
| `removeImage`             | Use `MessageComposer.attachmentManager.removeAttachments` method. Pass the ids of the attachments you want to remove. The id is accessible from `attachment.localMetadata.id`.                                                                                                  |
| `text`                    | Use `text` state from the `MessageComposer.textComposer` instead.                                                                                                                                                                                                               |
| `uploadNewFile`           | Use `uploadNewFile` method from `useMessageInputContext` instead.                                                                                                                                                                                                               |
| `uploadNewImage`          | Use `uploadNewFile` method from `useMessageInputContext` instead.                                                                                                                                                                                                               |
| `suggestions`             | This is handled by the `suggestions` state of the `MessageComposer.textComposer` so this isn't needed anymore.                                                                                                                                                                  |
| `triggerType`             | This is handled by the `suggestions.trigger` state of the `MessageComposer.textComposer` so this isn't needed anymore.                                                                                                                                                          |

The `editing` prop is now `boolean`. `MessageInput` checks `messageComposer.editedMessage` and passes a boolean.

#### CommandsButton

The `suggestions` prop is removed. The `InputButtons` checks for the `command` state from the `TextComposer` under the `MessageComposer` and conditionally renders the `CommandsButton` if the `command` state is set.

The default `CommandsButton` opens the commands picker via:

```ts
const messageComposer = useMessageComposer();
const { textComposer } = messageComposer;

const handleOnPress = async () => {
  await textComposer.handleChange({
    selection: {
      end: 1,
      start: 1,
    },
    text: "/",
  });
};
```

#### InputButtons

The following props are **removed** from the `InputButtons` component:

| Prop                 | Replacement                                                                                                     |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
| `giphyActive`        | Use the `command` state from the `TextComposer` of the `MessageComposer` to determine if the command is active. |
| `hasText`            | Use the `text` state from the `TextComposer` of the `MessageComposer` to determine if there's text.             |
| `openCommandsPicker` | Check [this](#commandsbutton).                                                                                  |
| `setShowMoreOptions` | This is handled internally; the state is no longer used.                                                        |
| `showMoreOptions`    | This is handled internally; the state is no longer used.                                                        |

The `uploadFile` capability is now checked through a prop to the component that is passed through the `useOwnCapabilitiesContext` hook in the wrapper.

#### SendButton

The props that are **removed** from the `SendButton` component:

- `giphyActive` - Use the `command` state from the `TextComposer` of the `MessageComposer` to determine if the command is active.

#### ShowThreadMessageInChannelButton

The props that are **removed** from the `ShowThreadMessageInChannelButton` component:

| Prop                            | Replacement                                                                                   |
| ------------------------------- | --------------------------------------------------------------------------------------------- |
| `sendThreadMessageInChannel`    | This is determined and handled using the `showReplyInChannel` state of the `MessageComposer`. |
| `setSendThreadMessageInChannel` | This can be set using the `MessageComposer.toggleShowReplyInChannel()` function.              |

#### InputEditingStateHeader

The `resetInput` prop is **removed** as we handle it using the `messageComposer.restore()`. The `clearEditingState` prop now comes from the `MessageComposerAPIContext` context using the `useMessageComposerAPIContext` hook.

#### InputReplyStateHeader

The `clearQuotedMessageState` prop is **removed** as you can set the quoted message state directly as `messageComposer.setQuotedMessage(null)`.

```ts
import { useMessageComposer } from "stream-chat-react-native";
const messageComposer = useMessageComposer();

const onPressHandler = () => {
  messageComposer.setQuotedMessage(null);
};
```

The `resetInput` prop is removed; clearing the quoted message is sufficient.

#### AutoCompleteInput

The component now extends the `TextInputProps` from [React Native](https://reactnative.dev/docs/textinput), so you can pass any valid `TextInput` props to it.

The following props are **removed** from the `AutoCompleteInput` component:

| Prop                           | Replacement                                                                                                                                                                                    |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `additionalTextInputProps`     | This is passed directly on the TextInput component of the auto complete input.                                                                                                                 |
| `autoCompleteSuggestionsLimit` | Use `MessageComposer.textComposer.closeSuggestions` method                                                                                                                                     |
| `giphyActive`                  | Determined by the `command` state from the `MessageComposer.textComposer` instead.                                                                                                             |
| `setGiphyActive`               | This is set within the `TextComposer` of the `MessageComposer` so this isn't needed anymore.                                                                                                   |
| `giphyEnabled`                 | This is removed in favour of new way to add support for commands UI on message input. Refer [this](/chat/docs/sdk/react-native/v8/guides/handle-commands-ui/) guide.                           |
| `maxMessageLength`             | Use `maxMessageLength` in the `additionalTextInputProps` to change the configuration in the `Channel` component.                                                                               |
| `mentionAllAppUsersEnabled`    | Mentions configuration can be done via `TextComposer` mentions middleware (`createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) })` |
| `mentionAllAppUsersQuery`      | Mentions configuration can be done via `TextComposer` mentions middleware (`createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) })` |
| `numberOfLines`                | Use `numberOfLines` in the `additionalTextInputProps` to change the configuration in the `Channel` component.                                                                                  |
| `onChange`                     | Use `onChangeText` in the `additionalTextInputProps` to change the configuration in the `Channel` component.                                                                                   |
| `text`                         | Use `text` state from the `MessageComposer.textComposer` instead.                                                                                                                              |
| `triggerSettings`              | The triggers in the message input are handled by the composer now. Both the searching of the suggestions and selecting them are a part of composer so we don't need it.                        |
| `closeSuggestions`             | This is automatically handled if there are no `suggestions` in the `MessageComposer.textComposer` state.                                                                                       |
| `openSuggestions`              | This is automatically handled if there are `suggestions` in the `MessageComposer.textComposer` state.                                                                                          |
| `updateSuggestions`            | The `suggestions` state in the `MessageComposer.textComposer` is automatically updated based on user input.                                                                                    |

The following props are **added** to the `AutoCompleteInput` component:

- `channel` - to get the config inside the component.

#### AutoCompleteSuggestionList

The following props are removed from `AutoCompleteSuggestionList`:

- `queryText`
- `triggerType`
- `active`
- `data`
- `onSelect`

The state is now handled using the text composer of the message composer as [here](#removed-suggestionscontext).

To select an item from the suggestion list, you can use the `textComposer.handleSelect` method:

```tsx
const handleSelect = async (item) => {
  await textComposer.handleSelect(item);
};
```

#### AutoCompleteSuggestionItem

The `itemProps` now accepts a type of `TextComposerSuggestion` from `stream-chat`.

### New components added

#### CommandInput

The `CommandInput` component is introduced to replace the previous `InputGiphySearch` component. It now handles more commands instead of just Giphy with a similar UI if the `command` state is set in the `TextComposer` of the `MessageComposer`.

The `CommandInput` component now **accepts** the following props:

- `additionalTextInputProps`
- `cooldownEndsAt`

Get the `command` state from the text composer as follows:

```ts
import { TextComposerState } from "stream-chat";
import { useMessageComposer, useStateStore } from "stream-chat-react-native";

const textComposerStateSelector = (state: TextComposerState) => ({
  command: state.command,
});

// Inside the component
const messageComposer = useMessageComposer();
const { textComposer } = messageComposer;
const { command } = useStateStore(
  textComposer.state,
  textComposerStateSelector,
);
```

#### AttachmentUploadPreviewList

The `AttachmentUploadPreviewList` component is introduced to replace the previous `ImageUploadPreview` and `FileUploadPreview` component. It handles the preview of attachments being uploaded and displays a list of attachments with their upload progress.

#### AttachmentUploadProgressIndicator

The `AttachmentUploadProgressIndicator` component is introduced to replace the previous `UploadProgressIndicator` component. It handles the upload progress of attachments and displays a progress indicator.

#### AudioAttachmentUploadPreview

This component is used to preview the uploaded audio attachments. This provides better customization options and is more flexible than the previous implementation as you can override it with your own implementation in the `Channel` component.

The props it takes are:

- `attachment`
- `audioAttachmentConfig`
- `handleRetry`
- `removeAttachments`
- `onLoad`
- `onPlayPause`
- `onProgress`

#### FileAttachmentUploadPreview

This component is used to preview the uploaded file attachments. This provides better customization options and is more flexible than the previous implementation as you can override it with your own implementation in the `Channel` component.

The props it takes are:

- `attachment`
- `handleRetry`
- `removeAttachments`
- `flatListWidth`

#### ImageAttachmentUploadPreview

This component is used to preview the uploaded image attachments. This provides better customization options and is more flexible than the previous implementation as you can override it with your own implementation in the `Channel` component.

The props it takes are:

- `attachment`
- `handleRetry`
- `removeAttachments`

#### VideoAttachmentUploadPreview

This component is used to preview the uploaded video attachments. This provides better customization options and is more flexible than the previous implementation as you can override it with your own implementation in the `Channel` component.

The default implementation of the `VideoAttachmentUploadPreview` component is same as `FileAttachmentUploadPreview`, but it can be overridden with your own implementation in the `Channel` component.

The props it takes are:

- `attachment`
- `handleRetry`
- `removeAttachments`
- `flatListWidth`

### Channel props change

The following props are now **removed** from the `Channel` component:

| Prop                           | Replacement                                                                                                                                                                                                                                                                                                   |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autoCompleteSuggestionsLimit` | [Customize the middlewares](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer-middleware/) to change the limit of results returned by the text composer mention, command or other middlewares.                                                                             |
| `autoCompleteTriggerSettings`  | The triggers in the message input are handled by the composer now. Both the searching of the suggestions and selecting them are a part of composer so we don't need it. [Customize the middlewares intead](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer-middleware/). |
| `doDocUploadRequest`           | Removed in favour of `doUploadRequest` config in the `attachments` object of the `MessageComposer` which can be set as per [this guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods).                                                         |
| `doImageUploadRequest`         | Removed in favour of `doUploadRequest` config in the `attachments` object of the `MessageComposer` which can be set as per [this guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods).                                                         |
| `emojiSearchIndex`             | This is handled by the `createTextComposerEmojiMiddleware` middleware in the `TextComposer`. Set a custom emoji search index as [here](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer-middleware/#emoji-suggestions-middleware).                                        |
| `giphyEnabled`                 | This is removed in favour of new way to add support for commands UI on message input. Refer [this](/chat/docs/sdk/react-native/v8/guides/handle-commands-ui/) guide.                                                                                                                                          |
| `initialValue`                 | The `initialValue` is governed through the global config of the `MessageComposer` which can be set as per [this guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods). Use the `defaultValue` key on the `text` object to set it.               |
| `maxNumberOfFiles`             | The `maxNumberOfFiles` is governed through the global config of the `MessageComposer` which can be set as per [this guide](/chat/docs/sdk/react-native/v8/ui-components/message-input/composer/message-composer/#configuration-methods). Use the `maxNumberOfFilesPerMessage` key to set it.                  |
| `mentionAllAppUsersEnabled`    | Mentions configuration can be done via `TextComposer` mentions middleware (`createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) })`                                                                                                                |
| `mentionAllAppUsersQuery`      | Mentions configuration can be done via `TextComposer` mentions middleware (`createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) })`                                                                                                                |
| `onChangeText`                 | Use `onChangeText` in the `additionalTextInputProps` to change the configuration in the `Channel` component.                                                                                                                                                                                                  |
| `sendImageAsync`               | This never worked properly and was getting hard to maintain across versions so we decided to remove it with the message input component refactor. You can use [offline support](/chat/docs/sdk/react-native/v8/basics/offline-support/) that allows sending file as soon as they are added.                   |
| `InputGiphySearch`             | This is changed to [`CommandInput`](#commandinput) component. Use it instead.                                                                                                                                                                                                                                 |
| `ImageUploadPreview`           | This is moved inside a common [`AttachmentUploadPreviewList`](/chat/docs/sdk/react-native/v8/ui-components/attachment-upload-preview-list/) component that handles both files and images uploads preview now.                                                                                                 |
| `FileUploadPreview`            | This is moved inside a common [`AttachmentUploadPreviewList`](/chat/docs/sdk/react-native/v8/ui-components/attachment-upload-preview-list/) component that handles both files and images uploads preview now.                                                                                                 |
| `UploadProgressIndicator`      | This is changed to [`AttachmentUploadProgressIndicator`](#attachmentuploadprogressindicator) component. Use it instead.                                                                                                                                                                                       |

The following props are now **added** to the `Channel` component:

- `AttachementUploadPreviewList` - to customize the attachment upload preview list.
- `FileAttachmentUploadPreview` - to customize the file attachment upload preview.
- `ImageAttachmentUploadPreview` - to customize the image attachment upload preview.
- `AudioAttachmentUploadPreview` - to customize the audio attachment upload preview.
- `VideoAttachmentUploadPreview` - to customize the video attachment upload preview.
- `CommandInput` - to customize the command input component and replaces the `InputGiphySearch` component.
- `AttachmentUploadProgressIndicator` - to customize the attachment upload progress indicator and replaces the `UploadProgressIndicator` component.
- `doFileUploadRequest` - Custom upload function can be configured via `MessageComposer` configuration (`attachments.doUploadRequest`) or `MessageComposer.attachmentManager.setCustomUploadFn` method.

## AttachmentPicker Changes

The `AttachmentPicker` component is now moved down to the `Channel` wrapper component from the previously `OverlayProvider` component.

The means that all the props around the `AttachmentPicker` are now passed from the `Channel` component, which were previously passed from the `OverlayProvider` component.

The props that can now be passed to the `Channel` component for customizing the `AttachmentPicker` are:

- bottomInset
- topInset
- CameraSelectorIcon
- FileSelectorIcon
- ImageSelectorIcon
- VideoRecorderSelectorIcon
- AttachmentPickerBottomSheetHandle
- attachmentPickerBottomSheetHandleHeight
- attachmentPickerBottomSheetHeight
- AttachmentPickerError
- attachmentPickerErrorButtonText
- AttachmentPickerErrorImage
- attachmentPickerErrorText
- AttachmentPickerIOSSelectMorePhotos
- attachmentSelectionBarHeight
- ImageOverlaySelectedComponent
- numberOfAttachmentImagesToLoadPerCall
- numberOfAttachmentPickerImageColumns

## Handle commands UI

The commands UI is now handled by the `CommandInput` component which replaces the previous `InputGiphySearch` component.

You can follow the guide on how to [handle commands UI](/chat/docs/sdk/react-native/v8/guides/handle-commands-ui/) to set up the commands UI in your application.

This can be now configured by setting up the middlware in the `MessageComposer` as follows:

```tsx
useEffect(() => {
  if (!chatClient) {
    return;
  }
  chatClient.setMessageComposerSetupFunction(({ composer }) => {
    setupCommandUIMiddlewares(composer);
  });
}, [chatClient]);
```

## Handle emoji suggestions

The emoji suggestions are now handled by the `createTextComposerEmojiMiddleware` middleware in the `TextComposer`.

Follow the guide on how to [handle emoji suggestions](/chat/docs/sdk/react-native/v8/guides/emoji-suggestions/) to set up the emoji suggestions in your application.

You can set a custom emoji search index as follows:

```tsx
import { createTextComposerEmojiMiddleware } from "stream-chat-react-native";
import type { TextComposerMiddleware } from "stream-chat";

import { init, SearchIndex } from "emoji-mart";
import data from "@emoji-mart/data";

init({ data });

const Component = () => {
  useEffect(() => {
    if (!chatClient) return;

    chatClient.setMessageComposerSetupFunction(({ composer }) => {
      composer.textComposer.middlewareExecutor.insert({
        middleware: [
          createTextComposerEmojiMiddleware(
            SearchIndex,
          ) as TextComposerMiddleware,
        ],
        position: { before: "stream-io/text-composer/mentions-middleware" },
        unique: true,
      });
    });
  }, [chatClient]);
};
```

## Draft Messages

With this release, the draft messages are now supported out of the box from the SDK.

You can follow the guide on how to [handle draft messages](/chat/docs/sdk/react-native/v8/guides/draft-messages/) to set up the draft messages in your application.

## Polls changes

The poll composition is now done using the `PollComposer` component which is a part of the `MessageComposer`. All the poll related fields and state are directly updated to the `PollComposer` state.

For this the `PollComposer.updateFields` is used to update the poll fields on change. And, on Blur, the `PollComposer.handleFieldBlur` is used.

The previously large `CreatePollContent` component is now split into smaller components to make it easier to use and customize.

- `NameField` - The component to render the name field of the poll.
- `MultipleAnswersField` - The component to render the multiple answers field of the poll.
- `CreatePollHeader` - The component to render the header of the poll creation modal.

If you have a custom poll while creating a poll, you can do the following:

```tsx
const messageComposer = useMessageComposer();
const { closePollCreationDialog, sendMessage } = useMessageInputContext();

const onCreatePoll = async () => {
  await messageComposer.createPoll();
  await sendMessage();
  closePollCreationDialog?.();
  // it's important that the reset of the pollComposer state happens
  // after we've already closed the modal; as otherwise we'd get weird
  // UI behaviour.
  messageComposer.pollComposer.initState();
};
```

Also, the poll options are now added automatically when there's no empty options left and removed when the field is emptied. This state is managed by the `PollComposer` middlewares.

## Clear message input while leaving channel

The `MessageInput` component now does not clears the message input state when the user leaves the channel. This is done to ensure that the message input state is managed by the integrators as they see fit.

To clear the input when moving back from the channel, you can use the `messageComposer.clear()` method in the `useEffect` hook of the channel component.

```tsx
import { useEffect, useCallback } from "react";
import { useMessageComposer } from "stream-chat-react-native";

import { useFocusEffect, useNavigation } from "@react-navigation/native";

export const useClearMessageInputFocusEffect = () => {
  const navigation = useNavigation();
  const messageComposer = useMessageComposer();

  useFocusEffect(
    useCallback(() => {
      return navigation.addListener("beforeRemove", async () => {
        await messageComposer.clear();
      });
    }, [navigation, messageComposer]),
  );
};

const ChannelComponent = () => {
  useClearMessageInputFocusEffect();

  return <></>;
};
```

You can alternatively, call the `messageComposer.clear()` method in the `useEffect` hook of the channel component to clear the message input state when the user leaves the channel.

## Theme changes

As a part of the refactor, there are some changes in the theme object compared to the previous version.

You can check the difference of the theme on the [previous version](https://github.com/GetStream/stream-chat-react-native/v8/blob/V7/package/src/contexts/themeContext/utils/theme.ts) and the [new version](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/contexts/themeContext/utils/theme.ts) and update your theme accordingly.

## Changes to Streami18n

In `v8.0.0` we've bumped the `i18n` library to the latest version, adding support for it.

Most of the breaking changes are handled within the SDK internally, however a breaking change that would impact integrations is the removal of generics for the translator function.

This means that if you were previously doing something like this:

```tsx
import { Text } from "react-native";
import { useTranslationContext } from "stream-chat-react-native";

const TranslatedText = (props) => {
  const { t } = useTranslationContext();

  return <Text>{t<string>(props.text)}</Text>;
};
```

you should now change it to this:

```tsx
import { Text } from "react-native";
import { useTranslationContext } from "stream-chat-react-native";

const TranslatedText = (props) => {
  const { t } = useTranslationContext();

  return <Text>{t(props.text)}</Text>;
};
```


---

This page was last updated at 2026-04-17T17:33:45.738Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v8/basics/upgrading-from-v7/](https://getstream.io/chat/docs/sdk/react-native/v8/basics/upgrading-from-v7/).