mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(app): add pending post view
This commit is contained in:
+25
-18
@@ -3,15 +3,16 @@ 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 useTheme from './hooks/use-theme';
|
import useTheme from './hooks/use-theme';
|
||||||
import styles from './app.module.css';
|
import styles from './app.module.css';
|
||||||
|
import Board from './views/board';
|
||||||
import Catalog from './views/catalog';
|
import Catalog from './views/catalog';
|
||||||
import Home from './views/home';
|
import Home from './views/home';
|
||||||
|
import PendingPost from './views/pending-post';
|
||||||
import PostPage from './views/post-page';
|
import PostPage from './views/post-page';
|
||||||
import Settings from './views/settings';
|
import Settings from './views/settings';
|
||||||
import Board from './views/board';
|
|
||||||
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 { DesktopBoardButtons, MobileBoardButtons } from './components/board-buttons';
|
||||||
import { MobileBoardButtons } from './components/board-buttons';
|
import BoardNav from './components/board-nav';
|
||||||
|
import ChallengeModal from './components/challenge-modal';
|
||||||
import SubplebbitStats from './components/subplebbit-stats';
|
import SubplebbitStats from './components/subplebbit-stats';
|
||||||
import PostForm from './components/post-form';
|
import PostForm from './components/post-form';
|
||||||
|
|
||||||
@@ -40,25 +41,31 @@ const App = () => {
|
|||||||
document.body.classList.add(theme);
|
document.body.classList.add(theme);
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
// const globalLayout = (
|
const globalLayout = (
|
||||||
// <>
|
<>
|
||||||
// <ChallengeModal />
|
<ChallengeModal />
|
||||||
// <Outlet />
|
<Outlet />
|
||||||
// </>
|
</>
|
||||||
// );
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
|
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path='/' element={<Home />} />
|
<Route element={globalLayout}>
|
||||||
<Route element={<BoardLayout />}>
|
<Route path='/' element={<Home />} />
|
||||||
<Route path='/p/:subplebbitAddress' element={<Board />} />
|
<Route element={<BoardLayout />}>
|
||||||
<Route path='/p/:subplebbitAddress/c/:commentCid' element={<PostPage />} />
|
<Route path='/p/:subplebbitAddress' element={<Board />} />
|
||||||
<Route path='/p/:subplebbitAddress/description' element={<PostPage />} />
|
|
||||||
<Route path='/p/:subplebbitAddress/rules' element={<PostPage />} />
|
<Route path='/p/:subplebbitAddress/catalog' element={<Catalog />} />
|
||||||
<Route path='/p/:subplebbitAddress/catalog' element={<Catalog />} />
|
|
||||||
|
<Route path='/p/:subplebbitAddress/c/:commentCid' element={<PostPage />} />
|
||||||
|
<Route path='/p/:subplebbitAddress/description' element={<PostPage />} />
|
||||||
|
<Route path='/p/:subplebbitAddress/rules' element={<PostPage />} />
|
||||||
|
|
||||||
|
<Route path='/profile/:accountCommentIndex' element={<PendingPost />} />
|
||||||
|
</Route>
|
||||||
|
<Route path='/settings' element={<Settings />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='/settings' element={<Settings />} />
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { useAccountComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import styles from './board-banner.module.css';
|
import styles from './board-banner.module.css';
|
||||||
|
|
||||||
@@ -15,7 +15,10 @@ const ImageBanner = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const BoardBanner = () => {
|
const BoardBanner = () => {
|
||||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
const params = useParams();
|
||||||
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
|
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = useSubplebbit({ subplebbitAddress });
|
||||||
const { address, title } = subplebbit || {};
|
const { address, title } = subplebbit || {};
|
||||||
const displayAddress = address && address.length > 10 && !address.includes('.') ? address.slice(0, 13).concat('...') : address;
|
const displayAddress = address && address.length > 10 && !address.includes('.') ? address.slice(0, 13).concat('...') : address;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import { useSubscribe } from '@plebbit/plebbit-react-hooks';
|
import { useAccountComment, useSubscribe } from '@plebbit/plebbit-react-hooks';
|
||||||
import styles from './board-buttons.module.css';
|
import styles from './board-buttons.module.css';
|
||||||
import { isCatalogView, isPostPageView } from '../../lib/utils/view-utils';
|
import { isCatalogView, isPendingPostView, isPostPageView } from '../../lib/utils/view-utils';
|
||||||
|
|
||||||
interface BoardButtonsProps {
|
interface BoardButtonsProps {
|
||||||
address: string | undefined;
|
address: string | undefined;
|
||||||
@@ -53,25 +53,30 @@ const BottomButton = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const MobileBoardButtons = () => {
|
export const MobileBoardButtons = () => {
|
||||||
const { subplebbitAddress: address } = useParams<{ subplebbitAddress: string }>();
|
const params = useParams();
|
||||||
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
|
const location = useLocation();
|
||||||
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
|
const isInPostPage = isPostPageView(location.pathname, params);
|
||||||
|
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.mobileBoardButtons}>
|
<div className={styles.mobileBoardButtons}>
|
||||||
{isInPostPage ? (
|
{isInPostPage || isInPendingPostPage ? (
|
||||||
<div className={styles.mobilePostPageButtons}>
|
<div className={styles.mobilePostPageButtons}>
|
||||||
<ReturnButton address={address} />
|
<ReturnButton address={subplebbitAddress} />
|
||||||
<CatalogButton address={address} />
|
<CatalogButton address={subplebbitAddress} />
|
||||||
<BottomButton />
|
<BottomButton />
|
||||||
<div className={styles.mobilePostPageButtonsSecondRow}>
|
<div className={styles.mobilePostPageButtonsSecondRow}>
|
||||||
<OptionsButton />
|
<OptionsButton />
|
||||||
<SubscribeButton address={address} />
|
<SubscribeButton address={subplebbitAddress} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<OptionsButton />
|
<OptionsButton />
|
||||||
<CatalogButton address={address} />
|
<CatalogButton address={subplebbitAddress} />
|
||||||
<SubscribeButton address={address} />
|
<SubscribeButton address={subplebbitAddress} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -79,28 +84,30 @@ export const MobileBoardButtons = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DesktopBoardButtons = () => {
|
export const DesktopBoardButtons = () => {
|
||||||
const { subplebbitAddress: address } = useParams<{ subplebbitAddress: string }>();
|
|
||||||
|
|
||||||
const location = useLocation();
|
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
const location = useLocation();
|
||||||
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
const isInPostPage = isPostPageView(location.pathname, params);
|
const isInPostPage = isPostPageView(location.pathname, params);
|
||||||
const isInCatalogView = isCatalogView(location.pathname, params);
|
const isInCatalogView = isCatalogView(location.pathname, params);
|
||||||
|
const isInPendingPostPage = isPendingPostView(location.pathname, params);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.desktopBoardButtons}>
|
<div className={styles.desktopBoardButtons}>
|
||||||
<hr />
|
<hr />
|
||||||
{isInPostPage ? (
|
{isInPostPage || isInPendingPostPage ? (
|
||||||
<>
|
<>
|
||||||
[<ReturnButton address={address} />] [<CatalogButton address={address} isInCatalogView={isInCatalogView} />] [<BottomButton />] [<OptionsButton />]
|
[<ReturnButton address={subplebbitAddress} />] [<CatalogButton address={subplebbitAddress} isInCatalogView={isInCatalogView} />] [<BottomButton />] [
|
||||||
|
<OptionsButton />]
|
||||||
<span className={styles.subscribeButton}>
|
<span className={styles.subscribeButton}>
|
||||||
[<SubscribeButton address={address} />]
|
[<SubscribeButton address={subplebbitAddress} />]
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
[<OptionsButton />] [<CatalogButton address={address} isInCatalogView={isInCatalogView} />]
|
[<OptionsButton />] [<CatalogButton address={subplebbitAddress} isInCatalogView={isInCatalogView} />]
|
||||||
<span className={styles.subscribeButton}>
|
<span className={styles.subscribeButton}>
|
||||||
[<SubscribeButton address={address} />]
|
[<SubscribeButton address={subplebbitAddress} />]
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useAccountComment } from '@plebbit/plebbit-react-hooks';
|
||||||
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { isCatalogView } from '../../lib/utils/view-utils';
|
import { isCatalogView } from '../../lib/utils/view-utils';
|
||||||
@@ -76,7 +77,11 @@ const BoardNavMobile = ({ subplebbitAddresses, subplebbitAddress }: BoardNavProp
|
|||||||
|
|
||||||
const BoardNav = () => {
|
const BoardNav = () => {
|
||||||
const subplebbitAddresses = useDefaultSubplebbitAddresses();
|
const subplebbitAddresses = useDefaultSubplebbitAddresses();
|
||||||
const { subplebbitAddress } = useParams();
|
|
||||||
|
const params = useParams();
|
||||||
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BoardNavDesktop subplebbitAddresses={subplebbitAddresses} />
|
<BoardNavDesktop subplebbitAddresses={subplebbitAddresses} />
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { useComment, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
|
import { useAccountComment, useComment, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
|
||||||
import styles from './subplebbit-stats.module.css';
|
import styles from './subplebbit-stats.module.css';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { isDescriptionView, isRulesView } from '../../lib/utils/view-utils';
|
import { isDescriptionView, isRulesView } from '../../lib/utils/view-utils';
|
||||||
|
|
||||||
const SubplebbitStats = () => {
|
const SubplebbitStats = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { commentCid, subplebbitAddress } = useParams<{ subplebbitAddress: string; commentCid: string }>();
|
const params = useParams();
|
||||||
|
|
||||||
|
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
|
||||||
|
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
|
||||||
|
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = useSubplebbit({ subplebbitAddress });
|
||||||
const { address, createdAt } = subplebbit || {};
|
const { address, createdAt } = subplebbit || {};
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const params = useParams();
|
|
||||||
const isInDescriptionView = isDescriptionView(location.pathname, params);
|
const isInDescriptionView = isDescriptionView(location.pathname, params);
|
||||||
const isInRulesView = isRulesView(location.pathname, params);
|
const isInRulesView = isRulesView(location.pathname, params);
|
||||||
|
|
||||||
const comment = useComment({ commentCid });
|
const comment = useComment({ commentCid: params?.commentCid });
|
||||||
const { deleted, locked, removed } = comment || {};
|
const { deleted, locked, removed } = comment || {};
|
||||||
const hideStats = deleted || locked || removed || isInDescriptionView || isInRulesView;
|
const hideStats = deleted || locked || removed || isInDescriptionView || isInRulesView;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export type ParamsType = {
|
export type ParamsType = {
|
||||||
|
accountCommentIndex?: string;
|
||||||
commentCid?: string;
|
commentCid?: string;
|
||||||
subplebbitAddress?: string;
|
subplebbitAddress?: string;
|
||||||
};
|
};
|
||||||
@@ -29,3 +30,7 @@ export const isCatalogView = (pathname: string, params: ParamsType): boolean =>
|
|||||||
const decodedPathname = decodeURIComponent(pathname);
|
const decodedPathname = decodeURIComponent(pathname);
|
||||||
return params.subplebbitAddress ? decodedPathname.startsWith(`/p/${params.subplebbitAddress}/catalog`) : false;
|
return params.subplebbitAddress ? decodedPathname.startsWith(`/p/${params.subplebbitAddress}/catalog`) : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isPendingPostView = (pathname: string, params: ParamsType): boolean => {
|
||||||
|
return pathname === `/profile/${params.accountCommentIndex}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './pending-post';
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.stateString {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: calc(100vw - 28px);
|
||||||
|
width: 100vw;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.stateString {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { useAccountComment } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import styles from './pending-post.module.css';
|
||||||
|
import Post from '../../components/post';
|
||||||
|
import useStateString from '../../hooks/use-state-string';
|
||||||
|
import LoadingEllipsis from '../../components/loading-ellipsis';
|
||||||
|
|
||||||
|
const PendingPost = () => {
|
||||||
|
const { accountCommentIndex } = useParams<{ accountCommentIndex?: string }>();
|
||||||
|
const commentIndex = accountCommentIndex ? parseInt(accountCommentIndex) : undefined;
|
||||||
|
const post = useAccountComment({ commentIndex });
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const stateString = useStateString(post);
|
||||||
|
|
||||||
|
useEffect(() => window.scrollTo(0, 0), []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (post?.cid && post?.subplebbitAddress) {
|
||||||
|
navigate(`/p/${post?.subplebbitAddress}/c/${post?.cid}`, { replace: true });
|
||||||
|
}
|
||||||
|
}, [post, navigate]);
|
||||||
|
|
||||||
|
const loadingString = stateString && (
|
||||||
|
<div className={`${styles.stateString} ${styles.ellipsis}`}>{stateString !== 'Failed' ? <LoadingEllipsis string={stateString} /> : stateString}</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<Post post={post} />
|
||||||
|
{loadingString}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PendingPost;
|
||||||
Reference in New Issue
Block a user