messageComposer.customDataManager.setMessageData({ a: "b" });
Migration from 7.x to 8.x
Change in Message Composition
Message composition is now managed by MessageComposer
class instances. Every composition context has its own composer. There are the following composition contexts:
channel
- for main channel list message compositionthread
- for message composition in Thread viewlegacy_thread
- for message composition in thread open next to the main channel listmessage
- for editing a message in any message list
The composer instances can be retrieved via useMessageComposer
hook.
Introduction of MessageComposer
leads to breaking changes described in the following sections.
The following hooks are introduced to access the MessageComposer
state and methods:
useMessageComposer
- to access theMessageComposer
instance.useAttachmentManagerState
- to access theAttachmentManager
state of theMessageComposer
.useMessageComposerHasSendableData
- to access thehasSendable
data of theMessageComposer
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. |
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 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
The sendMessage
doesn’t accept a customMessageData
parameter anymore. Instead, the custom message data can be injected via custom middleware handlers (see the middleware guide) or by setting the data directly:
Removed SuggestionsContext
The SuggestionsContext
is removed as the suggestions are now handled by the TextComposer
of the MessageComposer
. The suggestions are now part of the TextComposer
state and can be accessed through the useMessageComposer
hook.
The text composer internally searches for suggestions based on the text input and the trigger character. You can read more about it here.
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 auto complete suggestions list is automatically opened/closed when there are valid suggestions available based on the text input and the trigger character.
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.
The means that you can access the useAttachmentPickerContext
hook from the children of the Channel
component.
Ideally, if you were passing the topInset
and bottomInset
previously in your OverlayProvider
component, you might not need it anymore if your Channel wrapper is used correctly.
If you still want to pass the topInset
and bottomInset
values as per your layout, you can pass them to the Channel
component as follows:
<Channel channel={channel} topInset={topInset} bottomInset={bottomInset} />
Alternatively, you can set the values using the useAttachmentPickerContext
hook. Make sure you call the hook below the hierarchy of the Channel
component, as the context is now provided by the Channel
component.
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);
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.
The context no longer provides/contains the following values:
maxNumberOfFiles
setMaxNumberOfFiles
selectedFiles
setSelectedFiles
selectedImages
setSelectedImages
The uploads, on selection of a file/image, happens directly through the AttachmentManager
of the MessageComposer
.
You can access the selected files/images easily through the attachments
state of the AttachmentManager
. An example of how to check if an image is selected:
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.
You can set the maxNumberOfFilesPerMessage
key in the MessageComposer
config like this:
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 the following values/functions to be used to manage the quoted message and edited message states:
setEditingState
- The setter for the edited message state. Accepts aLocalMessage
object.clearEditingState
- The function to clear the edited message state.setQuotedMessage
- The function to set the quoted message state. Accepts aLocalMessage
object.
If you were using the MessagesContext
previously, you can now use the MessageComposerAPIContext
to manage the quoted message and edited message states.
const { setEditingState, clearEditingState, setQuotedMessage } =
useMessageComposerAPIContext();
To clear the quoted message state, you can use the message composer as follows:
import { useMessageComposer } from "stream-chat-react-native";
const messageComposer = useMessageComposer();
const onPressHandler = () => {
messageComposer.setQuotedMessage(null);
};
Component Changes
Message Input Components Changes
The following props are changed in the MessageInput
component and its subcomponents:
MessageInput
The following props are added to the MessageInput
component. They were previously used directly from the context, but now they are passed as a prop from the wrapper component using the context:
bottomInset
selectedPicker
attachmentPickerBottomSheetHeight
attachmentSelectionBarHeight
The props that are removed from the MessageInput
component:
Prop | Replacement |
---|---|
asyncIds | Removed in favor of sendImageAsync prop no longer supported. |
asyncUploads | Removed in favor of sendImageAsync prop no longer supported. |
clearEditingState | This is directly used in the component where the editing state is cancelled so its not needed. If you still want to use it you can do it from clearEditingState from useMessageComposerAPIContext . |
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 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 for more details. |
mentionedUsers | Use mentionedUsers state from the MessageComposer.textComposer instead. |
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 . |
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 | This was not needed in favour of the composer handling the message composer 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 type of the editing
prop is changed to boolean
. The MessageInput
component internally checks for the messageComposer.editedMessage
to be undefined and pass the boolean to the component.
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 onPress behaviour of the CommandsButton
is to open the commands picker, which is done done through:
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. |
setShowMoreOptions | This is handled internally within the component and the state is no more used. |
showMoreOptions | This is handled internally within the component and the state is no more 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 thecommand
state from theTextComposer
of theMessageComposer
to determine if the command is active.
ShowThreadMessageInChannelButton
The props that are removed from the ShowThreadMessageInChannelButton
component:
Prop | Replacement |
---|---|
sendThreadMessageInChannel | This is deteremined and handled using the showReplyInChannel state of the MessageComposer state. |
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)
.
import { useMessageComposer } from "stream-chat-react-native";
const messageComposer = useMessageComposer();
const onPressHandler = () => {
messageComposer.setQuotedMessage(null);
};
The resetInput
props is also removed as we don’t need to reset the input in this case. The quoted message state been cleared should suffice.
AutoCompleteInput
The component now extends the TextInputProps
from React Native, 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 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 follow props are removed from the AutoCompleteSuggestionList
component:
queryText
triggerType
active
data
onSelect
The state is now handled using the text composer of the message composer as here.
To select an item from the suggestion list, you can use the textComposer.handleSelect
method:
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
The command
state can be get from the text composer of the message composer as follows:
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 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. |
doDocUploadRequest | Removed in favour of doUploadRequest config in the attachments object of the MessageComposer which can be set as per this guide. |
doImageUploadRequest | Removed in favour of doUploadRequest config in the attachments object of the MessageComposer which can be set as per this guide. |
emojiSearchIndex | This is handled by the createTextComposerEmojiMiddleware middleware in the TextComposer . Set a custom emoji search index as here. |
giphyEnabled | This is removed in favour of new way to add support for commands UI on message input. Refer this guide. |
initialValue | The initialValue is governed through the global config of the MessageComposer which can be set as per this guide. 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. 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 that allows sending file as soon as they are added. |
InputGiphySearch | This is changed to CommandInput component. Use it instead. |
ImageUploadPreview | This is moved inside a common AttachmentUploadPreviewList component that handles both files and images uploads preview now. |
FileUploadPreview | This is moved inside a common AttachmentUploadPreviewList component that handles both files and images uploads preview now. |
UploadProgressIndicator | This is changed to 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 theInputGiphySearch
component.AttachmentUploadProgressIndicator
- to customize the attachment upload progress indicator and replaces theUploadProgressIndicator
component.doFileUploadRequest
- Custom upload function can be configured viaMessageComposer
configuration (attachments.doUploadRequest
) orMessageComposer.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 to set up the commands UI in your application.
This can be now configured by setting up the middlware in the MessageComposer
as follows:
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 to set up the emoji suggestions in your application.
You can set a custom emoji search index as follows:
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 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:
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.
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 and the new version 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:
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:
import { Text } from "react-native";
import { useTranslationContext } from "stream-chat-react-native";
const TranslatedText = (props) => {
const { t } = useTranslationContext();
return <Text>{t(props.text)}</Text>;
};