Skip to content

Commit

Permalink
🐛 fix: Effectively interrupt auto scrolling (#2223)
Browse files Browse the repository at this point in the history
* Interrupt auto scrolling

* reduce atBottomThreshold

* del

* del

* Alternative invalid followOutput

* BottomThreshold 过小导致无法连续滚动

* 避免删除消息触发下滑

* restore mobile BottomThreshold

* restore overscan

* fix

* little fix

* fix followOutput
  • Loading branch information
sxjeru authored Apr 30, 2024
1 parent 36e40aa commit afe4974
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/features/Conversation/components/AutoScroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import BackBottom from './BackBottom';

interface AutoScrollProps {
atBottom: boolean;
isScrolling: boolean;
onScrollToBottom: (type: 'auto' | 'click') => void;
}
const AutoScroll = memo<AutoScrollProps>(({ atBottom, onScrollToBottom }) => {
const AutoScroll = memo<AutoScrollProps>(({ 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]);
Expand Down
18 changes: 15 additions & 3 deletions src/features/Conversation/components/VirtualizedList/index.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -35,6 +35,7 @@ const VirtualizedList = memo<VirtualizedListProps>(({ mobile }) => {

const virtuosoRef = useRef<VirtuosoHandle>(null);
const [atBottom, setAtBottom] = useState(true);
const [isScrolling, setIsScrolling] = useState(false);

const [id, chatLoading] = useChatStore((s) => [
chatSelectors.currentChatKey(s),
Expand All @@ -53,6 +54,14 @@ const VirtualizedList = memo<VirtualizedListProps>(({ 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;

Expand All @@ -62,17 +71,20 @@ const VirtualizedList = memo<VirtualizedListProps>(({ mobile }) => {
<Flexbox height={'100%'}>
<Virtuoso
atBottomStateChange={setAtBottom}
atBottomThreshold={60 * (mobile ? 2 : 1)}
atBottomThreshold={50 * (mobile ? 2 : 1)}
computeItemKey={(_, item) => item}
data={data}
followOutput={'auto'}
followOutput={getFollowOutput}
// increaseViewportBy={overscan}
initialTopMostItemIndex={data?.length - 1}
isScrolling={setIsScrolling}
itemContent={itemContent}
overscan={overscan}
ref={virtuosoRef}
/>
<AutoScroll
atBottom={atBottom}
isScrolling={isScrolling}
onScrollToBottom={(type) => {
const virtuoso = virtuosoRef.current;
switch (type) {
Expand Down

0 comments on commit afe4974

Please sign in to comment.