@@ -91,7 +91,7 @@ export interface GroupChannelContextType extends ContextBaseType, MessageListDat
9191 isScrollBottomReached : boolean ;
9292 setIsScrollBottomReached : React . Dispatch < React . SetStateAction < boolean > > ;
9393
94- scrollToBottom : ( ) => void ;
94+ scrollToBottom : ( animated ?: boolean ) => void ;
9595 scrollToMessage : ( createdAt : number , messageId : number ) => void ;
9696 toggleReaction ( message : SendableMessageType , emojiKey : string , isReacted : boolean ) : void ;
9797}
@@ -145,7 +145,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
145145 const [ fetchChannelError , setFetchChannelError ] = useState < SendbirdError > ( null ) ;
146146
147147 // Ref
148- const { scrollRef, scrollPubSub, scrollDistanceFromBottomRef, isScrollBottomReached, setIsScrollBottomReached } = useMessageListScroll ( ) ;
148+ const { scrollRef, scrollPubSub, scrollDistanceFromBottomRef, isScrollBottomReached, setIsScrollBottomReached } = useMessageListScroll ( scrollBehavior ) ;
149149 const messageInputRef = useRef ( null ) ;
150150
151151 const toggleReaction = useToggleReactionCallback ( currentChannel , config . logger ) ;
@@ -179,7 +179,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
179179 } ,
180180 onMessagesReceived : ( ) => {
181181 if ( isScrollBottomReached && isContextMenuClosed ( ) ) {
182- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
182+ scrollPubSub . publish ( 'scrollToBottom' , { } ) ;
183183 }
184184 } ,
185185 onChannelDeleted : ( ) => {
@@ -211,7 +211,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
211211
212212 if ( viewUpdated ) {
213213 const bottomOffset = prevViewInfo . scrollHeight - prevViewInfo . scrollTop ;
214- scrollPubSub . publish ( 'scroll' , { top : nextViewInfo . scrollHeight - bottomOffset , lazy : false } ) ;
214+ scrollPubSub . publish ( 'scroll' , { top : nextViewInfo . scrollHeight - bottomOffset , lazy : false , animated : false } ) ;
215215 }
216216 } ) ;
217217 } ) ;
@@ -232,7 +232,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
232232 const viewUpdated = prevViewInfo . scrollHeight < nextViewInfo . scrollHeight ;
233233
234234 if ( viewUpdated ) {
235- scrollPubSub . publish ( 'scroll' , { top : prevViewInfo . scrollTop , lazy : false } ) ;
235+ scrollPubSub . publish ( 'scroll' , { top : prevViewInfo . scrollTop , lazy : false , animated : false } ) ;
236236 }
237237 } ) ;
238238 } ) ;
@@ -273,22 +273,22 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
273273 preventDuplicateRequest . lock ( ) ;
274274 await preventDuplicateRequest . run ( ( ) => {
275275 return new Promise < void > ( ( resolve ) => {
276- scrollPubSub . publish ( 'scrollToBottom' , resolve ) ;
276+ scrollPubSub . publish ( 'scrollToBottom' , { resolve, animated : false } ) ;
277277 } ) ;
278278 } ) ;
279279 preventDuplicateRequest . release ( ) ;
280280 }
281281
282282 const onSentMessageFromOtherModule = ( data : PubSubSendMessagePayload ) => {
283- if ( data . channel . url === channelUrl ) scrollPubSub . publish ( 'scrollToBottom' , null ) ;
283+ if ( data . channel . url === channelUrl ) scrollPubSub . publish ( 'scrollToBottom' , { } ) ;
284284 } ;
285285 const subscribes = [
286286 config . pubSub . subscribe ( PUBSUB_TOPICS . SEND_USER_MESSAGE , onSentMessageFromOtherModule ) ,
287287 config . pubSub . subscribe ( PUBSUB_TOPICS . SEND_FILE_MESSAGE , onSentMessageFromOtherModule ) ,
288288 ] ;
289289 return ( ) => {
290290 subscribes . forEach ( ( subscribe ) => subscribe . remove ( ) ) ;
291- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
291+ scrollPubSub . publish ( 'scrollToBottom' , { animated : false } ) ;
292292 } ;
293293 } , [ messageDataSource . initialized , channelUrl ] ) ;
294294
@@ -297,7 +297,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
297297 if ( typeof startingPoint === 'number' ) {
298298 // We do not handle animation for message search here.
299299 // Please update the animatedMessageId prop to trigger the animation.
300- scrollToMessage ( startingPoint , 0 , false ) ;
300+ scrollToMessage ( startingPoint , 0 , false , false ) ;
301301 }
302302 } , [ startingPoint ] ) ;
303303
@@ -306,17 +306,17 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
306306 if ( _animatedMessageId ) setAnimatedMessageId ( _animatedMessageId ) ;
307307 } , [ _animatedMessageId ] ) ;
308308
309- const scrollToBottom = usePreservedCallback ( async ( ) => {
309+ const scrollToBottom = usePreservedCallback ( async ( animated ?: boolean ) => {
310310 if ( ! scrollRef . current ) return ;
311311
312312 setAnimatedMessageId ( null ) ;
313313 setIsScrollBottomReached ( true ) ;
314314
315315 if ( config . isOnline && messageDataSource . hasNext ( ) ) {
316316 await messageDataSource . resetWithStartingPoint ( Number . MAX_SAFE_INTEGER ) ;
317- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
317+ scrollPubSub . publish ( 'scrollToBottom' , { animated } ) ;
318318 } else {
319- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
319+ scrollPubSub . publish ( 'scrollToBottom' , { animated } ) ;
320320 }
321321
322322 if ( currentChannel && ! messageDataSource . hasNext ( ) ) {
@@ -325,43 +325,45 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
325325 }
326326 } ) ;
327327
328- const scrollToMessage = usePreservedCallback ( async ( createdAt : number , messageId : number , animated = true ) => {
329- // NOTE: To prevent multiple clicks on the message in the channel while scrolling
330- // Check if it can be replaced with event.stopPropagation()
331- const element = scrollRef . current ;
332- const parentNode = element ?. parentNode as HTMLDivElement ;
333- const clickHandler = {
334- activate ( ) {
335- if ( ! element || ! parentNode ) return ;
336- element . style . pointerEvents = 'auto' ;
337- parentNode . style . cursor = 'auto' ;
338- } ,
339- deactivate ( ) {
340- if ( ! element || ! parentNode ) return ;
341- element . style . pointerEvents = 'none' ;
342- parentNode . style . cursor = 'wait' ;
343- } ,
344- } ;
345-
346- clickHandler . deactivate ( ) ;
347-
348- setAnimatedMessageId ( null ) ;
349- const message = messageDataSource . messages . find ( ( it ) => it . messageId === messageId || it . createdAt === createdAt ) ;
350- if ( message ) {
351- const topOffset = getMessageTopOffset ( message . createdAt ) ;
352- if ( topOffset ) scrollPubSub . publish ( 'scroll' , { top : topOffset } ) ;
353- if ( animated ) setAnimatedMessageId ( messageId ) ;
354- } else {
355- await messageDataSource . resetWithStartingPoint ( createdAt ) ;
356- setTimeout ( ( ) => {
357- const topOffset = getMessageTopOffset ( createdAt ) ;
358- if ( topOffset ) scrollPubSub . publish ( 'scroll' , { top : topOffset , lazy : false } ) ;
359- if ( animated ) setAnimatedMessageId ( messageId ) ;
360- } ) ;
361- }
328+ const scrollToMessage = usePreservedCallback (
329+ async ( createdAt : number , messageId : number , messageFocusAnimated ?: boolean , scrollAnimated ?: boolean ) => {
330+ // NOTE: To prevent multiple clicks on the message in the channel while scrolling
331+ // Check if it can be replaced with event.stopPropagation()
332+ const element = scrollRef . current ;
333+ const parentNode = element ?. parentNode as HTMLDivElement ;
334+ const clickHandler = {
335+ activate ( ) {
336+ if ( ! element || ! parentNode ) return ;
337+ element . style . pointerEvents = 'auto' ;
338+ parentNode . style . cursor = 'auto' ;
339+ } ,
340+ deactivate ( ) {
341+ if ( ! element || ! parentNode ) return ;
342+ element . style . pointerEvents = 'none' ;
343+ parentNode . style . cursor = 'wait' ;
344+ } ,
345+ } ;
346+
347+ clickHandler . deactivate ( ) ;
348+
349+ setAnimatedMessageId ( null ) ;
350+ const message = messageDataSource . messages . find ( ( it ) => it . messageId === messageId || it . createdAt === createdAt ) ;
351+ if ( message ) {
352+ const topOffset = getMessageTopOffset ( message . createdAt ) ;
353+ if ( topOffset ) scrollPubSub . publish ( 'scroll' , { top : topOffset , animated : scrollAnimated } ) ;
354+ if ( messageFocusAnimated ?? true ) setAnimatedMessageId ( messageId ) ;
355+ } else {
356+ await messageDataSource . resetWithStartingPoint ( createdAt ) ;
357+ setTimeout ( ( ) => {
358+ const topOffset = getMessageTopOffset ( createdAt ) ;
359+ if ( topOffset ) scrollPubSub . publish ( 'scroll' , { top : topOffset , lazy : false , animated : scrollAnimated } ) ;
360+ if ( messageFocusAnimated ?? true ) setAnimatedMessageId ( messageId ) ;
361+ } ) ;
362+ }
362363
363- clickHandler . activate ( ) ;
364- } ) ;
364+ clickHandler . activate ( ) ;
365+ } ,
366+ ) ;
365367
366368 const messageActions = useMessageActions ( { ...props , ...messageDataSource , scrollToBottom, quoteMessage, replyType } ) ;
367369
0 commit comments