feat: auto detach scrolling

This commit is contained in:
Fred 2024-02-27 11:43:40 +08:00
parent aacd26c7db
commit 410a22dc63
No known key found for this signature in database
GPG Key ID: 4DABDA85EF70EC71

View File

@ -6,6 +6,7 @@ import React, {
useMemo,
useCallback,
Fragment,
RefObject,
} from "react";
import SendWhiteIcon from "../icons/send-white.svg";
@ -382,11 +383,13 @@ function ChatAction(props: {
);
}
function useScrollToBottom() {
function useScrollToBottom(
scrollRef: RefObject<HTMLDivElement>,
detach: boolean = false,
) {
// for auto-scroll
const scrollRef = useRef<HTMLDivElement>(null);
const [autoScroll, setAutoScroll] = useState(true);
const [autoScroll, setAutoScroll] = useState(true);
function scrollDomToBottom() {
const dom = scrollRef.current;
if (dom) {
@ -399,7 +402,7 @@ function useScrollToBottom() {
// auto scroll
useEffect(() => {
if (autoScroll) {
if (autoScroll && !detach) {
scrollDomToBottom();
}
});
@ -658,7 +661,17 @@ function _Chat() {
const [userInput, setUserInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const { submitKey, shouldSubmit } = useSubmitHandler();
const { scrollRef, setAutoScroll, scrollDomToBottom } = useScrollToBottom();
const scrollRef = useRef<HTMLDivElement>(null);
const isScrolledToBottom = scrollRef?.current
? Math.abs(
scrollRef.current.scrollHeight -
(scrollRef.current.scrollTop + scrollRef.current.clientHeight),
) <= 1
: false;
const { setAutoScroll, scrollDomToBottom } = useScrollToBottom(
scrollRef,
isScrolledToBottom,
);
const [hitBottom, setHitBottom] = useState(true);
const isMobileScreen = useMobileScreen();
const navigate = useNavigate();
@ -1003,7 +1016,6 @@ function _Chat() {
setHitBottom(isHitBottom);
setAutoScroll(isHitBottom);
};
function scrollToBottom() {
setMsgRenderIndex(renderMessages.length - CHAT_PAGE_SIZE);
scrollDomToBottom();
@ -1151,6 +1163,13 @@ function _Chat() {
)}
<div className={`window-header-title ${styles["chat-body-title"]}`}>
<p>
{JSON.stringify({
scrollHeight: scrollRef?.current?.scrollHeight,
scrollTop: scrollRef?.current?.scrollTop,
clientHeight: scrollRef?.current?.clientHeight,
})}
</p>
<div
className={`window-header-main-title ${styles["chat-body-main-title"]}`}
onClickCapture={() => setIsEditingMessage(true)}