diff --git a/client/src/components/chat-messages-list/chat-message-list.component.jsx b/client/src/components/chat-messages-list/chat-message-list.component.jsx index 81d3296fc..00b9204cc 100644 --- a/client/src/components/chat-messages-list/chat-message-list.component.jsx +++ b/client/src/components/chat-messages-list/chat-message-list.component.jsx @@ -3,33 +3,41 @@ import { Virtuoso } from "react-virtuoso"; import { renderMessage } from "./renderMessage"; import "./chat-message-list.styles.scss"; +const SCROLL_DELAY_MS = 50; +const INITIAL_SCROLL_DELAY_MS = 100; + export default function ChatMessageListComponent({ messages }) { const virtuosoRef = useRef(null); // Scroll to the bottom after a short delay when the component mounts useEffect(() => { const timer = setTimeout(() => { - if (virtuosoRef.current) { + if (virtuosoRef?.current?.scrollToIndex && messages?.length) { virtuosoRef.current.scrollToIndex({ index: messages.length - 1, behavior: "auto" // Instantly scroll to the bottom }); } - }, 100); // Delay of 100ms to allow rendering + }, INITIAL_SCROLL_DELAY_MS); + + // Cleanup the timeout on unmount return () => clearTimeout(timer); - }, [messages.length]); // Run only once on component mount + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); // ESLint is disabled for this line because we only want this to load once (valid exception) // Scroll to the bottom after the new messages are rendered useEffect(() => { - if (virtuosoRef.current) { - // Allow the DOM and Virtuoso to fully render the new data - setTimeout(() => { + if (virtuosoRef?.current?.scrollToIndex && messages?.length) { + const timeout = setTimeout(() => { virtuosoRef.current.scrollToIndex({ index: messages.length - 1, align: "end", // Ensure the last message is fully visible behavior: "smooth" // Smooth scrolling }); - }, 50); // Slight delay to ensure layout recalculates + }, SCROLL_DELAY_MS); // Slight delay to ensure layout recalculates + + // Cleanup timeout on dependency changes + return () => clearTimeout(timeout); } }, [messages]); // Triggered when new messages are added