From e08c7a6b13ee2a22a03667d2e31b837f1581085a Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 14 Jul 2023 14:37:12 +0200 Subject: [PATCH] retain virtuoso scroll position --- src/components/views/All.jsx | 23 ++++++++++++++++++++++- src/components/views/Board.jsx | 23 +++++++++++++++++++++-- src/components/views/Subscriptions.jsx | 23 ++++++++++++++++++++++- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index c77a4967..26dc6d5d 100755 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -41,6 +41,7 @@ import useAnonModeStore from '../../hooks/stores/useAnonModeStore'; import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson +let lastVirtuosoStates = {}; const All = () => { @@ -85,6 +86,7 @@ const All = () => { const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); const selectedThreadCidRef = useRef(null); + const virtuosoRef = useRef(); const [isReplyOpen, setIsReplyOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); @@ -484,6 +486,22 @@ const All = () => { }; + useEffect(() => { + const setLastVirtuosoState = () => { + virtuosoRef.current?.getState((snapshot) => { + if (snapshot?.ranges?.length) { + lastVirtuosoStates['all'] = snapshot; + } + }); + }; + window.addEventListener('scroll', setLastVirtuosoState); + + return () => window.removeEventListener('scroll', setLastVirtuosoState); + }, []); + + const lastVirtuosoState = lastVirtuosoStates['all']; + + return ( <> @@ -620,7 +638,7 @@ const All = () => {
{feed ? ( { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; @@ -2202,6 +2220,9 @@ const All = () => { ); }} + ref={virtuosoRef} + restoreStateFrom={lastVirtuosoState} + initialScrollTop={lastVirtuosoState?.scrollTop} endReached={tryLoadMore} useWindowScroll={true} components={{ Footer: hasMore && feed.length > 0 ? () => : null }} diff --git a/src/components/views/Board.jsx b/src/components/views/Board.jsx index a1a60c2d..57f49116 100755 --- a/src/components/views/Board.jsx +++ b/src/components/views/Board.jsx @@ -43,6 +43,7 @@ import useAnonModeStore from '../../hooks/stores/useAnonModeStore'; import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson +let lastVirtuosoStates = {}; const Board = () => { @@ -103,6 +104,7 @@ const Board = () => { const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); const selectedThreadCidRef = useRef(null); + const virtuosoRef = useRef(); const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: [`${selectedAddress}`], sortType: 'active'}); const subplebbit = useSubplebbit({subplebbitAddress: selectedAddress}); @@ -648,7 +650,21 @@ const Board = () => { }; - + useEffect(() => { + const setLastVirtuosoState = () => { + virtuosoRef.current?.getState((snapshot) => { + if (snapshot?.ranges?.length) { + lastVirtuosoStates[selectedAddress] = snapshot; + } + }); + }; + window.addEventListener('scroll', setLastVirtuosoState); + + return () => window.removeEventListener('scroll', setLastVirtuosoState); + }, [selectedAddress]); + + const lastVirtuosoState = lastVirtuosoStates[selectedAddress]; + return ( <> @@ -1267,7 +1283,7 @@ const Board = () => { : null} { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; @@ -2825,6 +2841,9 @@ const Board = () => { ); }} + ref={virtuosoRef} + restoreStateFrom={lastVirtuosoState} + initialScrollTop={lastVirtuosoState?.scrollTop} endReached={tryLoadMore} useWindowScroll={true} components={{ Footer: hasMore && feed.length > 0 ? () => : null }} diff --git a/src/components/views/Subscriptions.jsx b/src/components/views/Subscriptions.jsx index bfafc125..f7cb8dea 100755 --- a/src/components/views/Subscriptions.jsx +++ b/src/components/views/Subscriptions.jsx @@ -41,6 +41,7 @@ import useSuccess from '../../hooks/useSuccess'; import useAnonModeStore from '../../hooks/stores/useAnonModeStore'; import packageJson from '../../../package.json' const {version} = packageJson +let lastVirtuosoStates = {}; const Subscriptions = () => { @@ -85,6 +86,7 @@ const Subscriptions = () => { const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); const selectedThreadCidRef = useRef(null); + const virtuosoRef = useRef(); const [isReplyOpen, setIsReplyOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); @@ -487,6 +489,22 @@ const Subscriptions = () => { }; + useEffect(() => { + const setLastVirtuosoState = () => { + virtuosoRef.current?.getState((snapshot) => { + if (snapshot?.ranges?.length) { + lastVirtuosoStates['subscriptions'] = snapshot; + } + }); + }; + window.addEventListener('scroll', setLastVirtuosoState); + + return () => window.removeEventListener('scroll', setLastVirtuosoState); + }, []); + + const lastVirtuosoState = lastVirtuosoStates['subscriptions']; + + return ( <> @@ -631,7 +649,7 @@ const Subscriptions = () => { null ) : ( { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; @@ -2213,6 +2231,9 @@ const Subscriptions = () => { ); }} + ref={virtuosoRef} + restoreStateFrom={lastVirtuosoState} + initialScrollTop={lastVirtuosoState?.scrollTop} endReached={tryLoadMore} useWindowScroll={true} components={{ Footer: hasMore && feed.length > 0 ? () => : null }}