type overrideSubmitHandler = (params: {
cid: string;
localMessage: LocalMessage;
message: Message;
sendOptions: SendMessageOptions;
}) => Promise<void> | void;Upgrade to v13
Removal of StreamChatGenerics
See the release guide of stream-chat and TypeScript & Custom Data Types article.
Changes in Message Types
Introduction of LocalMessage type
Types MessageToSend, StreamMessage, UpdatedMessage have been removed and replaced by LocalMessage. The type LocalMessage is a message representation stored in a local state. The message data is retrieved from the server as MessageResponse and immediately converted to LocalMessage.
Introduction of RenderedMessage type
The type RenderedMessage is comprised of LocalMessage as well as ephemeral messages generated client side - DateSeparatorMessage, IntroMessage.
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.
Replaced Text Autocomplete Components
Some components were dropped to be refreshed with new behavior and easier functionality:
| Removed | Replaced by |
|---|---|
| AutoCompleteTextarea | TextAreaComposer |
| ChatAutoComplete | TextAreaComposer |
| DefaultSuggestionList | SuggestionList |
| DefaultSuggestionListItem | SuggestionListItem |
Components ChatAutoComplete that used to render AutoCompleteTextarea were replaced by a single component TextAreaComposer.
Removed MessageInput, ChatAutoComplete and AutoCompleteTextarea props
The following props that were previously exposed for ChatAutoComplete and AutoCompleteTextarea are not available anymore.
AutoCompleteTextarea
| Prop | Replacement |
|---|---|
containerStyle | Apply custom styles using CSS |
defaultValue | The default value is set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or set reactively via TextComposer.defaultValue setter |
disabled | The default value is set via MessageComposer configuration (text.enabled) (see the composer configuration guide) |
disableMentions | Remove mentions middleware from the TextComposer.middlewareExecutor (see the composer middleware guide) |
dropdownClassName | Override prop containerClassName directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel |
dropdownStyle | Apply custom styles using CSS |
itemClassName | Override prop className directly on SuggestionListItem and pass the item component as AutocompleteSuggestionItem to Channel |
itemStyle | Apply custom styles using CSS |
listClassName | Override prop className directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel |
listStyle | Apply custom styles using CSS |
loaderClassName | The prop was not used. No replacement provided. |
loaderStyle | The prop was not used. No replacement provided. |
loadingComponent | The prop was not used. No replacement provided. |
grow | Redundant prop. Use prop maxRows to indicate up to what number of rows the textarea can grow. |
onCaretPositionChange | Subscribe to TextComposer.state to observe the changes of property selection (see the state store guide) |
onSelect | Add custom middleware to TextComposer.middlewareExecutor to handle onSuggestionItemSelect event (see the composer middleware guide) |
style | Apply custom styles using CSS |
trigger | The current trigger value is signaled via TextComposer.state.suggestions |
value | The current (text) value is signaled via TextComposer.state.text |
ChatAutoComplete
The component used to forward props to AutoCompleteTextarea. As those are already described in the previous section, we will omit them in the below table.
| Prop | Replacement |
|---|---|
handleSubmit | It is possible to customize the message composition via MessageComposer.compositionMiddlewareExecutor and draft composition via MessageComposer.draftCompositionMiddlewareExecutor (see the composer middleware guide). Also the sending of the message is customizable via Channel prop doSendMessageRequest. |
wordReplace | Replacement of text to native emoji entity is now performed via TextComposer middleware via onChange handler. Handled out-of-the-box with pre-built emoji middleware see the composer middleware guide |
MessageInput
| Prop | Replacement |
|---|---|
doFileUploadRequest | Custom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method. |
doImageUploadRequest | Custom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method. |
errorHandler | To handle errors thrown during the file upload, subscribe to client.notifications.state and react to notification.message ‘Error uploading attachment’. |
getDefaultValue | The default value is set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or set reactively via TextComposer.defaultValue setter |
mentionAllAppUsers | Mentions configuration can be done via TextComposer mentions middleware ( createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) }) |
mentionQueryParams | Override methods MentionsSearchSource.prepareQueryUsersParams or MentionsSearchSource.prepareQueryMembersParams respectively to generate filter, sort and options objects to perform user and member requests based on search text. |
message | The MessageComposer is automatically provide with the editted a message. No replacement. |
noFiles | Custom logic to filter files can be specified via MessageComposer configuration (attachments.fileUploadFilter) or MessageComposer.attachmentManager.fileUploadFilter setter. |
parent | The parent message is automatically provided to the MessageComposer. No replacement. |
publishTypingEvent | Configure with MessageComposer.textComposer.publishTypingEvents |
urlEnrichmentConfig | The link preview config can be specified via MessageCoposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters |
useMentionsTransliteration | Mentions configuration can be done via TextComposer mentions middleware ( createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {transliterate: (textToTransliterate: string) => string}) }) |
Further, the signature of function passed to overrideSubmitHandler has changed. It now accepts a single object parameter:
Removed Channel props
maxNumberOfFiles, multipleUploads, TriggerProvider
| Prop | Replacement |
|---|---|
acceptedFiles | The array of strings can be specified via MessageComposer configuration (attachments.acceptedFiles) or MessageComposer.attachmentManager.acceptedFiles setter. |
enrichURLForPreview, enrichURLForPreviewConfig | The link preview config can be specified via MessageCoposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters. |
maxNumberOfFiles | Can be specified via MessageComposer configuration (attachments.maxNumberOfFilesPerMessage) or MessageComposer.attachmentManager.maxNumberOfFilesPerMessage setter. |
multipleUploads | Does not have replacement. Multiple uploads are inferred from configuration parameter maxNumberOfFilesPerMessage value greater than 1. |
TriggerProvider | Triggers are characters in composed message text that cause suggestions to be rendered (emoji, mentions, commands). This component served to propagate potentially custom trigger logic. This is however now done via TextComposer.middlewareExecutor by providing custom middleware functions (see the composer middleware guide). |
Autocomplete trigger logic migration
The autocomplete trigger for text composition is now handled by TextComposer middleware located in stream-chat. The following types were therefore removed fromstream-chat-react:
SuggestionHeaderPropsChatAutoCompletePropsAutocompleteMinimalDataCommandTriggerSettingEmojiTriggerSettingUserTriggerSettingTriggerSettingTriggerSettings
The migration of trigger logic also lead to removal of trigger generic parameter in stream-chat-react components. The generic type is not needed anymore as typed text is processed by a customizable chain of middleware functions before it is committed to the MessageComposer state.
ChannelActionContext Changes
Beside the introduction of LocalMessage to editMessage, openThread, removeMessage, updateMessage parameters representing a message, the following changes have been introduced:
The sendMessage function signature has changed. Now it accepts a single object parameter:
type sendMessage = (params: {
localMessage: LocalMessage;
message: Message;
options?: SendMessageOptions;
}) => Promise<void>;Function setQuotedMessage has been removed. Quoted message state is now handled by MessageComposer. It can be set via MessageComposer.setQuotedMessage(quotedMessage: LocalMessage | null) method.
ChannelStateContext Changes
Removed Channel props are now absent from the ChannelStateContext too. These are: acceptedFiles, enrichURLForPreview, parts of the enrichURLForPreviewConfig ( debounceURLEnrichmentMs, findURLFn, onLinkPreviewDismissed), multipleUploads.
| Prop | Replacement |
|---|---|
quotedMessage | Value changes can now be observed by subscribing to MessageComposer.state changes. |
const messageComposerStateSelector = (state: MessageComposerState) => ({
quotedMessage: state.quotedMessage,
});
const messageComposer = useMessageComposer();
const { quotedMessage } = useStateStore(
messageComposer.state,
messageComposerStateSelector,
);Transformed useMessageInputState to useMessageInputControls
We have moved all the message composition state management from stream-chat-react to stream-chat and the new MessageComposer. Therefore the hook useMessageInputState has been renamed to useMessageInputControls as it does not handle the composition state anymore and provides only the following API that is accessible via MessageInputContext:
handleSubmit- Also received an overhaul resulting in signature change (see below).onPasterecordingControllertextareaRef
Message input state as well as the majority of the API is now kept within MessageComposer instead of MessageInputContext.
MessageInputContext Changes
Due to the transformation of useMessageInputState of
1. Context Values Removed
| Prop | Replacement |
|---|---|
insertText | Use MessageComposer.textComposer.insertText method |
handleChange | Use MessageComposer.textComposer.handleChange method |
isUploadEnabled | Use useAttachmentManagerState hook to subscribe to isUploadEnabled value changes |
maxFilesLeft | Use useAttachmentManagerState hook to subscribe to availableUploadSlots value changes |
numberOfUploads | Use useAttachmentManagerState hook to subscribe to successfulUploadsCount and uploadsInProgressCount value changes |
onSelectUser | Use MessageComposer.textComposer.handleSelect method to announce a suggestion item has been selected. It is possible to register custom TextComposer middleware (see the middleware guide). |
removeAttachments | Use MessageComposer.attachmentManager.removeAttachments method |
uploadAttachment | Use MessageComposer.attachmentManager.uploadAttachment method |
uploadNewFiles | Use MessageComposer.attachmentManager.uploadFiles method |
upsertAttachments | Use MessageComposer.attachmentManager.upsertAttachments method |
closeCommandsList | Use MessageComposer.textComposer.closeSuggestions method |
openCommandsList | Done automatically upon trigger identification. We can register a custom TextComposer middleware for onChange event to introduce custom logic, or override the command trigger character(s) (see the middleware guide). |
showCommandsList | Determine command suggestion list to be open by TextComposer.suggestions?.trigger === commandTrigger |
closeMentionsList | Use MessageComposer.textComposer.closeSuggestions method |
openMentionsList | Done automatically upon trigger identification. We can register a custom TextComposer middleware for onChange event to introduce custom logic, or override the mentions trigger character(s) (see the middleware guide). |
showMentionsList | Determine command suggestion list to be open by TextComposer.suggestions?.trigger === mentionTrigger |
The removed values forwarded from MessageInputProps to MessageInputContext have been documented above.
2. handleSubmit Signature Change
We changed the signature of function handleSubmit which now optionally accepts only event object. The other two parameters customMessageData and options have been removed.
Before:
type handleSubmit = (
event?: React.BaseSyntheticEvent,
customMessageData?: Partial<Message<StreamChatGenerics>>,
options?: SendMessageOptions,
) => Promise<void>;Now:
type handleSubmit = (event?: React.BaseSyntheticEvent) => Promise<void>;The custom message data can be injected via custom middleware handlers (see the middleware guide) or by setting the data directly:
messageComposer.customDataManager.setMessageData({ a: "b" });Attachment identity functions moved to stream-chat
The following identity functions were moved to stream-chat:
| Original Name | New Name |
|---|---|
isLocalAttachment | isLocalAttachment |
isScrapedContent | isScrapedContent |
| none | isLocalUploadAttachment |
isFileAttachment | isFileAttachment |
isLocalFileAttachment | isLocalFileAttachment |
isUploadedImage | isImageAttachment |
| none | isLocalImageAttachment |
isAudioAttachment | isAudioAttachment |
isLocalAudioAttachment | isLocalAudioAttachment |
isVoiceRecordingAttachment | isVoiceRecordingAttachment |
isLocalVoiceRecordingAttachment | isLocalVoiceRecordingAttachment |
isMediaAttachment | isVideoAttachment |
isLocalMediaAttachment | isLocalVideoAttachment |
| none | isUploadedAttachment |
The isGalleryAttachmentType still has to be imported from stream-chat-react as it is specific to the repository.
Message Composition Changes Summary
The message composition is now handled by MessageComposer class. The class instance should be retrieved using useMessageComposer hook. The hook provides the correct instance according to the context in which the hook was invoked.
All the API that was moved to MessageComposer had to be removed from the relevant React contexts and component props in stream-chat-react.
Removal of Channel.dragAndDropWindow Prop
Channel prop dragAndDropWindow and associated optionalMessageInputProps have been removed, use WithDragAndDropUpload component instead.
- Removal of StreamChatGenerics
- Changes in Message Types
- Change in Message Composition
- Replaced Text Autocomplete Components
- Removed MessageInput, ChatAutoComplete and AutoCompleteTextarea props
- Removed Channel props
- Autocomplete trigger logic migration
- ChannelActionContext Changes
- ChannelStateContext Changes
- Transformed useMessageInputState to useMessageInputControls
- MessageInputContext Changes
- Attachment identity functions moved to stream-chat
- Message Composition Changes Summary
- Removal of Channel.dragAndDropWindow Prop