<ThreadProvider thread={thread}>
<Thread />
</ThreadProvider>
Upgrade to v12
Introducing Threads 2.0
With the release of v12 of our SDK we’re also releasing new thread functionality - specifically “thread view”, which consists of ThreadList
and Thread
components allowing your users to quickly go over threaded conversations they’re part of. To implement this simple view see thread and channel view guide.
Thread & ThreadManager
Both Thread
and ThreadManager
are new classes within stream-chat
package with own logic which updates their respective state objects to which integrators can subscribe to and render their UI accordingly. These classes (or rather instances of these classes) are utilised within React SDK. Read more about accessing state of these classes in our SDK State Management documentation.
ThreadList & ThreadListItem
ThreadList
component represents a ThreadManager
instance while ThreadListItem
represents individual Thread
instances. UI of both of these components reflects latest state of their appropriate “controllers” but apart from communicating with their controllers via available methods these components do not manage any extra logic.
ThreadProvider
ThreadProvider
is an “adapter” which allows existing Thread
component to consume methods and state of the Thread
instance.
ChatView & ChatView.ThreadAdapter
ChatView
is component itself and a set of components which allow for a drop-in implementation of different chat views - the channel view and thread view. This drop-in solution allows your users to easily switch between said views without having to implement such mechanism yourself. Read more about it in our ChatView
documentation.
Introducing WithComponents & Dropping Defaults
We know that component overrides are 90% of our SDK and providing these overrides only through Channel
component isn’t optimal. In the upcoming minor releases we’ll be deprecating component overrides through individual component props and rather provide these overrides through WithComponents
, you can read more about this component in our WithComponents
documentation.
Dropped ComponentContext Defaults
These components are no longer provided through the ComponentContext
as default values but have moved to their respective components:
Attachment
DateSeparator
Message
MessageSystem
reactionOptions
UnreadMessagesSeparator
Before and After
Previous solution for component overrides:
const MessageInputUi1 = () => {
/*...*/
};
const MessageInputUi2 = () => {
/*...*/
};
<Channel Input={MessageInputUi1}>
<Window>
<MessageList />
<MessageInput focus />
</Window>
<Thread Input={MessageInputUi2} virtualized />
</Channel>;
Current solution utilising WithComponents
:
const MessageInputUi1 = () => {
/*...*/
};
const MessageInputUi2 = () => {
/*...*/
};
<Channel>
<WithComponents overrides={{ Input: MessageInputUi1 }}>
<Window>
<MessageList />
<MessageInput focus />
</Window>
<WithComponents overrides={{ Input: MessageInputUi2 }}>
<Thread virtualized />
</WithComponents>
</WithComponents>
</Channel>;
Audio recordings transcoding
Until now the audio recordings were transcoded to audio/mp3. As of v12, the MIME-type audio/wav will be the default. You can still opt-in to MP3 and benefit from the reduced file size and bandwidth usage:
Action required
To opt into MP3 transcoding follow these steps:
- The library
@breezystack/lamejs
has to be installed as this is a peer dependency tostream-chat-react
.
npm install @breezystack/lamejs
yarn add @breezystack/lamejs
- The MP3 encoder has to be imported separately as a plugin:
import { MessageInput } from 'stream-chat-react';
import { encodeToMp3 } from 'stream-chat-react/mp3-encoder';
<MessageInput focus audioRecordingConfig={{ transcoderConfig: { encoder: encodeToMp3 } }} />;
Unified dialog management
Dialogs will be managed centrally. At the moment, this applies to display of ReactionSelector
and MessageActionsBox
. They will be displayed on a transparent overlay that prevents users from opening other dialogs in the message list. Once an option from a dialog is selected or the overlay is clicked, the dialog will disappear. This adjust brings new API and removes some properties from MessageContextValue
.
Removed properties from MessageContextValue
isReactionEnabled
- served to signal the permission to send reactions by the current user in a given channel. With the current permissions implementation, the permission can be determined by doing the following:
import { useMessageContext } from 'stream-chat-react';
const { getMessageActions } = useMessageContext();
const messageActions = getMessageActions();
const canReact = messageActions.includes(MESSAGE_ACTIONS.react);
onReactionListClick
- handler function that toggled the open state ofReactionSelector
represented by another removed value -showDetailedReactions
showDetailedReactions
- flag used to decide, whether the reaction selector should be shown or notreactionSelectorRef
- ref to the root of the reaction selector component (served to control the display of the component)
Also prop messageWrapperRef
was removed as part of the change from MessageOptions
and MessageActions
props.
On the other hand, the Message
prop (configuration parameter) closeReactionSelectorOnClick
is now available in the MessageContextValue
.
If you used any of these values in your customizations, please make sure to adjust your implementation according to the newly recommended use of Dialog API in Dialog management guide.
New dialog management API
To learn about the new API, please, take a look at our Dialog management guide.
EmojiPickerIcon extraction to emojis plugin
The default EmojiPickerIcon
has been moved to emojis plugin from which we already import EmojiPicker
component.
Action required
In case you are importing EmojiPickerIcon
in your code, make sure to adjust the import as follows:
import { EmojiPickerIcon } from 'stream-chat-react/emojis';
Removal of duplicate uploads state in MessageInput
As of the version 12 of stream-chat-react
the MessageInputContext
will not expose the following state variables:
fileOrder
- An array of IDs for non-image uploaded attachments. Its purpose was just to keep order in which the attachments were added.imageOrder
- An array of IDs for image uploaded attachments. Its purpose was just to keep order in which the attachments were added.fileUploads
- A mapping of ID to attachment representing the uploaded non-image file.imageUploads
- A mapping of ID to attachment representing the uploaded image file.
These four variables’ purpose was to render the attachment previews in a given order. All the non-image attachments were assigned type "file"
until the message was sent at which point the audio files were assigned type "audio"
and video file type "video"
. Also, the attachment objects structure used to change upon submission. Some keys were renamed and other just removed.
The shortcomings of the above approach have been adjusted as follows:
All the attachments except the link preview attachments (objects that contain
og_scrape_url
attribute) are now stored inattachments
array ofMessageInputContext
. Array keeps order and the attachment type can be determined by theattachment.type
property.The previously removed “local” data is now stored on each attachment object under
localMetadata
key. This key is removed upon submission. EverylocalMetadata
object has to at least contain theid
attribute that allows us to update or remove the given attachment from the state. The attachments that represent an uploaded file has to also include thelocalMetadata.file
reference.Attachments representing uploaded files will be identified by the
file
attribute asattachment.localMetadata.file
. Default attachment types recognized by the SDK are:
audio
file
image
video
voiceRecording
The attachment
type
is assigned upon the upload and not upon the submission. Also, there is no renaming of attachment attributes upon submission, but the attachment objects are assigned the attributes that are kept from the upload until the submission. These attributes are:We have removed the following API tied to uploads state from the MessageInput state
uploadFile
-> from now on, useuploadAttachment
uploadImage
-> from now on, useuploadAttachment
removeFile
-> from now on, useremoveAttachments
removeImage
-> from now on, useremoveAttachments
The function uploadNewFiles
has been kept.
To sum up, the attachments management API in MessageInput is from now on only:
attachments
- An array that keeps all the message attachment objects except for link previews that should be accessed vialinkPreviews
(see the guide on how to uselinkPreviews
).uploadAttachment
- Uploads a single attachment. The provided attachment should contain alocalMetadata
object withfile
(references aFile
instance to be uploaded) andid
properties.uploadNewFiles
- Expects an array ofFile
orBlob
objects, generates an array of well-formed attachments and uploads the files withuploadAttachment
functionupsertAttachments
- Expects an array of attachment object where each of those should containlocalMetadata.id
. Creates or updates the attachment attributes based on the given id in theattachments
array ofMessageInputContext
.removeAttachments
- Expects and array of strings representing attachment IDs and removes those attachment objects from the state.
Action required
Make sure you are not using any of the removed API elements (for example you have implemented a custom AttachmentPreviewList
):
fileOrder
imageOrder
fileUploads
imageUploads
uploadFile
uploadImage
removeFile
removeImage
Date & time formatting
The components that display date and time are:
DateSeparator
- separates message groups in message listsEventComponent
- displays system messagesMessageTimestamp
- displays the creation timestamp for a message in a message list
These components had previously default values for props like format
or calendar
. This setup required for a custom formatting to be set up via i18n service, the default values had to be nullified. For a better developer experience we decided to remove the default prop values and rely on default configuration provided via i18n translations. The value null
is not a valid value for format
, calendar
or calendarFormats
props.
Action required
If you are not using the default translations provided with the SDK, make sure to follow the date & time formatting guide to verify that your dates are formatted according to your needs.
Avatar changes
The Avatar
styles are applied through CSS from the version 12 upwards. Therefore, the following changes were applied:
Props
shape
andsize
were removed. Subsequently, the classstr-chat__avatar--${shape}
was removed.Another class we removed is
str-chat__avatar-image--loaded
that was applied toimg
element in theAvatar
component.New prop
className
has been added toAvatar
. Integrators can now optionally apply custom styles to custom classes.There have also been added new classes to
Avatar
rootdiv
in different components:
Component | Avatar root CSS class |
---|---|
ChannelHeader | str-chat__avatar--channel-header |
ChannelPreviewMessenger | str-chat__avatar--channel-preview |
MessageStatus | str-chat__avatar--message-status |
ReactionsList | stream-chat__avatar--reaction |
QuotedMessage | str-chat__avatar--quoted-message-sender |
SearchResultItem | str-chat__avatar--channel-preview |
UserItem rendered by SuggestionListItem | str-chat__avatar--autocomplete-item |
- As a consequence of the
Avatar
props changes, theTypingIndicator
propavatarSize
have been removed as well.
Action required
1. Migrate CSS applied to .str-chat__avatar--${shape}
or re-apply the class through Avatar
className
prop.
2. Migrate CSS applied to .str-chat__avatar-image--loaded
to .str-chat__avatar-image
class.
3. If needed, apply custom styles to newly added classes based on the component that renders the Avatar
.
Removal of styling props
Removal of Window’s hideOnThread prop
The prop boolean hideOnThread
enabled us to control, whether class str-chat__main-panel--hideOnThread
was attached to Window
component’s root <div/>
. By assigning this class a CSS rule display: none
in the default SDK’s stylesheet we hid the contents of Window
. We decided to simplify the logic in this case:
- class
str-chat__main-panel--hideOnThread
was replaced by classstr-chat__main-panel--thread-open
- the class
str-chat__main-panel--thread-open
is attached to the root<div/>
always, when thread is open - the default value of
hideOnThread
prop wasfalse
(Window
contents was not hidden upon opening a thread) and so integrators still have to opt in to hiding the contents upon opening a thread by adding ruledisplay: none
tostr-chat__main-panel--thread-open
class
Action required
If your application renders Window
with hideOnThread
enabled, and you want to keep this behavior add the following rule to your CSS:
.str-chat__main-panel--thread-open {
display: none;
}
.str-chat__main-panel--thread-open + .str-chat__thread {
// occupy the whole space previously occupied by the main message list container
flex: 1;
}
Removal of Thread’s fullWidth prop
Setting the fullWidth
value to true
let to assignment of class str-chat__thread--full
to the Thread
component’s root <div/>
. This class had support in the SDK’s legacy stylesheet only. With the approach of avoiding styling React components via props, the prop has been removed along with the legacy stylesheet. Read more about the the stylesheet removal in the section Removal of deprecated components.
Removal of deprecated components
Attachment rendering utility functions
The attachment rendering functions were replaced with their component equivalents:
Action required
Replace the render functions in your custom components with container components alternatives.
Rendering function | Component equivalent |
---|---|
renderAttachmentWithinContainer | AttachmentWithinContainer |
renderAttachmentActions | AttachmentActionsContainer |
renderGallery | GalleryContainer |
renderImage | ImageContainer |
renderCard | CardContainer |
renderAudio | AudioContainer |
renderMedia | MediaContainer |
Change import of default styles
Until now, it was possible to import two stylesheets as follows:
import 'stream-chat-react/dist/css/v1/index.css';
Or
import 'stream-chat-react/dist/css/v2/index.css';
The legacy stylesheet has been removed from the SDK bundle, and therefore it is only possible to import one stylesheet from now on:
import 'stream-chat-react/dist/css/v2/index.css';
Action required
Make sure you are importing the default styles correctly as import 'stream-chat-react/dist/css/v2/index.css';
Removal of legacy styles
With the version 10 of stream-chat-react
new stylesheet has been introduced. The stylesheet used previously became a legacy stylesheet. Legacy stylesheet had often times CSS classes and SDK components, that were not supported with the new stylesheet. Now, the legacy stylesheet and corresponding CSS classes and SDK component are being removed.
These changes will impact you only if you have imported the CSS as one of the following (you have used the legacy styles):
import 'stream-chat-react/css/index.css';
import '@stream-io/stream-chat-css/dist/css/index.css';
Removal of themeVersion from ChatContext
Supporting two stylesheet lead to introduction of a flag themeVersion
into the ChatContext
. This flag is no more necessary and has been removed from the context value.
Action required
Make sure you are not using themeVersion
in your custom components.
Removal of styles related Chat props
With legacy stylesheet we have removed legacy approach to applying styles via component props. Two Chat
component props were removed as a consequence:
customStyles
darkMode
Also associated parts of code were removed:
Theme
typeuseCustomStyles
hook
Action required
1. The styles applied through customStyles
should be applied through custom CSS.
2. Theme (not only dark theme) can be through Chat
prop theme
instead of darkMode
Removal from ComponentContext
AutocompleteSuggestionHeader
- the up-to-date SDK markup does not count with a header in theChatAutoComplete
suggestion list
Action required
Make sure you are passing these custom components to the Channel
component.
Removal of legacy components
The following components are not available anymore as they were related to legacy stylesheet and are not used by the latest SDK components.
Action required
1. Remove imports of these components from stream-chat-react
in your custom components.
2. If importing SendIconV2
rename it to SendIcon
.
3. Remove the listed classes if used in your CSS.
Component | Details | Removed CSS classes |
---|---|---|
ChatDown | used to be rendered as the default for LoadingErrorIndicator by ChannelListMessenger (the default ChannelList UI component). The default is now a null component (renders null ) | str-chat__down and str-chat__down-main |
DefaultSuggestionListHeader | rendered only with legacy stylesheet in the ChatAutoComplete . As a consequence the AutocompleteSuggestionHeader prop has been removed from Channel props | |
Icons rendered Message component when legacy styles applied | ReplyIcon , DeliveredCheckIcon , ErrorIcon | |
Icons rendered MessageInput component when legacy styles applied | EmojiIconLarge , EmojiIconSmall , FileUploadIcon , FileUploadIconFlat , SendIconV1 (SendIconV2 renamed to SendIcon ) | |
MessageInputSmall | Used to be rendered in Thread , but was deprecated since v10 and replaced by MessageInputFlat | all the classes starting with str-chat__small-message-input |
UploadsPreview | Used to be rendered in MessageInput but was deprecated since v10 and replaced with AttachmentPreviewList | |
FilePreviewer was rendered by UploadsPreview | Used by component removed from the SDK | |
ImagePreviewer was rendered by UploadsPreview | Used by component removed from the SDK | |
AttachmentIcon | Not used by the SDK | |
PictureIcon | Not used by the SDK | |
FileUploadButton | Not used by the SDK | |
ImageUploadButton | Not used by the SDK | |
ThumbnailPlaceholder | Not used by the SDK | |
Thumbnail | Not used by the SDK |
Removal of legacy attachment file icons
The FileIcon
component does not accept argument version
anymore. This parameter used to determine the file icon set. There were two sets - version '1'
and '2'
. The icons of version '1'
have been rendered with legacy stylesheets in the SDK components. The icons displayed under the version '1'
have been removed now.
Action required
Remove prop version
if the FileIcon
is used in your custom components.
Removal of legacy CSS classes
We have removed classes that were used in the legacy CSS stylesheet only and thus are redundant. We recommend to use classes that were already available previously and are used by the SDK stylesheet:
Action required
Replace the removed classes with their alternatives in the custom CSS.
Component | Class removed | Class to be used instead |
---|---|---|
MediaContainer | str-chat__attachment-media | str-chat__attachment |
suggestion list in ReactTextAreaAutocomplete | rta__autocomplete | str-chat__suggestion-list-container |
Avatar root <div/> | str-chat__avatar--circle , str-chat__avatar--square , str-chat__avatar--rounded | str-chat__avatar possibly combined with custom class |
Avatar element <img/> | str-chat__avatar-image--loaded | |
Channel root <div/> | str-chat-channel | str-chat__channel |
ChannelHeader root <div/> | str-chat__header-livestream | str-chat__channel-header |
ChannelHeader root <div/> children | str-chat__header-livestream-left | str-chat__channel-header-end |
ChannelHeader root <div/> children | str-chat__header-livestream-left--title | str-chat__channel-header-title |
ChannelHeader root <div/> children | str-chat__header-livestream-left--subtitle | str-chat__channel-header-subtitle |
ChannelHeader root <div/> children | str-chat__header-livestream-left--members | str-chat__channel-header-info |
ChannelList root <div/> | str-chat-channel-list | str-chat__channel-list |
ChannelPreviewMessenger root <div/> children | str-chat__channel-preview-messenger--right | str-chat__channel-preview-end |
SearchResults root <div/> children | str-chat__channel-search-container | str-chat__channel-search-result-list |
SuggestionList (rendered by ChatAutoComplete ) container <div/> | str-chat__emojisearch | str-chat__suggestion-list-container |
SuggestionList (rendered by ChatAutoComplete ) root <div/> | str-chat__emojisearch__list | str-chat__suggestion-list |
SuggestionListItem (rendered by SuggestionList ) root <div/> | str-chat__emojisearch__item | str-chat__suggestion-list-item |
EmojiPicker root <div/> | str-chat__emojiselect-wrapper (only applied with legacy styles) | str-chat__message-textarea-emoji-picker |
EmojiPicker button | str-chat__input-flat-emojiselect (only applied with legacy styles) | str-chat__emoji-picker-button |
Emoji (rendered by Message ) | inline-text-emoji | the <p/> element has been removed, no substitute class |
MessageRepliesCountButton (rendered by Message ) root <div/> | str-chat__message-simple-reply-button | str-chat__message-replies-count-button-wrapper |
Message wrapper <div/> around MessageStatus & MessageTimestamp | str-chat__message-data , str-chat__message-simple-data | str-chat__message-metadata |
QuotedMessage root <div/> | quoted-message | str-chat__quoted-message-preview |
QuotedMessage bubble | quoted-message-inner | str-chat__quoted-message-bubble |
EditMessageForm | str-chat__edit-message-form-options | no alternative |
EditMessageForm | str-chat__fileupload-wrapper | no alternative |
EditMessageForm | str-chat__input-fileupload | no alternative |
MessageInputFlat root <div/> | all classes starting with str-chat__input-flat | see the current implementation of MessageInputFlat |
QuotedMessagePreviewHeader (rendered by QuotedMessagePreviewHeader ) root <div/> | quoted-message-preview-header | str-chat__quoted-message-preview-header |
QuotedMessagePreviewHeader (rendered by QuotedMessagePreviewHeader ) child <button/> | str-chat__square-button | str-chat__quoted-message-remove |
QuotedMessagePreview root <div/> | quoted-message-preview | no alternative |
QuotedMessagePreview | quoted-message-preview-content | str-chat__quoted-message-preview |
QuotedMessagePreview | quoted-message-preview-content-inner | str-chat__quoted-message-bubble |
MessageList | str-chat__thread--full | no alternative |
InfiniteScroll rendered by MessageList | str-chat__reverse-infinite-scroll | str-chat__message-list-scroll |
ScrollToBottomButton | str-chat__message-notification-right | str-chat__message-notification-scroll-to-latest |
ScrollToBottomButton | str-chat__message-notification-scroll-to-latest-unread-count | str-chat__jump-to-latest-unread-count |
ReactionsListModal | emoji | str-chat__message-reaction-emoji or str-chat__message-reaction-emoji--with-fallback |
SimpleReactionList | str-chat__simple-reactions-list-tooltip | no alternative - markup removal |
Thread | str-chat__list--thread | str-chat__thread-list |
ThreadHeader | str-chat__square-button | str-chat__close-thread-button |
TypingIndicator | str-chat__typing-indicator__avatars | no alternative - markup removal |
Added classes
Migration to non-legacy styles leads to rendering of markup with the following classes:
Action required
Verify your app layout is not broken and adjust the CSS if necessary.
Class | Details |
---|---|
str-chat__main-panel-inner | A <div/> with this class wraps MessageList and VirtualizedMessageList |
Removed types
Action required
Import type alternatives if necessary.
Removed type | Details | To be used instead |
---|---|---|
CustomMessageActionsType | Props for component CustomMessageActionsList , that renders custom messages actions in MessageActionsBox | CustomMessageActionsListProps |
TypingIndicator component without Avatars
The TypingIndicator
component does not render avatars as it used to with legacy stylesheet. Therefore, its prop Avatar
has been removed.
Action optional
Provide custom TypingIndicator
through the Channel
prop.
Updated browser target
Version 12 targets browsers that support ES2020. In particular, the code includes async
functions, optional chaining (?.
), and nullish coalescing (??
). These features have been supported by all major desktop and mobile browsers for years, so it made sense for us to raise the baseline.
The following browsers support ES2020 and should be able to run the SDK as-is:
- Chrome 80 and later
- Safari 14.1 and later on desktops, 14.5 and later on iOS
- Edge 80 and later
- Firefox 80 and later
If you need to support older browsers, you should transpile your bundle using babel
or a similar tool.
Action optional
If you’re targeting browsers that don’t support ES2020, use a transpilation tool like babel
to process your bundle.
Browser bundle removed from the package
Prior to version 12, we included the browser bundle in the package, which could be added to the page using the <script>
tag. We no longer ship the browser bundle.
Using the browser bundle was never recommended, and it was mostly for testing purposes. If you still want to quickly add the SDK using the <script>
tag, you can use services such as https://esm.sh/ or https://www.unpkg.com/.
Installing the package from NPM and then bundling it with your application is still the best way to use the SDK.
- Introducing Threads 2.0
- Introducing WithComponents & Dropping Defaults
- Dropped ComponentContext Defaults
- Audio recordings transcoding
- Unified dialog management
- EmojiPickerIcon extraction to emojis plugin
- Removal of duplicate uploads state in MessageInput
- Date & time formatting
- Avatar changes
- Removal of styling props
- Removal of deprecated components
- Change import of default styles
- Removal of legacy styles
- Updated browser target
- Browser bundle removed from the package