From 4385c4a3cffe26f723ecd14fa3d41faf133cd409 Mon Sep 17 00:00:00 2001 From: tjtanjin Date: Fri, 15 Mar 2024 17:51:11 +0800 Subject: [PATCH] fix: Fix chat history load and stream message scroll positions --- src/components/ChatBotBody/ChatBotBody.tsx | 19 ++++++++++++++----- src/components/ChatBotContainer.tsx | 8 ++++++-- src/services/ChatHistoryService.tsx | 1 - 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/ChatBotBody/ChatBotBody.tsx b/src/components/ChatBotBody/ChatBotBody.tsx index f498df8d..127a85f3 100644 --- a/src/components/ChatBotBody/ChatBotBody.tsx +++ b/src/components/ChatBotBody/ChatBotBody.tsx @@ -1,4 +1,4 @@ -import { RefObject, Dispatch, SetStateAction, useEffect, CSSProperties, MouseEvent } from "react"; +import { RefObject, Dispatch, SetStateAction, useEffect, useRef, CSSProperties, MouseEvent } from "react"; import { useBotOptions } from "../../context/BotOptionsContext"; import { useMessages } from "../../context/MessagesContext"; @@ -14,19 +14,22 @@ import "./ChatBotBody.css"; * @param isLoadingChatHistory boolean indicating is chat history is being loaded * @param prevScrollHeight number representing previously scrolled height * @param setPrevScrollHeight setter for tracking scroll height + * @param setIsLoadingChatHistory setter for tracking whether is loading history */ const ChatBotBody = ({ chatBodyRef, isBotTyping, isLoadingChatHistory, prevScrollHeight, - setPrevScrollHeight + setPrevScrollHeight, + setIsLoadingChatHistory, }: { chatBodyRef: RefObject; isBotTyping: boolean; isLoadingChatHistory: boolean; prevScrollHeight: number; setPrevScrollHeight: Dispatch>; + setIsLoadingChatHistory: Dispatch>; }) => { // handles options for bot @@ -35,6 +38,9 @@ const ChatBotBody = ({ // handles messages between user and the chat bot const { messages } = useMessages(); + // track if is scrolling body + const isScrollingBody = useRef(false); + // styles for chat body const bodyStyle: CSSProperties = { ...botOptions?.bodyStyle @@ -63,20 +69,23 @@ const ChatBotBody = ({ const scrollDifference = scrollHeight - prevScrollHeight; chatBodyRef.current.scrollTop = chatBodyRef.current.scrollTop + scrollDifference; setPrevScrollHeight(scrollHeight); + setIsLoadingChatHistory(false); return; } - if (chatBodyRef.current != null) { + if (chatBodyRef.current != null && !isScrollingBody.current) { chatBodyRef.current.scrollTop = chatBodyRef.current.scrollHeight; } - }, [messages.length, isBotTyping]); + }, [chatBodyRef.current?.scrollHeight, messages.length, isBotTyping]); /** * Updates scroll height within the chat body. */ const updateScrollHeight = () => { if (chatBodyRef?.current != null) { - setPrevScrollHeight(chatBodyRef.current.scrollHeight); + const { scrollTop, clientHeight, scrollHeight } = chatBodyRef.current; + setPrevScrollHeight(scrollHeight); + isScrollingBody.current = (scrollHeight - scrollTop !== clientHeight) } }; diff --git a/src/components/ChatBotContainer.tsx b/src/components/ChatBotContainer.tsx index 75e02c78..dafab894 100644 --- a/src/components/ChatBotContainer.tsx +++ b/src/components/ChatBotContainer.tsx @@ -519,6 +519,10 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => { await injectMessage(userInput, "user"); } + if (chatBodyRef.current != null) { + chatBodyRef.current.scrollTop = chatBodyRef.current.scrollHeight; + } + // Clear input field if (inputRef.current) { inputRef.current.value = ""; @@ -637,8 +641,8 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => { /> } {botOptions.theme?.showInputRow &&