Releases: sendbird/sendbird-uikit-react
Releases · sendbird/sendbird-uikit-react
[v3.9.1] (Dec 8 2023)
Features:
- Improved image loading speed by implementing lazy load with
IntersectionObserver
- Replaced lamejs binary
- Applied the
uikitUploadSizeLimit
to the Open Channel Message Input- Check the file size limit when sending file messages from Open Channel
- Display the modal alert when the file size over the limit
Fixes:
- Fixed a bug where the admin message disappears when sending a message
- Recognized the hash property in the URL
- Fixed a bug where resending MFM fails in the thread
- Group channel user left or banned event should not be ignored
- Removed left 0px from
<Avatar />
component to fix ruined align - Applied StringSet for the file upload limit notification
- Updated currentUserId properly in the channel list initialize step.
- Fixed group channel doesn't move to the top in a channel list even though
latest_last_message
is the default order.
- Fixed group channel doesn't move to the top in a channel list even though
Improvements:
- Divided
<EditUserProfileUI />
into Modal and View parts - Added a message prop to
<ReactionItem />
component - Improved the storybook of
<EmojiReactions />
v3.9.0
[v3.9.0] (Nov 24 2023)
Features:
Typing indicator bubble feature
TypingIndicatorBubble
is a new typing indicator UI that can be turned on through typingIndicatorTypes
option. When turned on, it will be displayed in MessageList
upon receiving typing event in real time.
- Added
typingIndicatorTypes
global option - Added
TypingIndicatorType
enum- How to use?
<App appId={appId} userId={userId} uikitOptions={{ groupChannel: { // Below turns on both bubble and text typing indicators. Default is Text only. typingIndicatorTypes: new Set([TypingIndicatorType.Bubble, TypingIndicatorType.Text]), } }} />
- Added
TypingIndicatorBubble
- How to use?
const moveScroll = (): void => { const current = scrollRef?.current; if (current) { const bottom = current.scrollHeight - current.scrollTop - current.offsetHeight; if (scrollBottom < bottom && scrollBottom < SCROLL_BUFFER) { // Move the scroll as much as the height of the message has changed current.scrollTop += bottom - scrollBottom; } } }; return ( <TypingIndicatorBubble typingMembers={typingMembers} handleScroll={moveScroll} // Scroll to the rendered typing indicator message IFF current scroll is bottom. /> );
Others
- Added support for
eventHandlers.connection.onFailed
callback insetupConnection
. This callback will be called on connection failure- How to use?
<Sendbird appId={appId} userId={undefined} // this will cause an error eventHandlers={{ connection: { onFailed: (error) => { alert(error?.message); // display a browser alert and print the error message inside } } }} >
- Added new props to the
MessageContent
component:renderMessageMenu
,renderEmojiMenu
, andrenderEmojiReactions
- How to use?
<Channel renderMessageContent={(props) => { return <MessageContent {...props} renderMessageMenu={(props) => { return <MessageMenu {...props} /> }} renderEmojiMenu={(props) => { return <MessageEmojiMenu {...props} /> }} renderEmojiReactions={(props) => { return <EmojiReactions {...props} /> }} /> }} />
- Added
onProfileEditSuccess
prop toApp
andChannelList
components - Added
renderFrozenNotification
inChannelUIProps
- How to use?
<Channel channelUrl={channelUrl} renderFrozenNotification={() => { return ( <div className="sendbird-notification sendbird-notification--frozen sendbird-conversation__messages__notification" >My custom Frozen Notification</div> ); }} />
- Exported
VoiceMessageInputWrapper
anduseHandleUploadFiles
- How to use?
import { useHandleUploadFiles } from '@sendbird/uikit-react/Channel/hooks/useHandleUploadFiles' import { VoiceMessageInputWrapper, VoiceMessageInputWrapperProps } from '@sendbird/uikit-react/Channel/components/MessageInput'
Fixes:
- Fixed a bug where setting
startingPoint
scrolls to the middle of the target message when it should be at the top of the message - Applied dark theme to the slide left icon
- Fixed a bug where changing current channel not clearing pending and failed messages from the previous channel
- Fixed a bug where the thumbnail image of
OGMessage
being displayed as not fitting the container - Fixed a bug where resending a failed message in
Thread
results in displaying resulting message inChannel
- Fixed a bug where unread message notification not being removed when scroll reaches bottom
Improvement:
- Channels list no longer displays unread message count badge for focused channel
[v3.8.2] (Nov 10 2023)
Features:
MessageContent
is not customizable with three new optional properties:renderSenderProfile
,renderMessageBody
, andrenderMessageHeader
- How to use?
import Channel from '@sendbird/uikit-react/Channel' import { useSendbirdStateContext } from '@sendbird/uikit-react/useSendbirdStateContext' import { useChannelContext } from '@sendbird/uikit-react/Channel/context' import MessageContent from '@sendbird/uikit-react/ui/MessageContent' const CustomChannel = () => { const { config } = useSendbirdStateContext(); const { userId } = config; const { currentGroupChannel } = useChannelContext(); return ( <Channel ... renderMessage={({ message }) => { return ( <MessageContent userId={userId} channel={currentGroupChannel} message={message} ... renderSenderProfile={(props: MessageProfileProps) => ( <MessageProfile {...props}/> )} renderMessageBody={(props: MessageBodyProps) => ( <MessageBody {...props}/> )} renderMessageHeader={(props: MessageHeaderProps) => ( <MessageHeader {...props}/> )} /> ) }} /> ) }
Fixes:
- Fix runtime error due to publishing modules
- Add missing date locale to the
UnreadCount
banner since string - Use the more impactful value between the
resizingWidth
andresizingHeight
- So, the original images' ratio won't be broken
- Apply the
ImageCompression
to theThread
module - Apply the
ImageCompression
for sending file message and multiple files message
Improvements:
- Use
channel.members
instead of fetching for non-super group channels in theSuggestedMentionList
[v3.8.1] (Nov 10 2023) - DEPRECATED
[v3.8.1] (Nov 10 2023)
Features:
MessageContent
is not customizable with three new optional properties:renderSenderProfile
,renderMessageBody
, andrenderMessageHeader
- How to use?
import Channel from '@sendbird/uikit-react/Channel' import { useSendbirdStateContext } from '@sendbird/uikit-react/useSendbirdStateContext' import { useChannelContext } from '@sendbird/uikit-react/Channel/context' import MessageContent from '@sendbird/uikit-react/ui/MessageContent' const CustomChannel = () => { const { config } = useSendbirdStateContext(); const { userId } = config; const { currentGroupChannel } = useChannelContext(); return ( <Channel ... renderMessage={({ message }) => { return ( <MessageContent userId={userId} channel={currentGroupChannel} message={message} ... renderSenderProfile={(props: MessageProfileProps) => ( <MessageProfile {...props}/> )} renderMessageBody={(props: MessageBodyProps) => ( <MessageBody {...props}/> )} renderMessageHeader={(props: MessageHeaderProps) => ( <MessageHeader {...props}/> )} /> ) }} /> ) }
Fixes:
- Fix runtime error due to publishing modules
- Add missing date locale to the
UnreadCount
banner since string - Use the more impactful value between the
resizingWidth
andresizingHeight
- So, the original images' ratio won't be broken
- Apply the
ImageCompression
to theThread
module - Apply the
ImageCompression
for sending file message and multiple files message
Improvements:
- Use
channel.members
instead of fetching for non-super group channels in theSuggestedMentionList
[v3.8.0] (Nov 3 2023)
Feat:
- Added a feature to support predefined suggested reply options for AI chatbot trigger messages.
- Introduced custom date format string sets, allowing users to customize the date format for
DateSeparators
andUnreadCount
. - Exported the
initialMessagesFetch
callback from the hook to provide more flexibility in UIKit customization.
Fixes:
- Removed duplicate
UserProfileProvider
in `OpenChannelSettings``. - Removed the logic blocking the addition of empty channels to the ChannelList.
- Fixed a runtime error in empty channels.
- Added precise object dependencies in effect hooks to prevent unnecessary re-renders in the Channel module.
Chores:
- Migrated the rest of modules & UI components to TypeScript from Javascript.
- Introduced new build settings:
- Changes have been made to export modules using the sub-path exports in the
package.json
. If you were using the package in a Native CJS environment, this might have an impact.
In that case, you can migrate the path as follows:- const ChannelList = require('@sendbird/uikit-react/cjs/ChannelList'); + const ChannelList = require('@sendbird/uikit-react/ChannelList');
- TypeScript support also has been improved. Now, precise types based on the source code are used.
- Changes have been made to export modules using the sub-path exports in the
[v3.7.0] (Oct 23 2023)
Multiple Files Message
Now we are supporting Multiple Files Message feature!
You can select some multiple files in the message inputs, and send multiple images in one message.
If you select several types of files, only images will be combined in the message and the other files will be sent separately.
Also we have resolved many issues found during QA.
How to enable this feature?
You can turn it on in four places.
- App Component
import App from '@sendbird/uikit-react/App'
<App
...
isMultipleFilesMessageEnabled
/>
- SendbirdProvider
import { SendbirdProvider } from '@sendbird/uikit-react/SendbirdProvider'
<SendbirdProvider
...
isMultipleFilesMessageEnabled
>
{...}
</SendbirdProvider>
- Channel
import Channel from '@sendbird/uikit-react/Channel';
import { ChannelProvider } from '@sendbird/uikit-react/Channel/context';
<Channel
...
isMultipleFilesMessageEnabled
/>
<ChannelProvider
...
isMultipleFilesMessageEnabled
>
{...}
</ChannelProvider>
- Thread
import Thread from '@sendbird/uikit-react/Thread';
import { ThreadProvider } from '@sendbird/uikit-react/Thread/context';
<Thread
...
isMultipleFilesMessageEnabled
/>
<ThreadProvider
...
isMultipleFilesMessageEnabled
>
{...}
</ThreadProvider>
Interface change/publish
- The properties of the
ChannelContext
andThreadContext
has been changed little bit.allMessages
of the ChannelContext has been divided intoallMessages
andlocalMessages
allThreadMessages
of the ThreadContext has been divided intoallThreadMessages
andlocalThreadMessages
- Each local messages includes
pending
andfailed
messages, and the all messages will contain onlysucceeded
messages - Please keep in mind, you have to migrate to using the local messages, IF you have used the
local messages
to draw your custom message components.
- pubSub has been published
publishingModules
has been added to the payload of pubSub.publish
You can specify the particular modules that you propose for event publishing
import { useCallback } from 'react' import { SendbirdProvider, useSendbirdStateContext } from '@sendbird/uikit-react/SendbirdProvider' import { PUBSUB_TOPICS as topics, PublishingModuleTypes } from '@sendbird/uikit-react/pubSub/topics' const CustomApp = () => { const globalState = useSendbirdStateContext(); const { stores, config } = globalState; const { sdk, initialized } = stores.sdkStore; const { pubSub } = config; const onSendFileMessageOnlyInChannel = useCallback((channel, params) => { channel.sendFileMessage(params) .onPending((pendingMessage) => { pubSub.publish(topics.SEND_MESSAGE_START, { channel, message: pendingMessage, publishingModules: [PublishingModuleTypes.CHANNEL], }); }) .onFailed((failedMessage) => { pubSub.publish(topics.SEND_MESSAGE_FAILED, { channel, message: failedMessage, publishingModules: [PublishingModuleTypes.CHANNEL], }); }) .onSucceeded((succeededMessage) => { pubSub.publish(topics.SEND_FILE_MESSAGE, { channel, message: succeededMessage, publishingModules: [PublishingModuleTypes.CHANNEL], }); }) }, []); return (<>...</>) }; const App = () => ( <SendbirdProvider> <CustomApp /> </SendbirdProvider> );
Fixes:
- Improve the pubSub&dispatch logics
- Allow deleting failed messages
- Check applicationUserListQuery.isLoading before fetching user list
- Fix the error message: "Query in progress."
- Fix missed or wrong type definitions
quoteMessage
of ChannelProviderInterfaceuseEditUserProfileProviderContext
has been renamed touseEditUserProfileContext
import { useEditUserProfileProviderContext } from '@sendbird/uikit-react/EditUserProfile/context' // to import { useEditUserProfileContext } from '@sendbird/uikit-react/EditUserProfile/context'
[v3.6.10] (Oct 11 2023)
Fixes:
- (in Safari) Display the placeholder of the MessageInput when the input text is cleared
- Remove duplicated CSS line
- (in iOS) fix focusing on the chat screen starts from the top in Mobile device
- Move to the top in the ChannelList when the current user but a different peer sends a message
[v3.6.9] (Oct 6 2023)
[v3.6.9] (Oct 6 2023)
Fixes:
- (in Safari) Display the placeholder of the MessageInput when the input text is cleared
- Remove duplicated CSS line
- Able to see the quoted messages regardless of the ReplyType
- Improve the types of the function props of
ui/MessageInput
componentinterface MessageInputProps { ... onFileUpload?: (fileList: FileList) => void; onSendMessage?: (props: { message: string, mentionTemplate: string }) => void; onUpdateMessage?: (props: { messageId: string, message: string, mentionTemplate: string }) => void; }
- Move to the channel list when current user is banned or the channel is deleted in MobileLayout
- Add new iconColor: THUMBNAIL_ICON which doesn't change by theme
- Add some props types that we have missed in the public interface
- ChannelProvider
- Add
interface ChannelContextProps { onBeforeSendVoiceMessage?: (file: File, quotedMessage?: SendableMessageType) => FileMessageCreateParams; }
- Usage
import { ChannelProvider } from '@sendbird/uikit-react/Channel/context' <ChannelProvider onBeforeSendVoiceMessage={() => {}} />
- Add
- ThreadProvider
- Add
interface ThreadProviderProps { onBeforeSendUserMessage?: (message: string, quotedMessage?: SendableMessageType) => UserMessageCreateParams; onBeforeSendFileMessage?: (file: File, quotedMessage?: SendableMessageType) => FileMessageCreateParams; onBeforeSendVoiceMessage?: (file: File, quotedMessage?: SendableMessageType) => FileMessageCreateParams; }
- Usage
import { ThreadProvider } from '@sendbird/uikit-react/Thread/context' <ThreadProvider onBeforeSendUserMessage={() => {}} onBeforeSendFileMessage={() => {}} onBeforeSendVoiceMessage={() => {}} />
- Add
- ui/Button
- Add
enum ButtonTypes { PRIMARY = 'PRIMARY', SECONDARY = 'SECONDARY', DANGER = 'DANGER', DISABLED = 'DISABLED', } enum ButtonSizes { BIG = 'BIG', SMALL = 'SMALL', }
- Usage
import Button, { ButtonTypes, ButtonSizes } from '@sendbird/uikit-react/ui/Button' <Button type={ButtonTypes.PRIMARY} size={ButtonSizes.BIG} />
- Add
- ui/Icon
- Add
export enum IconTypes { ADD = 'ADD', ARROW_LEFT = 'ARROW_LEFT', ATTACH = 'ATTACH', AUDIO_ON_LINED = 'AUDIO_ON_LINED', BAN = 'BAN', BROADCAST = 'BROADCAST', CAMERA = 'CAMERA', CHANNELS = 'CHANNELS', CHAT = 'CHAT', CHAT_FILLED = 'CHAT_FILLED', CHEVRON_DOWN = 'CHEVRON_DOWN', CHEVRON_RIGHT = 'CHEVRON_RIGHT', CLOSE = 'CLOSE', COLLAPSE = 'COLLAPSE', COPY = 'COPY', CREATE = 'CREATE', DELETE = 'DELETE', DISCONNECTED = 'DISCONNECTED', DOCUMENT = 'DOCUMENT', DONE = 'DONE', DONE_ALL = 'DONE_ALL', DOWNLOAD = 'DOWNLOAD', EDIT = 'EDIT', EMOJI_MORE = 'EMOJI_MORE', ERROR = 'ERROR', EXPAND = 'EXPAND', FILE_AUDIO = 'FILE_AUDIO', FILE_DOCUMENT = 'FILE_DOCUMENT', FREEZE = 'FREEZE', GIF = 'GIF', INFO = 'INFO', LEAVE = 'LEAVE', MEMBERS = 'MEMBERS', MESSAGE = 'MESSAGE', MODERATIONS = 'MODERATIONS', MORE = 'MORE', MUTE = 'MUTE', NOTIFICATIONS = 'NOTIFICATIONS', NOTIFICATIONS_OFF_FILLED = 'NOTIFICATIONS_OFF_FILLED', OPERATOR = 'OPERATOR', PHOTO = 'PHOTO', PLAY = 'PLAY', PLUS = 'PLUS', QUESTION = 'QUESTION', REFRESH = 'REFRESH', REPLY = 'REPLY', REMOVE = 'REMOVE', SEARCH = 'SEARCH', SEND = 'SEND', SETTINGS_FILLED = 'SETTINGS_FILLED', SLIDE_LEFT = 'SLIDE_LEFT', SPINNER = 'SPINNER', SUPERGROUP = 'SUPERGROUP', THREAD = 'THREAD', THUMBNAIL_NONE = 'THUMBNAIL_NONE', TOGGLE_OFF = 'TOGGLE_OFF', TOGGLE_ON = 'TOGGLE_ON', USER = 'USER', } export enum IconColors { DEFAULT = 'DEFAULT', PRIMARY = 'PRIMARY', PRIMARY_2 = 'PRIMARY_2', SECONDARY = 'SECONDARY', CONTENT = 'CONTENT', CONTENT_INVERSE = 'CONTENT_INVERSE', WHITE = 'WHITE', GRAY = 'GRAY', THUMBNAIL_ICON = 'THUMBNAIL_ICON', SENT = 'SENT', READ = 'READ', ON_BACKGROUND_1 = 'ON_BACKGROUND_1', ON_BACKGROUND_2 = 'ON_BACKGROUND_2', ON_BACKGROUND_3 = 'ON_BACKGROUND_3', ON_BACKGROUND_4 = 'ON_BACKGROUND_4', BACKGROUND_3 = 'BACKGROUND_3', ERROR = 'ERROR', }
- Usage
import Icon, { IconTypes, IconColors } from '@sendbird/uikit-react/ui/Icon' <Icon type={IconTypes.INFO} fillColor={IconColors.PRIMARY} />
- Add
- ChannelProvider
[v3.6.8] (Sep 1 2023)
[v3.6.8] (Sep 1 2023)
Feats:
- Update
ui/FileViewer
to support multiple images- Modify the props structure
export enum ViewerTypes { SINGLE = 'SINGLE', MULTI = 'MULTI', } interface SenderInfo { profileUrl: string; nickname: string; } interface FileInfo { name: string; type: string; url: string; } interface BaseViewer { onClose: (e: React.MouseEvent) => void; } interface SingleFileViewer extends SenderInfo, FileInfo, BaseViewer { viewerType?: typeof ViewerTypes.SINGLE; isByMe?: boolean; disableDelete?: boolean; onDelete: (e: React.MouseEvent) => void; } interface MultiFilesViewer extends SenderInfo, BaseViewer { viewerType: typeof ViewerTypes.MULTI; fileInfoList: FileInfo[]; currentIndex: number; onClickLeft: () => void; onClickRight: () => void; } export type FileViewerComponentProps = SingleFileViewer | MultiFilesViewer;
- Modify the props structure
- Export misc. utils
Channel/utils/getMessagePartsInfo
Channel/utils/compareMessagesForGrouping
Message/hooks/useDirtyGetMentions
ui/MessageInput/hooks/usePaste
Fixes:
- Apply some props which are related to the
metadata
to the ChannelListQuery- Add metadataKey, metadataValues, and metadataStartsWith to the Channel.queries.channelListQuery
- How to use
<Channel or ChannelProvider queries={{ channelListQuery: { metadataKey: 'isMatching', metadataValues: ['true'], } }} />
- Improve types of
ui/FileViewer
andChannel/component/FileViewer
- Add some props that have been missed
- Fix
<ImageRenderer />
not converting number to pixel string - Modify the types on useChannelContext & useThreadContext
useChannelContext.setQuoteMessage
should acceptUserMessage | FileMessage
useThreadContext.sendMessage
should bestring
[v3.6.7] (Aug 11 2023)
Feats:
- Added a new ImageGrid UI component (for internal use only) (#703)
- Introduced
fetchChannelList
to theChannelListContext
.- Implemented a custom hook function
useFetchChannelList
. - Utilized this function to fetch the channel list within the
ChannelListUI
component. - Added relevant tests for this function.
- Provided the method through the
ChannelListContext
:fetchChannelList
.
Example Usage:import SendbirdProvider from '@sendbird/uikit-react/SendbirdProvider' import useSendbirdStateContext from '@sendbird/uikit-react/useSendbirdStateContext' import { ChannelListProvider, useChannelListContext } from '@sendbird/uikit-react/ChannelList/context' const isAboutSame = (a, b, px) => (Math.abs(a - b) <= px); const CustomChannelList = () => { const { allChannels, fetchChannelList, } = useChannelListContext(); return ( <div className="custom-channel-list" onScroll={(e) => { const target = e.target; if (isAboutSame(target.clientHeight + target.scrollTop, target.scrollHeight, 10)) { fetchChannelList(); } }} > {allChannels.map((channel) => { return // custom channel list item })} </div> ); }; const CustomApp = () => { return ( <div className="custom-app"> <SendbirdProvider ... > <ChannelListProvider ... > <CustomChannelList /> </ChannelListProvider> </SendbirdProvider> </div> ); };
- Implemented a custom hook function
Fixes:
- Removed duplicated getEmoji API call from the
useGetChannel
hook (#705). - Fixed missing
SEND_MESSAGE_FAILED
event publishing (#704):- Addressed the failure state in
sendbirdSelectors.getSendUserMessage
and published theSEND_MESSAGE_FAILED
event. - Corrected typo
SEND_MESSAGEGE_FAILURE
.
- Addressed the failure state in