11import { useChannelStateContext } from '../../../../context' ;
2- import { useEffect , useState } from 'react' ;
2+ import { useEffect , useRef , useState } from 'react' ;
33import { MESSAGE_LIST_MAIN_PANEL_CLASS } from '../../MessageListMainPanel' ;
44import { UNREAD_MESSAGE_SEPARATOR_CLASS } from '../../UnreadMessagesSeparator' ;
55
@@ -10,14 +10,17 @@ const targetIsVisibleInContainer = (element: Element, container: Element) => {
1010} ;
1111
1212export type UseUnreadMessagesNotificationParams = {
13+ isMessageListScrolledToBottom : boolean ;
1314 unreadCount ?: number ;
1415} ;
1516
1617export const useUnreadMessagesNotification = ( {
18+ isMessageListScrolledToBottom,
1719 unreadCount,
1820} : UseUnreadMessagesNotificationParams ) => {
1921 const { messages } = useChannelStateContext ( 'UnreadMessagesNotification' ) ;
2022 const [ show , setShow ] = useState ( false ) ;
23+ const isScrolledAboveTargetTop = useRef ( false ) ;
2124 const intersectionObserverIsSupported = typeof IntersectionObserver !== 'undefined' ;
2225
2326 useEffect ( ( ) => {
@@ -41,9 +44,13 @@ export const useUnreadMessagesNotification = ({
4144 ( elements ) => {
4245 if ( ! elements . length ) return ;
4346 const { boundingClientRect, isIntersecting, rootBounds } = elements [ 0 ] ;
44- const isScrolledAboveTargetTop =
45- rootBounds && boundingClientRect && rootBounds . bottom < boundingClientRect . top ;
46- setShow ( ! isIntersecting && ! isScrolledAboveTargetTop ) ;
47+ const isScrolledAboveTargetTopCurrent = ! ! (
48+ rootBounds &&
49+ boundingClientRect &&
50+ rootBounds . bottom < boundingClientRect . top
51+ ) ;
52+ setShow ( ! isIntersecting && ! isScrolledAboveTargetTopCurrent ) ;
53+ isScrolledAboveTargetTop . current = isScrolledAboveTargetTopCurrent ;
4754 } ,
4855 { root : msgListPanel } ,
4956 ) ;
@@ -54,5 +61,18 @@ export const useUnreadMessagesNotification = ({
5461 } ;
5562 } , [ intersectionObserverIsSupported , messages , unreadCount ] ) ;
5663
64+ useEffect ( ( ) => {
65+ /**
66+ * Handle situation when scrollToBottom is called from another component when the msg list is scrolled above the observed target (unread separator).
67+ * The intersection observer is not triggered when Element.scrollTo() is called. So we end up in a situation when we are scrolled to the bottom
68+ * and at the same time scrolled above the observed target.
69+ */
70+
71+ if ( unreadCount && isMessageListScrolledToBottom && isScrolledAboveTargetTop . current ) {
72+ setShow ( true ) ;
73+ isScrolledAboveTargetTop . current = false ;
74+ }
75+ } , [ isMessageListScrolledToBottom , unreadCount ] ) ;
76+
5777 return { show : show && intersectionObserverIsSupported } ;
5878} ;
0 commit comments