From 3d0e738957cb79dbd45f5147bdfb7d684eea785b Mon Sep 17 00:00:00 2001 From: inokawa <48897392+inokawa@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:49:50 +0900 Subject: [PATCH] Improve jump compensation immediately after prepending --- src/core/store.ts | 23 +++++++++++++++++------ stories/advanced/Feed.stories.tsx | 15 --------------- stories/basics/VList.stories.tsx | 3 +-- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/core/store.ts b/src/core/store.ts index 7b290ae8e..f7380391e 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -129,6 +129,7 @@ export const createVirtualStore = ( let pendingJump = 0; let _flushedJump = 0; let _scrollDirection: ScrollDirection = SCROLL_IDLE; + let _prepended = false; let _isManualScrolling = false; let _smoothScrollRange: ItemsRange | null = null; let _prevRange: ItemsRange = [0, initialItemCount]; @@ -252,6 +253,9 @@ export const createVirtualStore = ( const updated = payload.filter( ([index, size]) => cache._sizes[index] !== size ); + const isJustPrepended = _prepended; + _prepended = false; + // Skip if all items are cached and not updated if (!updated.length) { break; @@ -267,12 +271,18 @@ export const createVirtualStore = ( // Keep end to stick to the end diff = calculateJump(cache, updated, true); } else { - const [startIndex] = _prevRange; - // Keep start at mid - diff = calculateJump( - cache, - updated.filter(([index]) => index < startIndex) - ); + if (isJustPrepended) { + // Keep distance from end immediately after prepending + // We can assume jumps occurred on the upper outside + diff = calculateJump(cache, updated); + } else { + // Keep start at mid + const [startIndex] = _prevRange; + diff = calculateJump( + cache, + updated.filter(([index]) => index < startIndex) + ); + } } if (diff) { @@ -326,6 +336,7 @@ export const createVirtualStore = ( ); applyJump(isRemove ? -min(shift, distanceToEnd) : shift); + _prepended = !isRemove; mutated = UPDATE_SCROLL_STATE; } else { updateCacheLength(cache as Writeable, payload[0]); diff --git a/stories/advanced/Feed.stories.tsx b/stories/advanced/Feed.stories.tsx index 5ea45a760..d28d72206 100644 --- a/stories/advanced/Feed.stories.tsx +++ b/stories/advanced/Feed.stories.tsx @@ -62,16 +62,10 @@ export const Default: StoryObj = { const createItems = (num: number) => range(num, createItem); const [shifting, setShifting] = useState(false); - const [startFetching, setStartFetching] = useState(false); - const [endFetching, setEndFetching] = useState(false); const fetchItems = async (isStart: boolean = false) => { setShifting(isStart); - const setFetching = isStart ? setStartFetching : setEndFetching; - - setFetching(true); await delay(1000); - setFetching(false); }; const ref = useRef(null); @@ -128,16 +122,7 @@ export const Default: StoryObj = { } }} > - {/* // TODO support the case when spinner is at index 0 - */} {elements} - ); }, diff --git a/stories/basics/VList.stories.tsx b/stories/basics/VList.stories.tsx index 7d6d2678f..2c50661a5 100644 --- a/stories/basics/VList.stories.tsx +++ b/stories/basics/VList.stories.tsx @@ -623,11 +623,10 @@ export const BiDirectionalInfiniteScrolling: StoryObj = { } }} > - {/* // TODO support the case when spinner is at index 0 */} + /> {items}