mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
perf(app): optimize subs loading as much as possible
This commit is contained in:
+27
-16
@@ -1,33 +1,39 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom';
|
import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom';
|
||||||
import { isHomeView } from './lib/utils/view-utils';
|
import { isHomeView } from './lib/utils/view-utils';
|
||||||
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Subplebbit as SubplebbitType, useSubplebbits } from '@plebbit/plebbit-react-hooks';
|
||||||
import styles from './app.module.css';
|
import { useDefaultSubplebbitAddresses } from './hooks/use-default-subplebbits';
|
||||||
import useTheme from './hooks/use-theme';
|
import useTheme from './hooks/use-theme';
|
||||||
|
import styles from './app.module.css';
|
||||||
import Home from './views/home';
|
import Home from './views/home';
|
||||||
import Settings from './views/settings';
|
import Settings from './views/settings';
|
||||||
import Subplebbit from './views/subplebbit';
|
import Subplebbit from './views/subplebbit';
|
||||||
import BoardNav from './components/board-nav';
|
import BoardNav from './components/board-nav';
|
||||||
import BoardBanner from './components/board-banner';
|
import BoardBanner from './components/board-banner';
|
||||||
|
import { DesktopBoardButtons } from './components/board-buttons';
|
||||||
|
import { MobileBoardButtons } from './components/board-buttons';
|
||||||
import BoardStats from './components/board-stats';
|
import BoardStats from './components/board-stats';
|
||||||
import PostForm from './components/post-form';
|
import PostForm from './components/post-form';
|
||||||
import { MobileBoardButtons } from './components/board-buttons';
|
|
||||||
import { DesktopBoardButtons } from './components/board-buttons';
|
|
||||||
|
|
||||||
const BoardLayout = () => {
|
interface BoardLayoutProps {
|
||||||
|
subplebbits: (SubplebbitType | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const BoardLayout = ({ subplebbits }: BoardLayoutProps) => {
|
||||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = subplebbits.find((s) => s?.address === subplebbitAddress);
|
||||||
|
const { address, createdAt, title } = subplebbit || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{subplebbitAddress && (
|
{address && (
|
||||||
<>
|
<>
|
||||||
<BoardNav address={subplebbitAddress} />
|
<BoardNav address={address} subplebbits={subplebbits} />
|
||||||
<BoardBanner title={subplebbit.title} address={subplebbitAddress} />
|
<BoardBanner title={title} address={address} />
|
||||||
<MobileBoardButtons address={subplebbitAddress} />
|
<MobileBoardButtons address={address} />
|
||||||
<PostForm address={subplebbitAddress} />
|
<PostForm address={address} />
|
||||||
<BoardStats address={subplebbitAddress} createdAt={subplebbit.createdAt} />
|
<BoardStats address={address} createdAt={createdAt} />
|
||||||
<DesktopBoardButtons address={subplebbitAddress} />
|
<DesktopBoardButtons address={address} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Outlet />
|
<Outlet />
|
||||||
@@ -40,6 +46,11 @@ const App = () => {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isInHomeView = isHomeView(location.pathname);
|
const isInHomeView = isHomeView(location.pathname);
|
||||||
|
|
||||||
|
const subplebbitAddresses = useDefaultSubplebbitAddresses();
|
||||||
|
const { subplebbits } = useSubplebbits({ subplebbitAddresses });
|
||||||
|
|
||||||
|
console.log(subplebbits);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.body.classList.forEach((className) => document.body.classList.remove(className));
|
document.body.classList.forEach((className) => document.body.classList.remove(className));
|
||||||
document.body.classList.add(theme);
|
document.body.classList.add(theme);
|
||||||
@@ -55,9 +66,9 @@ const App = () => {
|
|||||||
return (
|
return (
|
||||||
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
|
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path='/' element={<Home />} />
|
<Route path='/' element={<Home subplebbits={subplebbits} />} />
|
||||||
<Route element={<BoardLayout />}>
|
<Route element={<BoardLayout subplebbits={subplebbits} />}>
|
||||||
<Route path='/p/:subplebbitAddress' element={<Subplebbit />} />
|
<Route path='/p/:subplebbitAddress' element={<Subplebbit subplebbits={subplebbits} />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='/settings' element={<Settings />} />
|
<Route path='/settings' element={<Settings />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import useDefaultSubplebbits from '../../hooks/use-default-subplebbits';
|
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
import styles from './board-nav.module.css';
|
import styles from './board-nav.module.css';
|
||||||
|
|
||||||
interface BoardNavProps {
|
interface BoardNavProps {
|
||||||
address?: string | undefined;
|
address?: string | undefined;
|
||||||
subplebbits?: any;
|
subplebbits: (Subplebbit | undefined)[];
|
||||||
currentSubplebbit?: string | undefined;
|
currentSubplebbit?: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,15 +16,18 @@ const BoardNavDesktop = ({ subplebbits }: BoardNavProps) => {
|
|||||||
<div className={styles.boardNavDesktop}>
|
<div className={styles.boardNavDesktop}>
|
||||||
<span className={styles.boardList}>
|
<span className={styles.boardList}>
|
||||||
[
|
[
|
||||||
{subplebbits.map((subplebbit: any, index: number) => (
|
{subplebbits.map((subplebbit: any, index: number) => {
|
||||||
<span key={subplebbit.address}>
|
const { address, title } = subplebbit;
|
||||||
{index === 0 ? null : ' '}
|
return (
|
||||||
<Link to={`/p/${subplebbit.address}`} title={subplebbit.title || ''}>
|
<span key={address}>
|
||||||
{subplebbit.address.includes('.') ? subplebbit.address : subplebbit.title || subplebbit.address.slice(0, 10).concat('...')}
|
{index === 0 ? null : ' '}
|
||||||
</Link>
|
<Link to={`/p/${address}`} title={title || ''}>
|
||||||
{index !== subplebbits.length - 1 ? ' /' : null}
|
{address.includes('.') ? address : title || address.slice(0, 10).concat('...')}
|
||||||
</span>
|
</Link>
|
||||||
))}
|
{index !== subplebbits.length - 1 ? ' /' : null}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
]
|
]
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.navTopRight}>
|
<span className={styles.navTopRight}>
|
||||||
@@ -72,13 +75,11 @@ const BoardNavMobile = ({ subplebbits, currentSubplebbit }: BoardNavProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const BoardNav = ({ address }: BoardNavProps) => {
|
const BoardNav = ({ address, subplebbits }: BoardNavProps) => {
|
||||||
const defaultSubplebbits = useDefaultSubplebbits();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BoardNavDesktop subplebbits={defaultSubplebbits} />
|
<BoardNavDesktop subplebbits={subplebbits} />
|
||||||
<BoardNavMobile subplebbits={defaultSubplebbits} currentSubplebbit={address} />
|
<BoardNavMobile subplebbits={subplebbits} currentSubplebbit={address} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import ReactMarkdown from 'react-markdown';
|
|||||||
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
import supersub from 'remark-supersub';
|
import supersub from 'remark-supersub';
|
||||||
import { visit } from 'unist-util-visit';
|
|
||||||
|
|
||||||
interface MarkdownProps {
|
interface MarkdownProps {
|
||||||
content: string;
|
content: string;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hrWrapper hr {
|
.postDesktop .hrWrapper hr {
|
||||||
margin: 0; /* margin bugs Virtuoso scrolling */
|
margin: 0; /* margin bugs Virtuoso scrolling */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hrWrapper {
|
.postDesktop .hrWrapper {
|
||||||
padding-top: 0.5em; /* instead of using margin, wrap with padding */
|
padding-top: 0.5em; /* instead of using margin, wrap with padding */
|
||||||
padding-bottom: 0.5em;
|
padding-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
@@ -89,8 +89,24 @@
|
|||||||
padding: 1em 40px;
|
padding: 1em 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.postMobile hr {
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.postMobile .thread {
|
||||||
|
border-top: none;
|
||||||
|
margin: 0;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.postDesktop {
|
.postDesktop {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 641px) {
|
||||||
|
.postMobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import { getLinkMediaInfoMemoized } from '../../lib/utils/media-utils';
|
|||||||
import { getFormattedDate } from '../../lib/utils/time-utils';
|
import { getFormattedDate } from '../../lib/utils/time-utils';
|
||||||
import Markdown from '../markdown';
|
import Markdown from '../markdown';
|
||||||
|
|
||||||
const Post = ({ post }: Comment) => {
|
const PostDesktop = ({ post }: Comment) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { author, cid, content, link, locked, pinned, postCid, shortCid, subplebbitAddress, timestamp, title } = post || {};
|
const { author, cid, content, link, locked, pinned, postCid, shortCid, subplebbitAddress, timestamp, title } = post || {};
|
||||||
const { displayName, shortAddress } = author || {};
|
const { displayName, shortAddress } = author || {};
|
||||||
@@ -15,64 +15,85 @@ const Post = ({ post }: Comment) => {
|
|||||||
const linkMediaInfo = getLinkMediaInfoMemoized(link);
|
const linkMediaInfo = getLinkMediaInfoMemoized(link);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.thread}>
|
<div className={styles.postDesktop}>
|
||||||
<div className={styles.postContainer}>
|
<div className={styles.hrWrapper}>
|
||||||
<div className={styles.postDesktop}>
|
<hr />
|
||||||
<div className={styles.hrWrapper}>
|
</div>
|
||||||
<hr />
|
{linkMediaInfo?.url && (
|
||||||
</div>
|
<div className={styles.link}>
|
||||||
{linkMediaInfo?.url && (
|
{t('link')}:{' '}
|
||||||
<div className={styles.link}>
|
<a href={linkMediaInfo?.url} target='_blank' rel='noopener noreferrer'>
|
||||||
{t('link')}:{' '}
|
{linkMediaInfo.url.length > 30 ? linkMediaInfo?.url.slice(0, 30) + '...' : linkMediaInfo?.url}
|
||||||
<a href={linkMediaInfo?.url} target='_blank' rel='noopener noreferrer'>
|
</a>{' '}
|
||||||
{linkMediaInfo.url.length > 30 ? linkMediaInfo?.url.slice(0, 30) + '...' : linkMediaInfo?.url}
|
({linkMediaInfo?.type})
|
||||||
</a>{' '}
|
</div>
|
||||||
({linkMediaInfo?.type})
|
)}
|
||||||
</div>
|
<div className={styles.postInfo}>
|
||||||
)}
|
{title && <span className={styles.subject}>{title.length > 75 ? title.slice(0, 75) + '...' : title}</span>}{' '}
|
||||||
<div className={styles.postInfo}>
|
<span className={styles.nameBlock}>
|
||||||
{title && <span className={styles.subject}>{title.length > 75 ? title.slice(0, 75) + '...' : title}</span>}{' '}
|
<span className={styles.name}>{displayName || 'Anonymous'} </span>
|
||||||
<span className={styles.nameBlock}>
|
<span className={styles.userAddress}>(u/{shortAddress}) </span>
|
||||||
<span className={styles.name}>{displayName || 'Anonymous'} </span>
|
</span>
|
||||||
<span className={styles.userAddress}>(u/{shortAddress}) </span>
|
<span className={styles.dateTime}>{getFormattedDate(timestamp)} </span>
|
||||||
|
<span className={styles.postNum}>
|
||||||
|
<span className={styles.postNumLink}>
|
||||||
|
<Link to={`/p/${subplebbitAddress}/c/${cid}`} className={styles.linkToPost} title={t('link_to_post')}>
|
||||||
|
c/
|
||||||
|
</Link>
|
||||||
|
<span className={styles.replyToPost} title={t('reply_to_post')}>
|
||||||
|
{shortCid}
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.dateTime}>{getFormattedDate(timestamp)} </span>
|
</span>
|
||||||
<span className={styles.postNum}>
|
{pinned && (
|
||||||
<span className={styles.postNumLink}>
|
<span className={styles.stickyIconWrapper}>
|
||||||
<Link to={`/p/${subplebbitAddress}/c/${cid}`} className={styles.linkToPost} title={t('link_to_post')}>
|
<img src='assets/icons/sticky.gif' alt='' className={styles.stickyIcon} title={t('sticky')} />
|
||||||
c/
|
|
||||||
</Link>
|
|
||||||
<span className={styles.replyToPost} title={t('reply_to_post')}>
|
|
||||||
{shortCid}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
{pinned && (
|
|
||||||
<span className={styles.stickyIconWrapper}>
|
|
||||||
<img src='assets/icons/sticky.gif' alt='' className={styles.stickyIcon} title={t('sticky')} />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{locked && (
|
|
||||||
<span className={styles.closedIconWrapper}>
|
|
||||||
<img src='assets/icons/closed.gif' alt='' className={styles.closedIcon} title={t('closed')} />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<span className={styles.replyButton}>
|
|
||||||
[<Link to={`/p/${subplebbitAddress}/c/${postCid}`}>{t('reply')}</Link>]
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.postMenuBtn}>▶</span>
|
|
||||||
</div>
|
|
||||||
{content && (
|
|
||||||
<div className={styles.postMessage}>
|
|
||||||
<blockquote>
|
|
||||||
<Markdown content={content} />
|
|
||||||
</blockquote>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
{locked && (
|
||||||
|
<span className={styles.closedIconWrapper}>
|
||||||
|
<img src='assets/icons/closed.gif' alt='' className={styles.closedIcon} title={t('closed')} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span className={styles.replyButton}>
|
||||||
|
[<Link to={`/p/${subplebbitAddress}/c/${postCid}`}>{t('reply')}</Link>]
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span className={styles.postMenuBtn}>▶</span>
|
||||||
|
</div>
|
||||||
|
{content && (
|
||||||
|
<div className={styles.postMessage}>
|
||||||
|
<blockquote>
|
||||||
|
<Markdown content={content} />
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PostMobile = ({ post }: Comment) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.postMobile}>
|
||||||
|
<hr />
|
||||||
|
<div className={styles.thread}>
|
||||||
|
<div className={styles.postContainer}>
|
||||||
|
<div className={styles.postOp}></div>
|
||||||
|
<div className={styles.postLinkMobile}></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Post = ({ post }: Comment) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.thread}>
|
||||||
|
<div className={styles.postContainer}>
|
||||||
|
<PostDesktop post={post} />
|
||||||
|
<PostMobile post={post} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Post;
|
export default Post;
|
||||||
|
|||||||
+18
-10
@@ -2,9 +2,13 @@ import { useRef } from 'react';
|
|||||||
import styles from './home.module.css';
|
import styles from './home.module.css';
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
import packageJson from '../../../package.json';
|
import packageJson from '../../../package.json';
|
||||||
|
|
||||||
|
interface HomeProps {
|
||||||
|
subplebbits: (Subplebbit | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
const isValidAddress = (address: string): boolean => {
|
const isValidAddress = (address: string): boolean => {
|
||||||
if (address.includes('/') || address.includes('\\') || address.includes(' ')) {
|
if (address.includes('/') || address.includes('\\') || address.includes(' ')) {
|
||||||
return false;
|
return false;
|
||||||
@@ -65,9 +69,8 @@ const InfoBox = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Boards = () => {
|
const Boards = ({ subplebbits }: HomeProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.box}>
|
<div className={styles.box}>
|
||||||
@@ -79,11 +82,16 @@ const Boards = () => {
|
|||||||
<div className={styles.column}>
|
<div className={styles.column}>
|
||||||
<h3>Default SFW</h3>
|
<h3>Default SFW</h3>
|
||||||
<div className={styles.list}>
|
<div className={styles.list}>
|
||||||
{defaultSubplebbitAddresses.map((address) => (
|
{subplebbits
|
||||||
<div className={styles.subplebbit} key={address}>
|
.filter((subplebbit): subplebbit is Subplebbit => subplebbit !== undefined)
|
||||||
<Link to={`/p/${address}`}>{address}</Link>
|
.map((subplebbit) => {
|
||||||
</div>
|
const address = subplebbit.address;
|
||||||
))}
|
return (
|
||||||
|
<div className={styles.subplebbit} key={address}>
|
||||||
|
<Link to={`/p/${address}`}>{address}</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.column}>
|
<div className={styles.column}>
|
||||||
@@ -193,7 +201,7 @@ const Footer = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Home = () => {
|
const Home = ({ subplebbits }: HomeProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Link to='/'>
|
<Link to='/'>
|
||||||
@@ -203,7 +211,7 @@ const Home = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
<InfoBox />
|
<InfoBox />
|
||||||
<Boards />
|
<Boards subplebbits={subplebbits} />
|
||||||
<PopularThreads />
|
<PopularThreads />
|
||||||
<Stats />
|
<Stats />
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useMemo, useRef } from 'react';
|
import { useEffect, useMemo, useRef } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useFeed, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Subplebbit as SubplebbitType, useFeed } from '@plebbit/plebbit-react-hooks';
|
||||||
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
|
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import styles from './subplebbit.module.css';
|
import styles from './subplebbit.module.css';
|
||||||
@@ -9,12 +9,18 @@ import LoadingEllipsis from '../../components/loading-ellipsis';
|
|||||||
import Post from '../../components/post';
|
import Post from '../../components/post';
|
||||||
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
||||||
|
|
||||||
const Subplebbit = () => {
|
interface SubplebbitProps {
|
||||||
|
subplebbits: (SubplebbitType | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Subplebbit = ({ subplebbits }: SubplebbitProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
||||||
|
const subplebbit = subplebbits.find((s) => s?.address === subplebbitAddress);
|
||||||
const subplebbitAddresses = useMemo(() => [subplebbitAddress], [subplebbitAddress]) as string[];
|
const subplebbitAddresses = useMemo(() => [subplebbitAddress], [subplebbitAddress]) as string[];
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const { shortAddress, state, title } = subplebbit || {};
|
||||||
const { createdAt, description, roles, rules, shortAddress, state, title, updatedAt, settings } = subplebbit || {};
|
|
||||||
const sortType = 'active';
|
const sortType = 'active';
|
||||||
const { feed, hasMore, loadMore } = useFeed({ subplebbitAddresses, sortType });
|
const { feed, hasMore, loadMore } = useFeed({ subplebbitAddresses, sortType });
|
||||||
const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading');
|
const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading');
|
||||||
|
|||||||
Reference in New Issue
Block a user