import type { IMessage } from '@rocket.chat/core-typings'; import { isEditedMessage } from '@rocket.chat/core-typings'; import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks'; import { clientCallbacks } from '@rocket.chat/ui-client'; import type { Dispatch, MutableRefObject, SetStateAction } from 'react'; import { useCallback, useEffect, useState } from 'react'; import { RoomHistoryManager } from '../../../../lib/RoomHistoryManager'; import { useChat } from '../../contexts/ChatContext'; export const useHasNewMessages = ( rid: string, uid: string | undefined, setShouldJumpToBottom: Dispatch>, isAtBottom: MutableRefObject, ) => { const chat = useChat(); if (!chat) { throw new Error('No ChatContext provided'); } const [hasNewMessages, setHasNewMessages] = useState(false); const handleNewMessageButtonClick = useCallback(() => { setShouldJumpToBottom(true); setHasNewMessages(false); chat.composer?.focus(); }, [setShouldJumpToBottom, chat.composer]); const handleJumpToRecentButtonClick = useCallback(async () => { RoomHistoryManager.clear(rid); await RoomHistoryManager.getMoreIfIsEmpty(rid); setShouldJumpToBottom(true); }, [setShouldJumpToBottom, rid]); const handleComposerResize = useCallback((): void => { setShouldJumpToBottom(true); setHasNewMessages(false); }, [setShouldJumpToBottom]); useEffect(() => { clientCallbacks.add( 'streamNewMessage', (msg: IMessage) => { if (rid !== msg.rid || isEditedMessage(msg) || msg.tmid) { return; } if (msg.u._id === uid) { // If there are more next messages, jump to the recent messages if (RoomHistoryManager.hasMoreNext(rid)) { return handleJumpToRecentButtonClick(); } setShouldJumpToBottom(true); setHasNewMessages(false); return; } if (!isAtBottom.current) { setHasNewMessages(true); } }, clientCallbacks.priority.MEDIUM, rid, ); return () => { clientCallbacks.remove('streamNewMessage', rid); }; }, [handleJumpToRecentButtonClick, isAtBottom, rid, setShouldJumpToBottom, uid]); const debouncedClearNewMessagesOnScroll = useDebouncedCallback( () => { if (isAtBottom.current) { setHasNewMessages(false); } }, 100, [], ); return { debouncedClearNewMessagesOnScroll, handleNewMessageButtonClick, handleJumpToRecentButtonClick, handleComposerResize, hasNewMessages, }; };