diff --git a/app/soapbox/components/scrollable_list.tsx b/app/soapbox/components/scrollable_list.tsx index cc4b55867..3fb874eea 100644 --- a/app/soapbox/components/scrollable_list.tsx +++ b/app/soapbox/components/scrollable_list.tsx @@ -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(({ 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(null); + /** Normalized children */ const elements = Array.from(children || []); @@ -85,6 +90,15 @@ const ScrollableList = React.forwardRef(({ data.push(); } + 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(({ (({ Item, Footer: loadMore, }} - scrollerRef={scrollerRef} + scrollerRef={c => scroller.current = c} /> );