import { useEffect, useState, useRef } from 'react'; import { CSSTransition } from 'react-transition-group'; import { useRecoilValue } from 'recoil'; import ScrollToBottom from './ScrollToBottom'; import MessageHeader from './MessageHeader'; import MultiMessage from './MultiMessage'; import { Spinner } from '~/components'; import { useScreenshot, useScrollToRef } from '~/hooks'; import store from '~/store'; export default function Messages({ isSearchView = false }) { const [currentEditId, setCurrentEditId] = useState(-1); const [showScrollButton, setShowScrollButton] = useState(false); const scrollableRef = useRef(null); const messagesEndRef = useRef(null); const messagesTree = useRecoilValue(store.messagesTree); const showPopover = useRecoilValue(store.showPopover); const searchResultMessagesTree = useRecoilValue(store.searchResultMessagesTree); const _messagesTree = isSearchView ? searchResultMessagesTree : messagesTree; const conversation = useRecoilValue(store.conversation); const { conversationId } = conversation ?? {}; const { screenshotTargetRef } = useScreenshot(); const handleScroll = () => { if (!scrollableRef.current) { return; } const { scrollTop, scrollHeight, clientHeight } = scrollableRef.current; const diff = Math.abs(scrollHeight - scrollTop); const percent = Math.abs(clientHeight - diff) / clientHeight; if (percent <= 0.2) { setShowScrollButton(false); } else { setShowScrollButton(true); } }; useEffect(() => { const timeoutId = setTimeout(() => { if (!scrollableRef.current) { return; } const { scrollTop, scrollHeight, clientHeight } = scrollableRef.current; const diff = Math.abs(scrollHeight - scrollTop); const percent = Math.abs(clientHeight - diff) / clientHeight; const hasScrollbar = scrollHeight > clientHeight && percent > 0.2; setShowScrollButton(hasScrollbar); }, 650); // Add a listener on the window object window.addEventListener('scroll', handleScroll); return () => { clearTimeout(timeoutId); window.removeEventListener('scroll', handleScroll); }; }, [_messagesTree]); let timeoutId: ReturnType | undefined; const debouncedHandleScroll = () => { clearTimeout(timeoutId); timeoutId = setTimeout(handleScroll, 100); }; const { scrollToRef: scrollToBottom, handleSmoothToRef } = useScrollToRef(messagesEndRef, () => setShowScrollButton(false), ); return (
{_messagesTree === null ? (
) : _messagesTree?.length == 0 && isSearchView ? (
Nothing found
) : ( <> {() => showScrollButton && !showPopover && } )}
); }