update app layout, add 'thread closed' banner

This commit is contained in:
plebeius.eth
2024-04-08 17:13:02 +02:00
parent 254f9ed887
commit f13b496652
7 changed files with 83 additions and 59 deletions
+16 -30
View File
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react'; import { useEffect } from 'react';
import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom'; import { Outlet, Route, Routes, useLocation } from 'react-router-dom';
import { isHomeView } from './lib/utils/view-utils'; import { isHomeView } from './lib/utils/view-utils';
import { Subplebbit as SubplebbitType, useSubplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks'; import { useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { useDefaultSubplebbitAddresses } from './hooks/use-default-subplebbits'; 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 styles from './app.module.css';
@@ -16,32 +16,6 @@ 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';
interface BoardLayoutProps {
subplebbits: (SubplebbitType | undefined)[];
}
const BoardLayout = React.memo(({ subplebbits }: BoardLayoutProps) => {
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
const subplebbit = useSubplebbit({ subplebbitAddress });
const { address, createdAt, title } = subplebbit || {};
return (
<>
{address && (
<>
<BoardNav address={address} subplebbits={subplebbits} />
<BoardBanner title={title} address={address} />
<MobileBoardButtons address={address} />
<PostForm address={address} />
<BoardStats address={address} createdAt={createdAt} />
<DesktopBoardButtons address={address} />
</>
)}
<Outlet />
</>
);
});
const App = () => { const App = () => {
const [theme] = useTheme(); const [theme] = useTheme();
const location = useLocation(); const location = useLocation();
@@ -62,11 +36,23 @@ const App = () => {
// </> // </>
// ); // );
const boardLayout = (
<>
<BoardNav subplebbits={subplebbits} />
<BoardBanner />
<MobileBoardButtons />
<PostForm />
<BoardStats />
<DesktopBoardButtons />
<Outlet />
</>
);
return ( return (
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}> <div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
<Routes> <Routes>
<Route path='/' element={<Home subplebbits={subplebbits} />} /> <Route path='/' element={<Home subplebbits={subplebbits} />} />
<Route element={<BoardLayout subplebbits={subplebbits} />}> <Route element={boardLayout}>
<Route path='/p/:subplebbitAddress' element={<Subplebbit />} /> <Route path='/p/:subplebbitAddress' element={<Subplebbit />} />
<Route path='/p/:subplebbitAddress/c/:commentCid' element={<PostPage />} /> <Route path='/p/:subplebbitAddress/c/:commentCid' element={<PostPage />} />
</Route> </Route>
+7 -6
View File
@@ -1,3 +1,5 @@
import { useParams } from 'react-router-dom';
import { 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';
@@ -12,13 +14,12 @@ const ImageBanner = () => {
return <img src={imagePath} alt='banner' />; return <img src={imagePath} alt='banner' />;
}; };
interface BoardBannerProps { const BoardBanner = () => {
title: string | undefined; const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
address: string | undefined; const subplebbit = useSubplebbit({ subplebbitAddress });
} const { address, title } = subplebbit || {};
const BoardBanner = ({ address, title }: BoardBannerProps) => {
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;
return ( return (
<div className={styles.content}> <div className={styles.content}>
<div className={styles.bannerCnt}> <div className={styles.bannerCnt}>
@@ -5,7 +5,7 @@ import styles from './board-buttons.module.css';
import { isPostPageView } from '../../lib/utils/view-utils'; import { isPostPageView } from '../../lib/utils/view-utils';
interface BoardButtonsProps { interface BoardButtonsProps {
address: string; address: string | undefined;
} }
const OptionsButton = () => { const OptionsButton = () => {
@@ -51,7 +51,8 @@ const BottomButton = () => {
); );
}; };
export const MobileBoardButtons = ({ address }: BoardButtonsProps) => { export const MobileBoardButtons = () => {
const { subplebbitAddress: address } = useParams<{ subplebbitAddress: string }>();
const isInPostPage = isPostPageView(useLocation().pathname, useParams()); const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return ( return (
<div className={styles.mobileBoardButtons}> <div className={styles.mobileBoardButtons}>
@@ -76,7 +77,8 @@ export const MobileBoardButtons = ({ address }: BoardButtonsProps) => {
); );
}; };
export const DesktopBoardButtons = ({ address }: BoardButtonsProps) => { export const DesktopBoardButtons = () => {
const { subplebbitAddress: address } = useParams<{ subplebbitAddress: string }>();
const isInPostPage = isPostPageView(useLocation().pathname, useParams()); const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return ( return (
<div className={styles.desktopBoardButtons}> <div className={styles.desktopBoardButtons}>
@@ -1,3 +1,11 @@
.hide {
display: none;
}
.show {
display: block;
}
.content hr { .content hr {
min-width: 468px; min-width: 468px;
margin-left: -4px; margin-left: -4px;
+13 -8
View File
@@ -1,15 +1,20 @@
import { useState } from 'react'; import { useState } from 'react';
import { useSubplebbitStats } from '@plebbit/plebbit-react-hooks'; import { useParams } from 'react-router-dom';
import { useComment, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
import styles from './board-stats.module.css'; import styles from './board-stats.module.css';
import { Trans, useTranslation } from 'react-i18next'; import { Trans, useTranslation } from 'react-i18next';
export interface BoardStatsProps { const BoardStats = () => {
address: string | undefined;
createdAt: number | undefined;
}
const BoardStats = ({ address, createdAt }: BoardStatsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { commentCid, subplebbitAddress } = useParams<{ subplebbitAddress: string; commentCid: string }>();
const subplebbit = useSubplebbit({ subplebbitAddress });
const { address, createdAt } = subplebbit || {};
const comment = useComment({ commentCid });
const { deleted, locked, removed } = comment || {};
const hideStats = deleted || locked || removed;
const stats = useSubplebbitStats({ subplebbitAddress: address }); const stats = useSubplebbitStats({ subplebbitAddress: address });
const [showStats, setShowStats] = useState(true); const [showStats, setShowStats] = useState(true);
@@ -22,7 +27,7 @@ const BoardStats = ({ address, createdAt }: BoardStatsProps) => {
}; };
return ( return (
<div className={styles.content}> <div className={`${styles.content} ${hideStats ? styles.hide : styles.show}`}>
<table className={styles.blotter}> <table className={styles.blotter}>
<thead> <thead>
<tr> <tr>
@@ -10,6 +10,15 @@
padding-bottom: 0.5em; padding-bottom: 0.5em;
} }
.closed {
font-size: x-large;
text-align: center;
color: red;
font-weight: 700;
padding-top: 100px;
padding-bottom: 100px;
}
@media (max-width: 640px) { @media (max-width: 640px) {
.postFormButtonDesktop { .postFormButtonDesktop {
display: none; display: none;
+25 -12
View File
@@ -1,26 +1,39 @@
import { useState } from 'react'; import { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import styles from './post-form.module.css';
import { isPostPageView } from '../../lib/utils/view-utils';
import { useLocation, useParams } from 'react-router-dom'; import { useLocation, useParams } from 'react-router-dom';
import { useComment } from '@plebbit/plebbit-react-hooks';
import { isPostPageView } from '../../lib/utils/view-utils';
import styles from './post-form.module.css';
export interface PostFormProps { const PostForm = () => {
address: string | undefined;
}
const PostForm = ({ address }: PostFormProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { subplebbitAddress, commentCid } = useParams<{ subplebbitAddress: string; commentCid: string }>();
const comment = useComment({ commentCid });
const { deleted, locked, removed } = comment || {};
const isThreadClosed = deleted || locked || removed;
const [showForm, setShowForm] = useState(false); const [showForm, setShowForm] = useState(false);
const isInPostPage = isPostPageView(useLocation().pathname, useParams()); const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return ( return (
<> <>
<div className={styles.postFormButtonDesktop}> <div className={styles.postFormButtonDesktop}>
[ {isThreadClosed ? (
<button className='button' onClick={() => setShowForm(true)}> <div className={styles.closed}>
{isInPostPage ? t('post_a_reply') : t('start_new_thread')} Thread closed.
</button> <br />
] You may not reply at this time.
</div>
) : (
<div>
[
<button className='button' onClick={() => setShowForm(true)}>
{isInPostPage ? t('post_a_reply') : t('start_new_thread')}
</button>
]
</div>
)}
</div> </div>
<div className={styles.postFormButtonMobile}> <div className={styles.postFormButtonMobile}>
<button className='button' onClick={() => setShowForm(!showForm)}> <button className='button' onClick={() => setShowForm(!showForm)}>