mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(scroll): resolve race condition in onClick scroll-to-top behavior
This commit is contained in:
@@ -45,6 +45,12 @@ export default function App() {
|
||||
const location = useLocation();
|
||||
const isElectron = window.electron && window.electron.isElectron;
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
const [, setNewErrorMessage] = useError();
|
||||
const [, setNewSuccessMessage] = useSuccess();
|
||||
const [, setNewInfoMessage] = useInfo();
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState, useRef } fr
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import { useAccount, useAccountComments, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
|
||||
@@ -541,7 +541,12 @@ const All = () => {
|
||||
navigate(`/p/${selected}`);
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[`all`] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
@@ -552,7 +557,7 @@ const All = () => {
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, []);
|
||||
}, [location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates['all'];
|
||||
|
||||
@@ -578,14 +583,9 @@ const All = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -652,10 +652,9 @@ const All = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -3486,14 +3485,9 @@ const All = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
@@ -777,7 +777,12 @@ const AllCatalog = () => {
|
||||
setSelectedFeed(feed.filter((feed) => feed.title === title));
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[`allCatalog`] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
@@ -788,7 +793,7 @@ const AllCatalog = () => {
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, [selectedAddress]);
|
||||
}, [selectedAddress, location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates['allCatalog'];
|
||||
|
||||
@@ -813,14 +818,9 @@ const AllCatalog = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -894,10 +894,9 @@ const AllCatalog = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -933,11 +932,11 @@ const AllCatalog = () => {
|
||||
</select>
|
||||
</span>
|
||||
<div className='return-button' id='return-button-desktop'>
|
||||
[<Link to={`/p/all`}>Return</Link>]
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
</div>
|
||||
<div id='return-button-mobile'>
|
||||
<span className='btn-wrap-catalog btn-wrap'>
|
||||
<Link to={`/p/all`}>Return</Link>
|
||||
<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
{subplebbits.state === 'succeeded' ? null : (
|
||||
@@ -1008,14 +1007,9 @@ const AllCatalog = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
@@ -698,7 +698,12 @@ const Board = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[selectedAddress] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
@@ -709,7 +714,7 @@ const Board = () => {
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, [selectedAddress]);
|
||||
}, [selectedAddress, location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates[selectedAddress];
|
||||
|
||||
@@ -736,14 +741,9 @@ const Board = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -813,10 +813,9 @@ const Board = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -919,16 +918,8 @@ const Board = () => {
|
||||
</select>
|
||||
</span>
|
||||
<div id='catalog-button-desktop'>
|
||||
[
|
||||
<Link
|
||||
to={`/p/${selectedAddress}/catalog`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Catalog
|
||||
</Link>
|
||||
]{subplebbit.roles && subplebbit?.roles?.[account?.author?.address]?.role === 'admin' ? <BoardSettings subplebbit={subplebbit} /> : null}
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>]
|
||||
{subplebbit.roles && subplebbit?.roles?.[account?.author?.address]?.role === 'admin' ? <BoardSettings subplebbit={subplebbit} /> : null}
|
||||
</div>
|
||||
{subplebbit?.state === 'succeeded' ? (
|
||||
<>
|
||||
@@ -952,14 +943,7 @@ const Board = () => {
|
||||
)}
|
||||
<div id='catalog-button-mobile'>
|
||||
<span className='btn-wrap'>
|
||||
<Link
|
||||
to={`/p/${selectedAddress}/catalog`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Catalog
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>
|
||||
</span>
|
||||
</div>
|
||||
</TopBar>
|
||||
@@ -3759,7 +3743,6 @@ const Board = () => {
|
||||
to={`/p/${selectedAddress}/c/${thread.cid}`}
|
||||
onClick={() => {
|
||||
setSelectedThread(thread.cid);
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
className='button-mobile'
|
||||
>
|
||||
@@ -4568,14 +4551,9 @@ const Board = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
]
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useLayoutEffect, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
@@ -1462,7 +1462,12 @@ const Catalog = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[`${selectedAddress}-catalog`] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
@@ -1473,7 +1478,7 @@ const Catalog = () => {
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, [selectedAddress]);
|
||||
}, [selectedAddress, location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates[`${selectedAddress}-catalog`];
|
||||
|
||||
@@ -1498,14 +1503,9 @@ const Catalog = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -1580,10 +1580,9 @@ const Catalog = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -1688,16 +1687,8 @@ const Catalog = () => {
|
||||
</select>
|
||||
</span>
|
||||
<div className='return-button' id='return-button-desktop'>
|
||||
[
|
||||
<Link
|
||||
to={`/p/${selectedAddress}`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Return
|
||||
</Link>
|
||||
]{subplebbit.roles && subplebbit?.roles[account?.author?.address]?.role === 'admin' ? <BoardSettings subplebbit={subplebbit} /> : null}
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
{subplebbit.roles && subplebbit?.roles[account?.author?.address]?.role === 'admin' ? <BoardSettings subplebbit={subplebbit} /> : null}
|
||||
</div>
|
||||
{subplebbit.state === 'succeeded' ? (
|
||||
<>
|
||||
@@ -1721,14 +1712,7 @@ const Catalog = () => {
|
||||
)}
|
||||
<div id='return-button-mobile'>
|
||||
<span className='btn-wrap-catalog btn-wrap'>
|
||||
<Link
|
||||
to={`/p/${selectedAddress}`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Return
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
@@ -1793,14 +1777,9 @@ const Catalog = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
]
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
@@ -160,14 +160,9 @@ const Description = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -245,7 +240,6 @@ const Description = () => {
|
||||
to='/'
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -275,25 +269,13 @@ const Description = () => {
|
||||
<PostForm selectedStyle={selectedStyle}>
|
||||
<ReplyFormLink id='post-form-link' selectedStyle={selectedStyle} style={{ marginBottom: '10px' }}>
|
||||
<div id='return-button-mobile'>
|
||||
<span
|
||||
className='btn-wrap'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<Link to={`/p/${selectedAddress}`}>Return</Link>
|
||||
<span className='btn-wrap'>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='catalog-button-mobile'>
|
||||
<span className='btn-wrap'>
|
||||
<Link
|
||||
to={`/p/${selectedAddress}/catalog`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Catalog
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='bottom-button-mobile'>
|
||||
@@ -323,10 +305,10 @@ const Description = () => {
|
||||
</select>
|
||||
</span>
|
||||
<span className='return-button' id='return-button-desktop'>
|
||||
[<Link to={`/p/${selectedAddress}`}>Return</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='catalog-button-desktop'>
|
||||
[<Link to={`/p/${selectedAddress}/catalog`}>Catalog</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='bottom-button-desktop'>
|
||||
[
|
||||
@@ -694,14 +676,9 @@ const Description = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
]
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
@@ -31,7 +31,6 @@ const PopularThreads = ({ commentCid }) => {
|
||||
onClick={() => {
|
||||
setSelectedTitle(subplebbit?.title);
|
||||
setSelectedAddress(comment?.subplebbitAddress);
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
{commentMediaInfo?.type === 'webpage' && commentMediaInfo?.thumbnail ? (
|
||||
@@ -223,13 +222,7 @@ const Home = () => {
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<Link
|
||||
to='/p/all'
|
||||
id='button'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<Link to={{ pathname: '/p/all', state: { scrollToTop: true } }} id='button'>
|
||||
[view all]
|
||||
</Link>
|
||||
<ul>
|
||||
@@ -239,10 +232,10 @@ const Home = () => {
|
||||
<Link
|
||||
key={`default-link-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
to={{
|
||||
pathname: `/p/${address}`,
|
||||
state: { scrollToTop: true },
|
||||
}}
|
||||
to={`/p/${address}`}
|
||||
>
|
||||
{address}
|
||||
</Link>
|
||||
@@ -273,14 +266,7 @@ const Home = () => {
|
||||
{defaultNsfwSubplebbits.slice(0, showAllSFWBoards ? undefined : 18).map((subplebbit, index) => (
|
||||
<li key={`default-${index}`}>
|
||||
<OfflineIndicator address={subplebbit.address} className='disconnected' isText={true} />
|
||||
<Link
|
||||
key={`default-link-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
to={`/p/${subplebbit.address}`}
|
||||
>
|
||||
<Link key={`default-link-${index}`} className='boardlink' to={{ pathname: `/p/${subplebbit.address}`, state: { scrollToTop: true } }}>
|
||||
{subplebbit.address}
|
||||
</Link>
|
||||
|
||||
@@ -297,13 +283,7 @@ const Home = () => {
|
||||
<div className='column'>
|
||||
<h3 style={{ textDecoration: 'underline', display: 'inline' }}>Subscriptions</h3>
|
||||
|
||||
<Link
|
||||
to='/p/subscriptions'
|
||||
id='button'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<Link to={{ pathname: '/p/subscriptions', state: { scrollToTop: true } }} id='button'>
|
||||
[view all]
|
||||
</Link>
|
||||
<br />
|
||||
@@ -312,14 +292,7 @@ const Home = () => {
|
||||
{account?.subscriptions?.slice(0, showAllSubscriptions ? undefined : 18).map((subscription, index) => (
|
||||
<li key={`sub-${index}`}>
|
||||
<OfflineIndicator address={subscription} className='disconnected' isText={true} />
|
||||
<Link
|
||||
key={`sub-link-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
to={`/p/${subscription}`}
|
||||
>
|
||||
<Link key={`sub-link-${index}`} className='boardlink' to={{ pathname: `/p/${subscription}`, state: { scrollToTop: true } }}>
|
||||
{subscription}
|
||||
</Link>
|
||||
|
||||
@@ -340,14 +313,7 @@ const Home = () => {
|
||||
{accountSubplebbitsAddresses?.slice(0, showAllSubscriptions ? undefined : 18).map((subplebbit, index) => (
|
||||
<li key={`sub-${index}`}>
|
||||
<OfflineIndicator address={subplebbit} className='disconnected' isText={true} />
|
||||
<Link
|
||||
key={`sub-link-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
to={`/p/${subplebbit}`}
|
||||
>
|
||||
<Link key={`sub-link-${index}`} className='boardlink' to={{ pathname: `/p/${subplebbit}`, state: { scrollToTop: true } }}>
|
||||
{subplebbit}
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -120,14 +120,9 @@ const Pending = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
|
||||
@@ -170,14 +170,9 @@ const Rules = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -255,7 +250,6 @@ const Rules = () => {
|
||||
to='/'
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -285,25 +279,13 @@ const Rules = () => {
|
||||
<PostForm selectedStyle={selectedStyle}>
|
||||
<ReplyFormLink id='post-form-link' selectedStyle={selectedStyle} style={{ marginBottom: '10px' }}>
|
||||
<div id='return-button-mobile'>
|
||||
<span
|
||||
className='btn-wrap'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<Link to={`/p/${selectedAddress}`}>Return</Link>
|
||||
<span className='btn-wrap'>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='catalog-button-mobile'>
|
||||
<span className='btn-wrap'>
|
||||
<Link
|
||||
to={`/p/${selectedAddress}/catalog`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Catalog
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='bottom-button-mobile'>
|
||||
@@ -333,10 +315,10 @@ const Rules = () => {
|
||||
</select>
|
||||
</span>
|
||||
<span className='return-button' id='return-button-desktop'>
|
||||
[<Link to={`/p/${selectedAddress}`}>Return</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='catalog-button-desktop'>
|
||||
[<Link to={`/p/${selectedAddress}/catalog`}>Catalog</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='bottom-button-desktop'>
|
||||
[
|
||||
@@ -630,14 +612,9 @@ const Rules = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
]
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState, useRef } fr
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import { useAccount, useAccountComments, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
|
||||
@@ -540,7 +540,12 @@ const Subscriptions = () => {
|
||||
navigate(`/p/${selected}`);
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[`subscriptions`] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
@@ -551,7 +556,7 @@ const Subscriptions = () => {
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, []);
|
||||
}, [location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates['subscriptions'];
|
||||
|
||||
@@ -577,14 +582,9 @@ const Subscriptions = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -651,10 +651,9 @@ const Subscriptions = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { confirmAlert } from 'react-confirm-alert';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
@@ -710,7 +710,6 @@ const SubscriptionsCatalog = () => {
|
||||
isSettingsOpen,
|
||||
setIsSettingsOpen,
|
||||
originalCommentContent,
|
||||
selectedAddress,
|
||||
setSelectedAddress,
|
||||
selectedStyle,
|
||||
setSelectedTitle,
|
||||
@@ -777,18 +776,23 @@ const SubscriptionsCatalog = () => {
|
||||
navigate(`/p/${selected}`);
|
||||
};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (location.state?.scrollToTop) {
|
||||
lastVirtuosoStates[`subscriptionsCatalog`] = null;
|
||||
}
|
||||
const setLastVirtuosoState = () => {
|
||||
virtuosoRef.current?.getState((snapshot) => {
|
||||
if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
|
||||
lastVirtuosoStates[`${selectedAddress}-catalog`] = snapshot;
|
||||
lastVirtuosoStates[`subscriptionsCatalog`] = snapshot;
|
||||
}
|
||||
});
|
||||
};
|
||||
window.addEventListener('scroll', setLastVirtuosoState);
|
||||
|
||||
return () => window.removeEventListener('scroll', setLastVirtuosoState);
|
||||
}, [selectedAddress]);
|
||||
}, [location.state?.scrollToTop]);
|
||||
|
||||
const lastVirtuosoState = lastVirtuosoStates['subscriptionsCatalog'];
|
||||
|
||||
@@ -813,14 +817,9 @@ const SubscriptionsCatalog = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -894,10 +893,9 @@ const SubscriptionsCatalog = () => {
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to='/'
|
||||
to={{ pathname: '/', state: { scrollToTop: true } }}
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -941,11 +939,11 @@ const SubscriptionsCatalog = () => {
|
||||
</select>
|
||||
</span>
|
||||
<div className='return-button' id='return-button-desktop'>
|
||||
[<Link to={`/p/subscriptions`}>Return</Link>]
|
||||
[<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
</div>
|
||||
<div id='return-button-mobile'>
|
||||
<span className='btn-wrap-catalog btn-wrap'>
|
||||
<Link to={`/p/subscriptions`}>Return</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
{subplebbits.state === 'succeeded' ? null : (
|
||||
@@ -1015,10 +1013,7 @@ const SubscriptionsCatalog = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
|
||||
@@ -664,14 +664,9 @@ const Thread = () => {
|
||||
<NavBar selectedStyle={selectedStyle}>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
] [
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<span className='boardList' key={`span-${subplebbit.address}`}>
|
||||
@@ -749,7 +744,6 @@ const Thread = () => {
|
||||
to='/'
|
||||
onClick={() => {
|
||||
handleStyleChange({ target: { value: 'Yotsuba' } });
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Home
|
||||
@@ -779,25 +773,13 @@ const Thread = () => {
|
||||
<PostForm selectedStyle={selectedStyle} name='post' action='' method='post' enctype='multipart/form-data'>
|
||||
<ReplyFormLink id='post-form-link' showReplyFormLink={showPostFormLink} selectedStyle={selectedStyle}>
|
||||
<div id='return-button-mobile'>
|
||||
<span
|
||||
className='btn-wrap'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<span className='btn-wrap'>
|
||||
<Link to={`/p/${selectedAddress}`}>Return</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='catalog-button-mobile'>
|
||||
<span className='btn-wrap'>
|
||||
<Link
|
||||
to={`/p/${selectedAddress}/catalog`}
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
Catalog
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div id='bottom-button-mobile'>
|
||||
@@ -898,7 +880,7 @@ const Thread = () => {
|
||||
[<Link to={`/p/${selectedAddress}`}>Return</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='catalog-button-desktop'>
|
||||
[<Link to={`/p/${selectedAddress}/catalog`}>Catalog</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>]
|
||||
</span>
|
||||
<span className='return-button catalog-button' id='bottom-button-desktop'>
|
||||
[
|
||||
@@ -3043,10 +3025,10 @@ const Thread = () => {
|
||||
<div id='bottombar-desktop'>
|
||||
<hr />
|
||||
<span className='bottom-bar-return'>
|
||||
[<Link to={`/p/${selectedAddress}`}>Return</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}`, state: { scrollToTop: true } }}>Return</Link>]
|
||||
</span>
|
||||
<span className='bottom-bar-catalog'>
|
||||
[<Link to={`/p/${selectedAddress}/catalog`}>Catalog</Link>]
|
||||
[<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>]
|
||||
</span>
|
||||
<span className='bottom-bar-top'>
|
||||
[
|
||||
@@ -3151,7 +3133,7 @@ const Thread = () => {
|
||||
</div>
|
||||
<div id='catalog-button-mobile' style={{ paddingRight: '2px' }}>
|
||||
<span className='btn-wrap'>
|
||||
<Link to={`/p/${selectedAddress}/catalog`}>Catalog</Link>
|
||||
<Link to={{ pathname: `/p/${selectedAddress}/catalog`, state: { scrollToTop: true } }}>Catalog</Link>
|
||||
</span>
|
||||
</div>
|
||||
<span className='bottom-bar-top'>
|
||||
@@ -3232,14 +3214,9 @@ const Thread = () => {
|
||||
>
|
||||
<>
|
||||
<span className='boardList'>
|
||||
[
|
||||
<Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>
|
||||
All
|
||||
</Link>
|
||||
[<Link to={{ pathname: `/p/all`, state: { scrollToTop: true } }}>All</Link>
|
||||
/
|
||||
<Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>
|
||||
Subscriptions
|
||||
</Link>
|
||||
<Link to={{ pathname: `/p/subscriptions`, state: { scrollToTop: true } }}>Subscriptions</Link>
|
||||
]
|
||||
</span>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
|
||||
Reference in New Issue
Block a user