ScrollableList: save and restore scroll position

environments/review-scroll-pos-dnhc2t/deployments/24
Alex Gleason 2022-05-19 16:09:22 -05:00
rodzic c749738e4b
commit ba0b4851f6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
1 zmienionych plików z 18 dodań i 3 usunięć

Wyświetl plik

@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import { Virtuoso, Components, VirtuosoProps, VirtuosoHandle } from 'react-virtuoso';
import PullToRefresh from 'soapbox/components/pull-to-refresh';
@ -62,11 +62,16 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
placeholderComponent: Placeholder,
placeholderCount = 0,
initialTopMostItemIndex = 0,
scrollerRef,
}, ref) => {
const settings = useSettings();
const autoloadMore = settings.get('autoloadMore');
// Preserve scroll position
const scrollPositionKey = `soapbox:scrollPosition:${location.pathname}`;
const scrollPosition = Number(sessionStorage.getItem(scrollPositionKey));
const initialScrollTop = useRef(scrollPosition);
const scroller = useRef<Window | HTMLElement | null>(null);
/** Normalized children */
const elements = Array.from(children || []);
@ -85,6 +90,15 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
data.push(<Spinner />);
}
useEffect(() => {
sessionStorage.removeItem(scrollPositionKey);
// On unmount, save the scroll position.
return () => {
sessionStorage.setItem(scrollPositionKey, String(document.documentElement.scrollTop));
};
}, []);
/* Render an empty state instead of the scrollable list */
const renderEmpty = (): JSX.Element => {
return (
@ -130,6 +144,7 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
<Virtuoso
ref={ref}
useWindowScroll
initialScrollTop={initialScrollTop.current}
className={className}
data={data}
startReached={onScrollToTop}
@ -149,7 +164,7 @@ const ScrollableList = React.forwardRef<VirtuosoHandle, IScrollableList>(({
Item,
Footer: loadMore,
}}
scrollerRef={scrollerRef}
scrollerRef={c => scroller.current = c}
/>
);