@@ -91,7 +91,7 @@ export interface GroupChannelContextType extends ContextBaseType, MessageListDat
91
91
isScrollBottomReached : boolean ;
92
92
setIsScrollBottomReached : React . Dispatch < React . SetStateAction < boolean > > ;
93
93
94
- scrollToBottom : ( ) => void ;
94
+ scrollToBottom : ( animated ?: boolean ) => void ;
95
95
scrollToMessage : ( createdAt : number , messageId : number ) => void ;
96
96
toggleReaction ( message : SendableMessageType , emojiKey : string , isReacted : boolean ) : void ;
97
97
}
@@ -145,7 +145,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
145
145
const [ fetchChannelError , setFetchChannelError ] = useState < SendbirdError > ( null ) ;
146
146
147
147
// Ref
148
- const { scrollRef, scrollPubSub, scrollDistanceFromBottomRef, isScrollBottomReached, setIsScrollBottomReached } = useMessageListScroll ( ) ;
148
+ const { scrollRef, scrollPubSub, scrollDistanceFromBottomRef, isScrollBottomReached, setIsScrollBottomReached } = useMessageListScroll ( scrollBehavior ) ;
149
149
const messageInputRef = useRef ( null ) ;
150
150
151
151
const toggleReaction = useToggleReactionCallback ( currentChannel , config . logger ) ;
@@ -179,7 +179,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
179
179
} ,
180
180
onMessagesReceived : ( ) => {
181
181
if ( isScrollBottomReached && isContextMenuClosed ( ) ) {
182
- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
182
+ scrollPubSub . publish ( 'scrollToBottom' , { } ) ;
183
183
}
184
184
} ,
185
185
onChannelDeleted : ( ) => {
@@ -211,7 +211,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
211
211
212
212
if ( viewUpdated ) {
213
213
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 } ) ;
215
215
}
216
216
} ) ;
217
217
} ) ;
@@ -232,7 +232,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
232
232
const viewUpdated = prevViewInfo . scrollHeight < nextViewInfo . scrollHeight ;
233
233
234
234
if ( viewUpdated ) {
235
- scrollPubSub . publish ( 'scroll' , { top : prevViewInfo . scrollTop , lazy : false } ) ;
235
+ scrollPubSub . publish ( 'scroll' , { top : prevViewInfo . scrollTop , lazy : false , animated : false } ) ;
236
236
}
237
237
} ) ;
238
238
} ) ;
@@ -273,22 +273,22 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
273
273
preventDuplicateRequest . lock ( ) ;
274
274
await preventDuplicateRequest . run ( ( ) => {
275
275
return new Promise < void > ( ( resolve ) => {
276
- scrollPubSub . publish ( 'scrollToBottom' , resolve ) ;
276
+ scrollPubSub . publish ( 'scrollToBottom' , { resolve, animated : false } ) ;
277
277
} ) ;
278
278
} ) ;
279
279
preventDuplicateRequest . release ( ) ;
280
280
}
281
281
282
282
const onSentMessageFromOtherModule = ( data : PubSubSendMessagePayload ) => {
283
- if ( data . channel . url === channelUrl ) scrollPubSub . publish ( 'scrollToBottom' , null ) ;
283
+ if ( data . channel . url === channelUrl ) scrollPubSub . publish ( 'scrollToBottom' , { } ) ;
284
284
} ;
285
285
const subscribes = [
286
286
config . pubSub . subscribe ( PUBSUB_TOPICS . SEND_USER_MESSAGE , onSentMessageFromOtherModule ) ,
287
287
config . pubSub . subscribe ( PUBSUB_TOPICS . SEND_FILE_MESSAGE , onSentMessageFromOtherModule ) ,
288
288
] ;
289
289
return ( ) => {
290
290
subscribes . forEach ( ( subscribe ) => subscribe . remove ( ) ) ;
291
- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
291
+ scrollPubSub . publish ( 'scrollToBottom' , { animated : false } ) ;
292
292
} ;
293
293
} , [ messageDataSource . initialized , channelUrl ] ) ;
294
294
@@ -297,7 +297,7 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
297
297
if ( typeof startingPoint === 'number' ) {
298
298
// We do not handle animation for message search here.
299
299
// Please update the animatedMessageId prop to trigger the animation.
300
- scrollToMessage ( startingPoint , 0 , false ) ;
300
+ scrollToMessage ( startingPoint , 0 , false , false ) ;
301
301
}
302
302
} , [ startingPoint ] ) ;
303
303
@@ -306,17 +306,17 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
306
306
if ( _animatedMessageId ) setAnimatedMessageId ( _animatedMessageId ) ;
307
307
} , [ _animatedMessageId ] ) ;
308
308
309
- const scrollToBottom = usePreservedCallback ( async ( ) => {
309
+ const scrollToBottom = usePreservedCallback ( async ( animated ?: boolean ) => {
310
310
if ( ! scrollRef . current ) return ;
311
311
312
312
setAnimatedMessageId ( null ) ;
313
313
setIsScrollBottomReached ( true ) ;
314
314
315
315
if ( config . isOnline && messageDataSource . hasNext ( ) ) {
316
316
await messageDataSource . resetWithStartingPoint ( Number . MAX_SAFE_INTEGER ) ;
317
- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
317
+ scrollPubSub . publish ( 'scrollToBottom' , { animated } ) ;
318
318
} else {
319
- scrollPubSub . publish ( 'scrollToBottom' , null ) ;
319
+ scrollPubSub . publish ( 'scrollToBottom' , { animated } ) ;
320
320
}
321
321
322
322
if ( currentChannel && ! messageDataSource . hasNext ( ) ) {
@@ -325,43 +325,45 @@ export const GroupChannelProvider = (props: GroupChannelProviderProps) => {
325
325
}
326
326
} ) ;
327
327
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
+ }
362
363
363
- clickHandler . activate ( ) ;
364
- } ) ;
364
+ clickHandler . activate ( ) ;
365
+ } ,
366
+ ) ;
365
367
366
368
const messageActions = useMessageActions ( { ...props , ...messageDataSource , scrollToBottom, quoteMessage, replyType } ) ;
367
369
0 commit comments