ScrollableList: preserve index rather than scrollTop

dnd
Alex Gleason 2022-05-19 20:03:52 -05:00
rodzic ba0b4851f6
commit 533c356d60
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
1 zmienionych plików z 12 dodań i 13 usunięć

Wyświetl plik

@ -1,5 +1,5 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import { Virtuoso, Components, VirtuosoProps, VirtuosoHandle } from 'react-virtuoso'; import { Virtuoso, Components, VirtuosoProps, VirtuosoHandle, ListRange } from 'react-virtuoso';
import PullToRefresh from 'soapbox/components/pull-to-refresh'; import PullToRefresh from 'soapbox/components/pull-to-refresh';
import { useSettings } from 'soapbox/hooks'; import { useSettings } from 'soapbox/hooks';
@ -66,10 +66,10 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
const settings = useSettings(); const settings = useSettings();
const autoloadMore = settings.get('autoloadMore'); const autoloadMore = settings.get('autoloadMore');
// Preserve scroll position // Preserve scroll index
const scrollPositionKey = `soapbox:scrollPosition:${location.pathname}`; const scrollIndexKey = `soapbox:scrollIndex:${location.pathname}`;
const scrollPosition = Number(sessionStorage.getItem(scrollPositionKey)); const scrollIndex = Number(sessionStorage.getItem(scrollIndexKey));
const initialScrollTop = useRef(scrollPosition); const initialIndex = useRef(scrollIndex);
const scroller = useRef<Window | HTMLElement | null>(null); const scroller = useRef<Window | HTMLElement | null>(null);
/** Normalized children */ /** Normalized children */
@ -91,12 +91,7 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
} }
useEffect(() => { useEffect(() => {
sessionStorage.removeItem(scrollPositionKey); sessionStorage.removeItem(scrollIndexKey);
// On unmount, save the scroll position.
return () => {
sessionStorage.setItem(scrollPositionKey, String(document.documentElement.scrollTop));
};
}, []); }, []);
/* Render an empty state instead of the scrollable list */ /* Render an empty state instead of the scrollable list */
@ -139,19 +134,23 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
} }
}; };
const handleRangeChanged = (range: ListRange) => {
sessionStorage.setItem(scrollIndexKey, String(range.startIndex));
};
/** Render the actual Virtuoso list */ /** Render the actual Virtuoso list */
const renderFeed = (): JSX.Element => ( const renderFeed = (): JSX.Element => (
<Virtuoso <Virtuoso
ref={ref} ref={ref}
useWindowScroll useWindowScroll
initialScrollTop={initialScrollTop.current}
className={className} className={className}
data={data} data={data}
startReached={onScrollToTop} startReached={onScrollToTop}
endReached={handleEndReached} endReached={handleEndReached}
isScrolling={isScrolling => isScrolling && onScroll && onScroll()} isScrolling={isScrolling => isScrolling && onScroll && onScroll()}
itemContent={renderItem} itemContent={renderItem}
initialTopMostItemIndex={showLoading ? 0 : initialTopMostItemIndex} initialTopMostItemIndex={showLoading ? 0 : initialTopMostItemIndex || initialIndex.current}
rangeChanged={handleRangeChanged}
context={{ context={{
listClassName: className, listClassName: className,
itemClassName, itemClassName,