import { useLayoutEffect, useState, useRef, useCallback } from 'react'; import type { ReactNode } from 'react'; import type { TMessage } from 'librechat-data-provider'; import ScrollToBottom from '~/components/Messages/ScrollToBottom'; import { useScreenshot, useScrollToRef } from '~/hooks'; import { CSSTransition } from 'react-transition-group'; import { useChatContext } from '~/Providers'; import MultiMessage from './MultiMessage'; export default function MessagesView({ messagesTree: _messagesTree, Header, }: { messagesTree?: TMessage[] | null; Header?: ReactNode; }) { const scrollableRef = useRef(null); const messagesEndRef = useRef(null); const [showScrollButton, setShowScrollButton] = useState(false); const [currentEditId, setCurrentEditId] = useState(-1); const { conversation, showPopover, setAbortScroll } = useChatContext(); const { conversationId } = conversation ?? {}; const { screenshotTargetRef } = useScreenshot(); const checkIfAtBottom = useCallback(() => { 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.15; setShowScrollButton(hasScrollbar); }, [scrollableRef]); useLayoutEffect(() => { const timeoutId = setTimeout(() => { checkIfAtBottom(); }, 650); // Add a listener on the window object window.addEventListener('scroll', checkIfAtBottom); return () => { clearTimeout(timeoutId); window.removeEventListener('scroll', checkIfAtBottom); }; }, [_messagesTree, checkIfAtBottom]); let timeoutId: ReturnType | undefined; const debouncedHandleScroll = () => { clearTimeout(timeoutId); timeoutId = setTimeout(checkIfAtBottom, 100); }; const scrollCallback = () => setShowScrollButton(false); const { scrollToRef: scrollToBottom, handleSmoothToRef } = useScrollToRef({ targetRef: messagesEndRef, callback: scrollCallback, smoothCallback: () => { scrollCallback(); setAbortScroll(false); }, }); return (
{(_messagesTree && _messagesTree?.length == 0) || _messagesTree === null ? (
Nothing found
) : ( <> {Header && Header}
{() => showScrollButton && !showPopover && }
)}
); }