Features
-
renderUserProfilenow also applies to the profile popup opened by clicking an@mentionPreviously the
@mentionpopup always showed the default UI and ignoredrenderUserProfile(unlike avatar clicks). It now honorsrenderUserProfileanddisableUserProfile, consistent with the other profile popups. This only affects apps that already providerenderUserProfile. -
Added
onBeforeStartDirectMessageto customize the 1:1 channel created from the profile popup's Message buttonThis optional prop on
SendbirdProvider(andApp) runs right before the default profile popup creates the channel, so you can adjust the creation parameters — for example setisDistinct: trueor attachdata/customType. The callback also receives the targetusers.import SendbirdProvider from '@sendbird/uikit-react/SendbirdProvider'; <SendbirdProvider appId={APP_ID} userId={USER_ID} onBeforeStartDirectMessage={(channelParams, users) => ({ ...channelParams, isDistinct: true, data: JSON.stringify({ source: 'mention' }), })} > {/* ... */} </SendbirdProvider>
Whether
onBeforeStartDirectMessageruns together withrenderUserProfiledepends on whether your custom popup keeps the built-in<UserProfile>.Wrapping the built-in popup —
onBeforeStartDirectMessagestill runs, because<UserProfile>(and its Message button) is still rendered:import UserProfile from '@sendbird/uikit-react/ui/UserProfile'; <SendbirdProvider appId={APP_ID} userId={USER_ID} onBeforeStartDirectMessage={(channelParams) => ({ ...channelParams, isDistinct: true })} renderUserProfile={({ user, currentUserId, close }) => ( <MyCard> <MyHeader /> <UserProfile user={user} currentUserId={currentUserId} onSuccess={close} /> </MyCard> )} > {/* ... */} </SendbirdProvider>
Fully replacing the popup —
<UserProfile>is not rendered, soonBeforeStartDirectMessagedoes not run; create the channel yourself with thegetCreateGroupChannelselector:import { useSendbird, sendbirdSelectors } from '@sendbird/uikit-react'; import type { User } from '@sendbird/chat'; // A custom popup replaces the default one, so it creates the channel itself. function MyProfileCard({ user, currentUserId, close }: { user: User; currentUserId: string; close: () => void }) { const { state } = useSendbird(); const createChannel = sendbirdSelectors.getCreateGroupChannel(state); const startDirectMessage = async () => { close(); await createChannel({ isDistinct: true, invitedUserIds: [user.userId], operatorUserIds: [currentUserId], data: JSON.stringify({ source: 'profile-popup' }), }); }; return ( <div> <img src={user.profileUrl} alt="" /> <span>{user.nickname}</span> <button onClick={startDirectMessage}>Message</button> </div> ); } <SendbirdProvider appId={APP_ID} userId={USER_ID} renderUserProfile={(props) => <MyProfileCard {...props} />}> {/* ... */} </SendbirdProvider>
Fixes
- Fixed an issue introduced in v3.18.3 where
initializeThreadFetcher,fetchPrevThreads, andfetchNextThreadsfromuseThreadContext()returnedundefined— soawait/.then()on them threw — and passed the entire accumulated reply list to their callback instead of the newly fetched page - Fixed failed file and voice messages in a thread keep their local file preview
- Changed
sendMultipleFilesMessagefromuseThreadContext()rejects on fewer than two files or a missing channel, instead of resolvingnull - Changed
sendFileMessagefromuseThreadContext()rejects when no channel is available, instead of resolvingnull - Fixed a bug where the
GroupChannelmessage list could fail to load for around two and a half minutes when the provider remounted while the network was stalled