Browse Source

prevent auto scrolling down to bottom when user already scrolled up (#2813)

Rozstone 1 year ago
parent
commit
8a4015722d
1 changed files with 21 additions and 7 deletions
  1. 21 7
      web/app/components/base/chat/chat/index.tsx

+ 21 - 7
web/app/components/base/chat/chat/index.tsx

@@ -4,6 +4,7 @@ import type {
 } from 'react'
 } from 'react'
 import {
 import {
   memo,
   memo,
+  useCallback,
   useEffect,
   useEffect,
   useRef,
   useRef,
 } from 'react'
 } from 'react'
@@ -76,19 +77,20 @@ const Chat: FC<ChatProps> = ({
   const chatContainerInnerRef = useRef<HTMLDivElement>(null)
   const chatContainerInnerRef = useRef<HTMLDivElement>(null)
   const chatFooterRef = useRef<HTMLDivElement>(null)
   const chatFooterRef = useRef<HTMLDivElement>(null)
   const chatFooterInnerRef = useRef<HTMLDivElement>(null)
   const chatFooterInnerRef = useRef<HTMLDivElement>(null)
+  const userScrolledRef = useRef(false)
 
 
-  const handleScrolltoBottom = () => {
-    if (chatContainerRef.current)
+  const handleScrolltoBottom = useCallback(() => {
+    if (chatContainerRef.current && !userScrolledRef.current)
       chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight
       chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight
-  }
+  }, [])
 
 
-  const handleWindowResize = () => {
+  const handleWindowResize = useCallback(() => {
     if (chatContainerRef.current && chatFooterRef.current)
     if (chatContainerRef.current && chatFooterRef.current)
       chatFooterRef.current.style.width = `${chatContainerRef.current.clientWidth}px`
       chatFooterRef.current.style.width = `${chatContainerRef.current.clientWidth}px`
 
 
     if (chatContainerInnerRef.current && chatFooterInnerRef.current)
     if (chatContainerInnerRef.current && chatFooterInnerRef.current)
       chatFooterInnerRef.current.style.width = `${chatContainerInnerRef.current.clientWidth}px`
       chatFooterInnerRef.current.style.width = `${chatContainerInnerRef.current.clientWidth}px`
-  }
+  }, [])
 
 
   useThrottleEffect(() => {
   useThrottleEffect(() => {
     handleScrolltoBottom()
     handleScrolltoBottom()
@@ -98,7 +100,7 @@ const Chat: FC<ChatProps> = ({
   useEffect(() => {
   useEffect(() => {
     window.addEventListener('resize', debounce(handleWindowResize))
     window.addEventListener('resize', debounce(handleWindowResize))
     return () => window.removeEventListener('resize', handleWindowResize)
     return () => window.removeEventListener('resize', handleWindowResize)
-  }, [])
+  }, [handleWindowResize])
 
 
   useEffect(() => {
   useEffect(() => {
     if (chatFooterRef.current && chatContainerRef.current) {
     if (chatFooterRef.current && chatContainerRef.current) {
@@ -117,7 +119,19 @@ const Chat: FC<ChatProps> = ({
         resizeObserver.disconnect()
         resizeObserver.disconnect()
       }
       }
     }
     }
-  }, [chatFooterRef, chatContainerRef])
+  }, [handleScrolltoBottom])
+
+  useEffect(() => {
+    const chatContainer = chatContainerRef.current
+    if (chatContainer) {
+      const setUserScrolled = () => {
+        if (chatContainer)
+          userScrolledRef.current = chatContainer.scrollHeight - chatContainer.scrollTop >= chatContainer.clientHeight + 300
+      }
+      chatContainer.addEventListener('scroll', setUserScrolled)
+      return () => chatContainer.removeEventListener('scroll', setUserScrolled)
+    }
+  }, [])
 
 
   const hasTryToAsk = config?.suggested_questions_after_answer?.enabled && !!suggestedQuestions?.length && onSend
   const hasTryToAsk = config?.suggested_questions_after_answer?.enabled && !!suggestedQuestions?.length && onSend