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 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

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:

RemovedReplaced by
AutoCompleteTextareaTextAreaComposer
ChatAutoCompleteTextAreaComposer
DefaultSuggestionListSuggestionList
DefaultSuggestionListItemSuggestionListItem

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

PropReplacement
containerStyleApply custom styles using CSS
defaultValueThe default value is set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or set reactively via TextComposer.defaultValue setter
disabledThe default value is set via MessageComposer configuration (text.enabled) (see the composer configuration guide)
disableMentionsRemove mentions middleware from the TextComposer.middlewareExecutor (see the composer middleware guide)
dropdownClassNameOverride prop containerClassName directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel
dropdownStyleApply custom styles using CSS
itemClassNameOverride prop className directly on SuggestionListItem and pass the item component as AutocompleteSuggestionItem to Channel
itemStyleApply custom styles using CSS
listClassNameOverride prop className directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel
listStyleApply custom styles using CSS
loaderClassNameThe prop was not used. No replacement provided.
loaderStyleThe prop was not used. No replacement provided.
loadingComponentThe prop was not used. No replacement provided.
growRedundant prop. Use prop maxRows to indicate up to what number of rows the textarea can grow.
onCaretPositionChangeSubscribe to TextComposer.state to observe the changes of property selection (see the state store guide)
onSelectAdd custom middleware to TextComposer.middlewareExecutor to handle onSuggestionItemSelect event (see the composer middleware guide)
styleApply custom styles using CSS
triggerThe current trigger value is signaled via TextComposer.state.suggestions
valueThe 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.

PropReplacement
handleSubmitIt 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.
wordReplaceReplacement 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

PropReplacement
doFileUploadRequestCustom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method.
doImageUploadRequestCustom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method.
errorHandlerTo handle errors thrown during the file upload, subscribe to client.notifications.state and react to notification.message ‘Error uploading attachment’.
getDefaultValueThe default value is set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or set reactively via TextComposer.defaultValue setter
mentionAllAppUsersMentions configuration can be done via TextComposer mentions middleware ( createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) })
mentionQueryParamsOverride methods MentionsSearchSource.prepareQueryUsersParams or MentionsSearchSource.prepareQueryMembersParams respectively to generate filter, sort and options objects to perform user and member requests based on search text.
messageThe MessageComposer is automatically provide with the editted a message. No replacement.
noFilesCustom logic to filter files can be specified via MessageComposer configuration (attachments.fileUploadFilter) or MessageComposer.attachmentManager.fileUploadFilter setter.
parentThe parent message is automatically provided to the MessageComposer. No replacement.
publishTypingEventConfigure with MessageComposer.textComposer.publishTypingEvents
urlEnrichmentConfigThe link preview config can be specified via MessageCoposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters
useMentionsTransliterationMentions 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:

type overrideSubmitHandler = (params: {
  cid: string;
  localMessage: LocalMessage;
  message: Message;
  sendOptions: SendMessageOptions;
}) => Promise<void> | void;

Removed Channel props

maxNumberOfFiles, multipleUploads, TriggerProvider

PropReplacement
acceptedFilesThe array of strings can be specified via MessageComposer configuration (attachments.acceptedFiles) or MessageComposer.attachmentManager.acceptedFiles setter.
enrichURLForPreview, enrichURLForPreviewConfigThe link preview config can be specified via MessageCoposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters.
maxNumberOfFilesCan be specified via MessageComposer configuration (attachments.maxNumberOfFilesPerMessage) or MessageComposer.attachmentManager.maxNumberOfFilesPerMessage setter.
multipleUploadsDoes not have replacement. Multiple uploads are inferred from configuration parameter maxNumberOfFilesPerMessage value greater than 1.
TriggerProviderTriggers 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:

  • SuggestionHeaderProps
  • ChatAutoCompleteProps
  • AutocompleteMinimalData
  • CommandTriggerSetting
  • EmojiTriggerSetting
  • UserTriggerSetting
  • TriggerSetting
  • TriggerSettings

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.

PropReplacement
quotedMessageValue 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).
  • onPaste
  • recordingController
  • textareaRef

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

PropReplacement
insertTextUse MessageComposer.textComposer.insertText method
handleChangeUse MessageComposer.textComposer.handleChange method
isUploadEnabledUse useAttachmentManagerState hook to subscribe to isUploadEnabled value changes
maxFilesLeftUse useAttachmentManagerState hook to subscribe to availableUploadSlots value changes
numberOfUploadsUse useAttachmentManagerState hook to subscribe to successfulUploadsCount and uploadsInProgressCount value changes
onSelectUserUse MessageComposer.textComposer.handleSelect method to announce a suggestion item has been selected. It is possible to register custom TextComposer middleware (see the middleware guide).
removeAttachmentsUse MessageComposer.attachmentManager.removeAttachments method
uploadAttachmentUse MessageComposer.attachmentManager.uploadAttachment method
uploadNewFilesUse MessageComposer.attachmentManager.uploadFiles method
upsertAttachmentsUse MessageComposer.attachmentManager.upsertAttachments method
closeCommandsListUse MessageComposer.textComposer.closeSuggestions method
openCommandsListDone 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).
showCommandsListDetermine command suggestion list to be open by TextComposer.suggestions?.trigger === commandTrigger
closeMentionsListUse MessageComposer.textComposer.closeSuggestions method
openMentionsListDone 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).
showMentionsListDetermine 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 NameNew Name
isLocalAttachmentisLocalAttachment
isScrapedContentisScrapedContent
noneisLocalUploadAttachment
isFileAttachmentisFileAttachment
isLocalFileAttachmentisLocalFileAttachment
isUploadedImageisImageAttachment
noneisLocalImageAttachment
isAudioAttachmentisAudioAttachment
isLocalAudioAttachmentisLocalAudioAttachment
isVoiceRecordingAttachmentisVoiceRecordingAttachment
isLocalVoiceRecordingAttachmentisLocalVoiceRecordingAttachment
isMediaAttachmentisVideoAttachment
isLocalMediaAttachmentisLocalVideoAttachment
noneisUploadedAttachment

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.

© Getstream.io, Inc. All Rights Reserved.