implement VirtuosoGrid in catalog views

This commit is contained in:
plebeius.eth
2023-07-25 21:10:22 +02:00
parent a6dd7b2dfa
commit 6241772016
4 changed files with 385 additions and 357 deletions
@@ -1,5 +1,12 @@
import styled from 'styled-components'; import styled from 'styled-components';
export const GridContainer = styled.div`
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 100%;
`;
export const Threads = styled.div` export const Threads = styled.div`
padding: 20px 0; padding: 20px 0;
text-align: center; text-align: center;
@@ -7,7 +14,7 @@ export const Threads = styled.div`
.thread { .thread {
width: 180px; width: 180px;
max-height: 320px; height: 320px;
vertical-align: top; vertical-align: top;
display: inline-block; display: inline-block;
word-wrap: break-word; word-wrap: break-word;
+17 -15
View File
@@ -1,14 +1,14 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import InfiniteScroll from 'react-infinite-scroller';
import { Link, useNavigate} from 'react-router-dom'; import { Link, useNavigate} from 'react-router-dom';
import { confirmAlert } from 'react-confirm-alert'; import { confirmAlert } from 'react-confirm-alert';
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import { VirtuosoGrid } from 'react-virtuoso';
import { useAccount, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks'; import { useAccount, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { Container, NavBar, Header, Break, PostMenu, BoardForm } from '../styled/views/Board.styled'; import { Container, NavBar, Header, Break, PostMenu, BoardForm } from '../styled/views/Board.styled';
import { Threads, PostMenuCatalog } from '../styled/views/Catalog.styled'; import { Threads, PostMenuCatalog, GridContainer } from '../styled/views/Catalog.styled';
import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled'; import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled';
import CatalogLoader from '../CatalogLoader'; import CatalogLoader from '../CatalogLoader';
import EditModal from '../modals/EditModal'; import EditModal from '../modals/EditModal';
@@ -74,7 +74,7 @@ const AllCatalog = () => {
const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);
const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address); const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address);
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: addresses, sortType: 'active'}); const { feed, loadMore } = useFeed({subplebbitAddresses: addresses, sortType: 'active'});
const {subplebbits} = useSubplebbits({subplebbitAddresses: addresses, sortType: 'active'}); const {subplebbits} = useSubplebbits({subplebbitAddresses: addresses, sortType: 'active'});
const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp)); const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp));
@@ -467,13 +467,13 @@ const AllCatalog = () => {
</TopBar> </TopBar>
<Tooltip id="tooltip" className="tooltip" /> <Tooltip id="tooltip" className="tooltip" />
<Threads selectedStyle={selectedStyle}> <Threads selectedStyle={selectedStyle}>
{feed ? ( {feed.length > 1 ? (
<InfiniteScroll <VirtuosoGrid
pageStart={0} style={{width: '100%', height: '100%'}}
loadMore={tryLoadMore} data={feed}
hasMore={hasMore} increaseViewportBy={{bottom: 600, top: 600}}
> itemContent={(index) => {
{feed.map((thread, index) => { const thread = feed[index];
const commentMediaInfo = getCommentMediaInfo(thread); const commentMediaInfo = getCommentMediaInfo(thread);
const fallbackImgUrl = "assets/filedeleted-res.gif"; const fallbackImgUrl = "assets/filedeleted-res.gif";
const isModerator = moderatorPermissions[thread.subplebbitAddress]; const isModerator = moderatorPermissions[thread.subplebbitAddress];
@@ -662,11 +662,13 @@ const AllCatalog = () => {
</div> </div>
</Link> </Link>
</div> </div>
)})} )
</InfiniteScroll> }}
) : ( endReached={tryLoadMore}
<CatalogLoader /> useWindowScroll={true}
)} components={{List: GridContainer}}
/>
) : (<CatalogLoader />)}
</Threads> </Threads>
<Footer selectedStyle={selectedStyle}> <Footer selectedStyle={selectedStyle}>
<Break id="break" selectedStyle={selectedStyle} style={{ <Break id="break" selectedStyle={selectedStyle} style={{
+43 -26
View File
@@ -1,14 +1,14 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import InfiniteScroll from 'react-infinite-scroller';
import { Link, useNavigate, useParams } from 'react-router-dom'; import { Link, useNavigate, useParams } from 'react-router-dom';
import { confirmAlert } from 'react-confirm-alert'; import { confirmAlert } from 'react-confirm-alert';
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import { VirtuosoGrid } from 'react-virtuoso';
import { useAccount, useFeed, usePublishComment, usePublishCommentEdit, useSubplebbit, useSubscribe } from '@plebbit/plebbit-react-hooks'; import { useAccount, useFeed, usePublishComment, usePublishCommentEdit, useSubplebbit, useSubscribe } from '@plebbit/plebbit-react-hooks';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { Container, NavBar, Header, Break, PostForm, PostFormLink, PostFormTable, PostMenu, BoardForm } from '../styled/views/Board.styled'; import { Container, NavBar, Header, Break, PostForm, PostFormLink, PostFormTable, PostMenu, BoardForm } from '../styled/views/Board.styled';
import { Threads, PostMenuCatalog } from '../styled/views/Catalog.styled'; import { Threads, PostMenuCatalog, GridContainer } from '../styled/views/Catalog.styled';
import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled'; import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled';
import CatalogLoader from '../CatalogLoader'; import CatalogLoader from '../CatalogLoader';
import EditModal from '../modals/EditModal'; import EditModal from '../modals/EditModal';
@@ -87,16 +87,25 @@ const Catalog = () => {
const [executeAnonMode, setExecuteAnonMode] = useState(false); const [executeAnonMode, setExecuteAnonMode] = useState(false);
const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: [`${selectedAddress}`], sortType: 'active'}); const account = useAccount();
const { feed, loadMore } = useFeed({subplebbitAddresses: [`${selectedAddress}`], sortType: 'active'});
const { subplebbitAddress } = useParams(); const { subplebbitAddress } = useParams();
const subplebbit = useSubplebbit({subplebbitAddress: selectedAddress}); const subplebbit = useSubplebbit({subplebbitAddress: selectedAddress});
const account = useAccount();
const stateString = useStateString(subplebbit); const stateString = useStateString(subplebbit);
let feedWithDescriptionAndRules = [];
useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode);
if (subplebbit.rules) {
feedWithDescriptionAndRules.push({type: 'rules', content: subplebbit.rules});
}
if (subplebbit.description) {
feedWithDescriptionAndRules.push({type: 'description', content: subplebbit.description});
}
useEffect(() => { useEffect(() => {
if (subplebbit.roles !== undefined) { if (subplebbit.roles !== undefined) {
const role = subplebbit.roles[account?.author.address]?.role; const role = subplebbit.roles[account?.author.address]?.role;
@@ -716,16 +725,20 @@ const Catalog = () => {
</TopBar> </TopBar>
<Tooltip id="tooltip" className="tooltip" /> <Tooltip id="tooltip" className="tooltip" />
<Threads selectedStyle={selectedStyle}> <Threads selectedStyle={selectedStyle}>
{subplebbit?.state === "failed" ? ( {subplebbit?.state !== "failed" && subplebbit.state === "succeeded" ? (
null <VirtuosoGrid
) : ( style={{width: '100%', height: '100%'}}
subplebbit.state === "succeeded" ? ( data={feed}
<InfiniteScroll increaseViewportBy={{bottom: 600, top: 600}}
pageStart={0} itemContent={(index) => {
loadMore={tryLoadMore} const thread = feed[index];
hasMore={hasMore} const commentMediaInfo = getCommentMediaInfo(thread);
> const linkCount = countLinks(thread);
{subplebbit.rules ? ( const fallbackImgUrl = "assets/filedeleted-res.gif";
const item = feedWithDescriptionAndRules[index];
if (item?.type === 'rules') {
return (
<div className='thread' <div className='thread'
onMouseOver={() => setIsHoveringOnThread('rules')} onMouseOver={() => setIsHoveringOnThread('rules')}
onMouseLeave={() => setIsHoveringOnThread('')}> onMouseLeave={() => setIsHoveringOnThread('')}>
@@ -792,8 +805,10 @@ const Catalog = () => {
</div> </div>
</Link> </Link>
</div> </div>
) : null} )
{subplebbit.description ? ( } else if (item?.type === 'description') {
return (
<>
<div className='thread' <div className='thread'
onMouseOver={() => setIsHoveringOnThread('description')} onMouseOver={() => setIsHoveringOnThread('description')}
onMouseLeave={() => setIsHoveringOnThread('')}> onMouseLeave={() => setIsHoveringOnThread('')}>
@@ -907,11 +922,9 @@ const Catalog = () => {
</div> </div>
</Link> </Link>
</div> </div>
) : null} </>
{feed.map((thread, index) => { )
const commentMediaInfo = getCommentMediaInfo(thread); } else {
const fallbackImgUrl = "assets/filedeleted-res.gif";
const linkCount = countLinks(thread);
return ( return (
<div key={`thread-${index}`} className="thread" <div key={`thread-${index}`} className="thread"
onMouseOver={() => {setIsHoveringOnThread(thread.cid)}} onMouseOver={() => {setIsHoveringOnThread(thread.cid)}}
@@ -1114,10 +1127,14 @@ const Catalog = () => {
</div> </div>
</Link> </Link>
</div> </div>
)})} )
</InfiniteScroll> }
) : (<CatalogLoader />) }}
)} endReached={tryLoadMore}
useWindowScroll={true}
components={{List: GridContainer}}
/>
) : (<CatalogLoader />)}
</Threads> </Threads>
<Footer selectedStyle={selectedStyle}> <Footer selectedStyle={selectedStyle}>
<Break id="break" selectedStyle={selectedStyle} style={{ <Break id="break" selectedStyle={selectedStyle} style={{
+17 -15
View File
@@ -1,15 +1,15 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import InfiniteScroll from 'react-infinite-scroller';
import { Link, useNavigate} from 'react-router-dom'; import { Link, useNavigate} from 'react-router-dom';
import { confirmAlert } from 'react-confirm-alert'; import { confirmAlert } from 'react-confirm-alert';
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import { VirtuosoGrid } from 'react-virtuoso';
import { useAccount, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks'; import { useAccount, useFeed, usePublishCommentEdit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import useGeneralStore from '../../hooks/stores/useGeneralStore'; import useGeneralStore from '../../hooks/stores/useGeneralStore';
import { Container, NavBar, Header, Break, PostMenu, BoardForm } from '../styled/views/Board.styled'; import { Container, NavBar, Header, Break, PostMenu, BoardForm } from '../styled/views/Board.styled';
import { Threads, PostMenuCatalog } from '../styled/views/Catalog.styled'; import { Threads, PostMenuCatalog, GridContainer } from '../styled/views/Catalog.styled';
import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled'; import { TopBar, Footer, AuthorDeleteAlert } from '../styled/views/Thread.styled';
import CatalogLoader from '../CatalogLoader'; import CatalogLoader from '../CatalogLoader';
import EditModal from '../modals/EditModal'; import EditModal from '../modals/EditModal';
@@ -72,7 +72,7 @@ const SubscriptionsCatalog = () => {
const [moderatorPermissions, setModeratorPermissions] = useState({}); const [moderatorPermissions, setModeratorPermissions] = useState({});
const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);
const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); const { feed, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'});
const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp)); const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp));
const {subplebbits} = useSubplebbits({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); const {subplebbits} = useSubplebbits({subplebbitAddresses: account?.subscriptions, sortType: 'active'});
@@ -471,13 +471,13 @@ const SubscriptionsCatalog = () => {
</TopBar> </TopBar>
<Tooltip id="tooltip" className="tooltip" /> <Tooltip id="tooltip" className="tooltip" />
<Threads selectedStyle={selectedStyle}> <Threads selectedStyle={selectedStyle}>
{feed ? ( {feed.length > 1 ? (
<InfiniteScroll <VirtuosoGrid
pageStart={0} style={{width: '100%', height: '100%'}}
loadMore={tryLoadMore} data={feed}
hasMore={hasMore} increaseViewportBy={{bottom: 600, top: 600}}
> itemContent={(index) => {
{feed.map((thread, index) => { const thread = feed[index];
const commentMediaInfo = getCommentMediaInfo(thread); const commentMediaInfo = getCommentMediaInfo(thread);
const fallbackImgUrl = "assets/filedeleted-res.gif"; const fallbackImgUrl = "assets/filedeleted-res.gif";
const isModerator = moderatorPermissions[thread.subplebbitAddress]; const isModerator = moderatorPermissions[thread.subplebbitAddress];
@@ -666,11 +666,13 @@ const SubscriptionsCatalog = () => {
</div> </div>
</Link> </Link>
</div> </div>
)})} )
</InfiniteScroll> }}
) : ( endReached={tryLoadMore}
<CatalogLoader /> useWindowScroll={true}
)} components={{List: GridContainer}}
/>
) : (<CatalogLoader />)}
</Threads> </Threads>
<Footer selectedStyle={selectedStyle}> <Footer selectedStyle={selectedStyle}>
<Break id="break" selectedStyle={selectedStyle} style={{ <Break id="break" selectedStyle={selectedStyle} style={{