From afe49747f393e76480e8b519d18d2852ff6dd414 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Tue, 30 Apr 2024 11:14:02 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Effectively=20interrupt?= =?UTF-8?q?=20auto=20scrolling=20(#2223)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Interrupt auto scrolling * reduce atBottomThreshold * del * del * Alternative invalid followOutput * BottomThreshold 过小导致无法连续滚动 * 避免删除消息触发下滑 * restore mobile BottomThreshold * restore overscan * fix * little fix * fix followOutput --- .../Conversation/components/AutoScroll.tsx | 5 +++-- .../components/VirtualizedList/index.tsx | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/features/Conversation/components/AutoScroll.tsx b/src/features/Conversation/components/AutoScroll.tsx index 5e97e5437d9f..6e806490510c 100644 --- a/src/features/Conversation/components/AutoScroll.tsx +++ b/src/features/Conversation/components/AutoScroll.tsx @@ -7,14 +7,15 @@ import BackBottom from './BackBottom'; interface AutoScrollProps { atBottom: boolean; + isScrolling: boolean; onScrollToBottom: (type: 'auto' | 'click') => void; } -const AutoScroll = memo(({ atBottom, onScrollToBottom }) => { +const AutoScroll = memo(({ atBottom, isScrolling, onScrollToBottom }) => { const trackVisibility = useChatStore((s) => !!s.chatLoadingId); const str = useChatStore(chatSelectors.chatsMessageString); useEffect(() => { - if (atBottom && trackVisibility) { + if (atBottom && trackVisibility && !isScrolling) { onScrollToBottom?.('auto'); } }, [atBottom, trackVisibility, str]); diff --git a/src/features/Conversation/components/VirtualizedList/index.tsx b/src/features/Conversation/components/VirtualizedList/index.tsx index d467c4752447..de3c63d5ced6 100644 --- a/src/features/Conversation/components/VirtualizedList/index.tsx +++ b/src/features/Conversation/components/VirtualizedList/index.tsx @@ -1,5 +1,5 @@ import isEqual from 'fast-deep-equal'; -import React, { memo, useEffect, useRef, useState } from 'react'; +import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; import { Flexbox } from 'react-layout-kit'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; @@ -35,6 +35,7 @@ const VirtualizedList = memo(({ mobile }) => { const virtuosoRef = useRef(null); const [atBottom, setAtBottom] = useState(true); + const [isScrolling, setIsScrolling] = useState(false); const [id, chatLoading] = useChatStore((s) => [ chatSelectors.currentChatKey(s), @@ -53,6 +54,14 @@ const VirtualizedList = memo(({ mobile }) => { } }, [id]); + const prevDataLengthRef = useRef(data.length); + + const getFollowOutput = useCallback(() => { + const newFollowOutput = data.length > prevDataLengthRef.current ? 'auto' : false; + prevDataLengthRef.current = data.length; + return newFollowOutput; + }, [data.length]); + // overscan should be 1.5 times the height of the window const overscan = typeof window !== 'undefined' ? window.innerHeight * 1.5 : 0; @@ -62,17 +71,20 @@ const VirtualizedList = memo(({ mobile }) => { item} data={data} - followOutput={'auto'} + followOutput={getFollowOutput} + // increaseViewportBy={overscan} initialTopMostItemIndex={data?.length - 1} + isScrolling={setIsScrolling} itemContent={itemContent} overscan={overscan} ref={virtuosoRef} /> { const virtuoso = virtuosoRef.current; switch (type) {