diff --git a/app/components/ConversationFrontend.tsx b/app/components/ConversationFrontend.tsx index 1056c87..c869d5c 100644 --- a/app/components/ConversationFrontend.tsx +++ b/app/components/ConversationFrontend.tsx @@ -1,4 +1,4 @@ -import React, { ForwardedRef, useEffect, useRef } from 'react'; +import React, { ForwardedRef, useState, useEffect, useRef } from 'react'; type Message = { role: string @@ -15,24 +15,45 @@ interface ConversationProps { } const ConversationFrontend = React.forwardRef( - ({ messages,onStopClick, onResendClick, onEditClick, onCopyClick, isClicked }, ref: ForwardedRef) => { - - const messagesEndRef = useRef(null) + ({ messages, onStopClick, onResendClick, onEditClick, onCopyClick, isClicked }, ref: ForwardedRef) => { + const [isScrolling, setIsScrolling] = useState(true); + const messagesEndRef = useRef(null); useEffect(() => { - if (messagesEndRef.current) { - const rect = messagesEndRef.current.getBoundingClientRect(); - console.log('Position of the target div:'); - console.log('Top:', rect.top); // Distance from the top of the viewport - console.log('Left:', rect.left); // Distance from the left of the viewport - console.log('Width:', rect.width); // Width of the element - console.log('Height:', rect.height); // Height of the element - } - }, [messages]); + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) { + console.log('End of messages reached'); + setIsScrolling(true); + } else { + console.log('End of messages not reached'); + setIsScrolling(false); + } + }, + { + root: document.querySelector('.output'), + threshold: 1.0, // Ensure the whole element is visible + } + ); + + const endOfMessages = messagesEndRef.current; + if (endOfMessages) { + observer.observe(endOfMessages); + } + return () => { + if (endOfMessages) { + observer.unobserve(endOfMessages); + } + }; + }, [messages]); + + // Scroll to bottom when new messages arrive useEffect(() => { - messagesEndRef.current?.scrollIntoView() - }, [messages]) + if (isScrolling) { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages, isScrolling]); return (
@@ -77,11 +98,12 @@ const ConversationFrontend = React.forwardRef {isClicked?"Copied!": "Copy" }
-
+
+
); - } + } ); export default ConversationFrontend; diff --git a/app/styles/output.css b/app/styles/output.css index cb48ee8..93fcbf2 100644 --- a/app/styles/output.css +++ b/app/styles/output.css @@ -1,5 +1,6 @@ /* Output Section */ .output { + scroll-behavior: smooth; grid-column: 2; grid-row: 1 / 4; background-color: var(--output-background-color); @@ -13,6 +14,7 @@ overflow-y: auto; width: calc(100% - 2em); /* Corrected calculation for width */ height: 86dvh; + position: relative; } #conversation { @@ -127,3 +129,16 @@ pointer-events: none; user-select: none; } + +#scrollToBottom{ + scroll-behavior: smooth; + visibility: hidden; + position: absolute; + height: 50px; + width: 50px; + margin: auto; + border-radius: 100%; + bottom: 16dvh; + left: 50%; + translate: -25px; +}