mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(home): redesigned home to be more similar to 4chan, with boards box listing all boards and thread box showing recent threads
This commit is contained in:
@@ -44,7 +44,7 @@ export const Search = styled.div`
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
input[type="text"] {
|
||||
input[type='text'] {
|
||||
width: 400px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
@@ -60,27 +60,27 @@ export const Search = styled.div`
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
width: 60px;
|
||||
input[type='submit'] {
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
input[type="submit"] {
|
||||
input[type='submit'] {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
input[type="submit"] {
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
input[type='submit'] {
|
||||
vertical-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media not all and (min-resolution:.001dpcm) {
|
||||
input[type="submit"] {
|
||||
@media not all and (min-resolution: 0.001dpcm) {
|
||||
input[type='submit'] {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ export const Search = styled.div`
|
||||
@media only screen and (max-width: 480px) {
|
||||
text-align: center;
|
||||
|
||||
input[type="text"] {
|
||||
input[type='text'] {
|
||||
width: 80%;
|
||||
height: 35px;
|
||||
font-size: 20px;
|
||||
@@ -96,8 +96,8 @@ export const Search = styled.div`
|
||||
box-sizing: border-box;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
|
||||
input[type='submit'] {
|
||||
height: 35px;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
@@ -107,7 +107,6 @@ export const Search = styled.div`
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
export const Page = styled.div`
|
||||
@@ -119,15 +118,15 @@ export const About = styled.div`
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border: 1px solid;
|
||||
margin-bottom: .5em;
|
||||
padding-bottom: .5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
`;
|
||||
|
||||
export const AboutTitle = styled.div`
|
||||
background: #800;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
padding-left: .5em;
|
||||
padding-left: 0.5em;
|
||||
line-height: 2em;
|
||||
|
||||
h2 {
|
||||
@@ -141,8 +140,8 @@ export const AboutTitle = styled.div`
|
||||
export const AboutContent = styled.div`
|
||||
line-height: 1.5em;
|
||||
font-size: 93%;
|
||||
padding: .5em;
|
||||
padding-top: .25em;
|
||||
padding: 0.5em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0;
|
||||
min-height: 91px;
|
||||
|
||||
@@ -165,39 +164,92 @@ export const AboutContent = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export const Boards = styled.div`
|
||||
export const BoardsBox = styled.div`
|
||||
border: 1px solid;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: .5em;
|
||||
padding-bottom: 0.5em;
|
||||
background: #fff;
|
||||
word-wrap: break-word;
|
||||
margin-bottom: 6px;
|
||||
|
||||
#subscriptions {
|
||||
text-align: left;
|
||||
&:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
`;
|
||||
|
||||
export const BoardsTitle = styled.div`
|
||||
background: #fca;
|
||||
color: #800;
|
||||
position: relative;
|
||||
padding-left: .5em;
|
||||
line-height: 2em;
|
||||
.boxbar {
|
||||
background: #fca;
|
||||
color: #800;
|
||||
padding-left: 0.5em;
|
||||
line-height: 2em;
|
||||
|
||||
h2 {
|
||||
font-size: 131%;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
h2 {
|
||||
font-size: 131%;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.boxcontent {
|
||||
font-size: 93%;
|
||||
padding: 0.5em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0;
|
||||
line-height: 130%;
|
||||
|
||||
.column {
|
||||
float: left;
|
||||
width: 163px;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
h3 {
|
||||
font-size: 100%;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
white-space: nowrap;
|
||||
|
||||
a {
|
||||
color: #800;
|
||||
text-decoration: none;
|
||||
|
||||
:hover {
|
||||
text-decoration: underline;
|
||||
color: #e00;
|
||||
}
|
||||
}
|
||||
}
|
||||
.disconnected {
|
||||
width: 13px;
|
||||
margin: 0 2px -3px 0;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
#button {
|
||||
color: #800;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
:hover {
|
||||
color: #e00;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const BoardsContent = styled.div`
|
||||
font-size: 93%;
|
||||
padding: .5em;
|
||||
padding-top: .25em;
|
||||
padding: 0.5em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
@@ -233,7 +285,6 @@ export const BoardsContent = styled.div`
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.board-avatar-container img.board-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -265,7 +316,7 @@ export const BoardsContent = styled.div`
|
||||
|
||||
:hover {
|
||||
text-decoration: underline;
|
||||
color: #e00
|
||||
color: #e00;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +331,8 @@ export const BoardsContent = styled.div`
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.boardlink, #view-all {
|
||||
.boardlink,
|
||||
#view-all {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
@@ -302,15 +354,13 @@ export const BoardsContent = styled.div`
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
`;
|
||||
|
||||
export const Footer = styled.div`
|
||||
font-size: 93%;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
padding-top: .5em;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 2em;
|
||||
|
||||
ul {
|
||||
@@ -320,7 +370,7 @@ export const Footer = styled.div`
|
||||
width: 750px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
li {
|
||||
background: #fed;
|
||||
display: block;
|
||||
@@ -331,7 +381,7 @@ export const Footer = styled.div`
|
||||
margin-top: -1px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
.fill {
|
||||
border-top: 1x solid;
|
||||
border-right: 0;
|
||||
@@ -340,16 +390,16 @@ export const Footer = styled.div`
|
||||
background: #ffe;
|
||||
width: 10.5%;
|
||||
}
|
||||
|
||||
|
||||
.first {
|
||||
border-left: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #800;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
@media (max-device-width: 640px) {
|
||||
padding-top: 2em;
|
||||
padding-bottom: 3em;
|
||||
@@ -386,4 +436,4 @@ export const Footer = styled.div`
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
||||
+202
-93
@@ -1,13 +1,14 @@
|
||||
import React, { Fragment, useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import { useAccount, useComment, useSubplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Container, Header, Logo, Page, Search, About, AboutTitle, AboutContent, Boards, BoardsTitle, BoardsContent, Footer } from '../styled/views/Home.styled';
|
||||
import { Container, Header, Logo, Page, Search, About, AboutTitle, AboutContent, BoardsBox, BoardsContent, Footer } from '../styled/views/Home.styled';
|
||||
import BoardAvatar from '../BoardAvatar';
|
||||
import OfflineIndicator from '../OfflineIndicator';
|
||||
import CreateBoardModal from '../modals/CreateBoardModal';
|
||||
import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
||||
import packageJson from '../../../package.json';
|
||||
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
const { version } = packageJson;
|
||||
const commitRef = process?.env?.REACT_APP_COMMIT_REF ? ` ${process.env.REACT_APP_COMMIT_REF.slice(0, 7)}` : '';
|
||||
@@ -20,17 +21,64 @@ const SubplebbitTitle = ({ address }) => {
|
||||
return <>{title ? <span>{title}</span> : <span style={{ userSelect: 'none' }}> </span>}</>;
|
||||
};
|
||||
|
||||
const RecentThread = ({ commentCid }) => {
|
||||
const comment = useComment({ commentCid });
|
||||
const subplebbit = useSubplebbit({ subplebbitAddress: comment?.subplebbitAddress });
|
||||
const { setSelectedAddress, setSelectedTitle } = useGeneralStore((state) => state);
|
||||
const commentMediaInfo = getCommentMediaInfo(comment);
|
||||
|
||||
return (
|
||||
<div className='board'>
|
||||
<div className='board-title' key='board-title'>
|
||||
<SubplebbitTitle address={comment?.subplebbitAddress} />
|
||||
</div>
|
||||
<div className='board-avatar-container' key='board-avatar-container'>
|
||||
<Link
|
||||
to={`/p/${comment?.subplebbitAddress}/c/${comment?.cid}`}
|
||||
key='link'
|
||||
onClick={() => {
|
||||
setSelectedTitle(subplebbit?.title);
|
||||
setSelectedAddress(comment?.subplebbitAddress);
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
{commentMediaInfo?.type === 'webpage' && comment.thumbnailUrl ? (
|
||||
<img className='board-avatar' src={commentMediaInfo?.thumbnail} alt='post' />
|
||||
) : commentMediaInfo?.type === 'image' ? (
|
||||
<img className='board-avatar' src={commentMediaInfo?.url} alt='post' />
|
||||
) : (
|
||||
<BoardAvatar address={comment.subplebbitAddress} />
|
||||
)}
|
||||
</Link>
|
||||
<OfflineIndicator address={comment?.subplebbitAddress} className='offline-indicator' tooltipPlace='top' key='oi2' />
|
||||
</div>
|
||||
<div className='board-text' key='bt'>
|
||||
{comment?.title ? <b>{comment?.title}</b> : null}
|
||||
{comment?.content ? `: ${comment.content}` : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Home = () => {
|
||||
const { bodyStyle, setBodyStyle, defaultSubplebbits, setSelectedAddress, selectedStyle, setSelectedStyle, setSelectedTitle } = useGeneralStore((state) => state);
|
||||
const { bodyStyle, setBodyStyle, defaultSubplebbits, defaultNsfwSubplebbits, setSelectedAddress, selectedStyle, setSelectedStyle } = useGeneralStore((state) => state);
|
||||
|
||||
const sfwAddresses = defaultSubplebbits.map((subplebbit) => subplebbit.address);
|
||||
const sfwSubs = useSubplebbits({ subplebbitAddresses: sfwAddresses });
|
||||
const sfwList = sfwSubs.subplebbits.map((subplebbit) => subplebbit?.address);
|
||||
const sfwListCids = sfwSubs.subplebbits.map((s) => s?.lastPostCid);
|
||||
|
||||
const account = useAccount();
|
||||
const navigate = useNavigate();
|
||||
const isElectron = window.electron && window.electron.isElectron;
|
||||
|
||||
const inputRef = useRef(null);
|
||||
const prevStyle = useRef(selectedStyle);
|
||||
const prevBodyStyle = useRef(bodyStyle);
|
||||
|
||||
const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);
|
||||
const [showAllSFWBoards, setShowAllSFWBoards] = useState(false);
|
||||
const [showAllSubscriptions, setShowAllSubscriptions] = useState(false);
|
||||
|
||||
// prevent dark mode
|
||||
useEffect(() => {
|
||||
@@ -84,7 +132,7 @@ const Home = () => {
|
||||
/>
|
||||
<input
|
||||
type='submit'
|
||||
value='Search'
|
||||
value='Connect'
|
||||
onClick={() => {
|
||||
const address = inputRef.current.value;
|
||||
if (address) {
|
||||
@@ -101,58 +149,112 @@ const Home = () => {
|
||||
<AboutContent>
|
||||
<div id='content'>
|
||||
<p>
|
||||
Plebchan is the only serverless, adminless, fully decentralized 4chan alternative where any pleb can create and own unlimited boards, and nobody can
|
||||
take them down. Boards can always find competition, and board owners can monetize freely, so janitors aren't needed. Plebchan is a client for{' '}
|
||||
Plebchan is a serverless, adminless, decentralized 4chan alternative where any pleb can create and own unlimited boards. All data comes from the
|
||||
<a href='https://plebbit.com' target='_blank' rel='noreferrer'>
|
||||
plebbit
|
||||
</a>
|
||||
, a pure P2P protocol and tooling for creating decentralized forum applications. All data is just text, and plebchan's speed depends on how many users
|
||||
are{' '}
|
||||
<button
|
||||
style={{ all: 'unset', cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
alert(
|
||||
'You can seed automatically simply by using the plebchan desktop app, which is a plebbit full node. Download it here:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, you can use plebbit-cli with the --seed flag:\nhttps://github.com/plebbit/plebbit-cli\n\n',
|
||||
);
|
||||
}}
|
||||
>
|
||||
seeding
|
||||
</button>
|
||||
. Search for any board address above, or feel free to click on a popular board below that interests you and jump right in!{' '}
|
||||
</a>{' '}
|
||||
protocol, it's all text including links from which media is embedded, shared peer-to-peer. Users do not need to register an account before participating
|
||||
in the community. Feel free to click on a board below that interests you and jump right in!{' '}
|
||||
</p>
|
||||
<br />
|
||||
<p>There are no global rules, each board is completely independent and its owner decides how/if it should be moderated.</p>
|
||||
<br />
|
||||
<p>
|
||||
{' '}
|
||||
HOW TO RUN A BOARD (currently via CLI only): <strong>(1)</strong> have a computer you can use as server, because users will connect to your board
|
||||
peer-to-peer; <strong>(2)</strong> go to{' '}
|
||||
<a href='https://github.com/plebbit/plebbit-cli#install' target='_blank' rel='noreferrer'>
|
||||
https://github.com/plebbit/plebbit-cli#install
|
||||
</a>{' '}
|
||||
and follow the instructions to run your daemon, create a subplebbit (board) and edit its settings; <strong>(3)</strong> users can always connect to your
|
||||
board via its address, but it can be added below by submitting a pull request here:{' '}
|
||||
<a href='https://github.com/plebbit/temporary-default-subplebbits' target='_blank' rel='noreferrer'>
|
||||
https://github.com/plebbit/temporary-default-subplebbits
|
||||
</a>{' '}
|
||||
this will be automated with a plebbit DAO using the plebbit token.
|
||||
</p>
|
||||
</div>
|
||||
</AboutContent>
|
||||
</About>
|
||||
{account?.subscriptions?.length > 0 ? (
|
||||
<Boards>
|
||||
<BoardsTitle>
|
||||
<h2>Subscriptions</h2>
|
||||
</BoardsTitle>
|
||||
<BoardsContent id='subscriptions'>
|
||||
<BoardsBox>
|
||||
<div className='boxbar'>
|
||||
<h2>Boards</h2>
|
||||
</div>
|
||||
<div class='boxcontent'>
|
||||
<div class='column'>
|
||||
<h3 style={{ textDecoration: 'underline', display: 'inline' }}>
|
||||
You have subscribed to {account?.subscriptions?.length} board{account?.subscriptions?.length > 1 ? 's' : null}
|
||||
<a
|
||||
href='https://github.com/plebbit/temporary-default-subplebbits'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
style={{ all: 'unset', cursor: 'pointer' }}
|
||||
>
|
||||
Default SFW
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<Link
|
||||
to='/p/all'
|
||||
id='button'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
[view all]
|
||||
</Link>
|
||||
<ul>
|
||||
{sfwList.slice(0, showAllSFWBoards ? undefined : 18).map((address, index) => (
|
||||
<li key={`default-${index}`}>
|
||||
<OfflineIndicator address={address} className='disconnected' isText={true} />
|
||||
<Link
|
||||
key={`default-link-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
to={`/p/${address}`}
|
||||
>
|
||||
{address}
|
||||
</Link>
|
||||
|
||||
</li>
|
||||
))}
|
||||
{sfwList.length > 17 && (
|
||||
<li onClick={() => setShowAllSFWBoards(!showAllSFWBoards)}>
|
||||
{!showAllSFWBoards ? '... ' : null}
|
||||
<span id='button'>{showAllSFWBoards ? '[show less]' : '[show more]'}</span>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class='column'>
|
||||
<h3 style={{ textDecoration: 'underline', display: 'inline' }}>
|
||||
<a
|
||||
href='https://github.com/plebbit/temporary-default-subplebbits'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
style={{ all: 'unset', cursor: 'pointer' }}
|
||||
>
|
||||
Default NSFW
|
||||
</a>
|
||||
</h3>
|
||||
<ul>
|
||||
{defaultNsfwSubplebbits.length === 0 && <li style={{ color: 'black' }}>No boards yet in this list.</li>}
|
||||
{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}`}
|
||||
>
|
||||
{subplebbit.address}
|
||||
</Link>
|
||||
|
||||
</li>
|
||||
))}
|
||||
{defaultNsfwSubplebbits.length > 17 && (
|
||||
<li onClick={() => setShowAllSFWBoards(!showAllSFWBoards)}>
|
||||
{!showAllSFWBoards ? '... ' : null}
|
||||
<span id='button'>{showAllSFWBoards ? '[show less]' : '[show more]'}</span>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class='column'>
|
||||
<h3 style={{ textDecoration: 'underline', display: 'inline' }}>Subscriptions</h3>
|
||||
|
||||
<Link
|
||||
to='/p/subscriptions'
|
||||
id='view-all'
|
||||
id='button'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
@@ -160,58 +262,65 @@ const Home = () => {
|
||||
[view all]
|
||||
</Link>
|
||||
<br />
|
||||
{account?.subscriptions?.map((subscription, index) => (
|
||||
<Fragment key={`frag-${index}`}>
|
||||
<Link
|
||||
key={`sub-${index}`}
|
||||
className='boardlink'
|
||||
onClick={() => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
to={`/p/${subscription}`}
|
||||
>
|
||||
<br id='mobile-br' />
|
||||
{subscription}
|
||||
</Link>
|
||||
<OfflineIndicator key={`offline-${index}`} address={subscription} className='disconnected' isText={true} />
|
||||
<br key={`br-${index}`} />
|
||||
</Fragment>
|
||||
))}
|
||||
<br id='mobile-br' />
|
||||
</BoardsContent>
|
||||
</Boards>
|
||||
) : null}
|
||||
<Boards>
|
||||
<BoardsTitle>
|
||||
<h2>Default Boards</h2>
|
||||
</BoardsTitle>
|
||||
<ul>
|
||||
{account?.subscriptions?.length === 0 && <li style={{ color: 'black' }}>Not subscribed to any board.</li>}
|
||||
{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}`}
|
||||
>
|
||||
{subscription}
|
||||
</Link>
|
||||
|
||||
</li>
|
||||
))}
|
||||
{account?.subscriptions?.length > 17 && (
|
||||
<li onClick={() => setShowAllSubscriptions(!showAllSubscriptions)}>
|
||||
{!showAllSubscriptions ? '... ' : null}
|
||||
<span id='button'>{showAllSubscriptions ? '[show less]' : '[show more]'}</span>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class='column'>
|
||||
<h3 style={{ textDecoration: 'underline', display: 'inline' }}>Moderating</h3>
|
||||
<ul>
|
||||
{!isElectron ? (
|
||||
<li style={{ color: 'black' }}>
|
||||
Visible on{' '}
|
||||
<a
|
||||
style={{ color: 'blue', textDecoration: 'underline' }}
|
||||
href='https://github.com/plebbit/plebchan/releases/latest'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
>
|
||||
full node (desktop)
|
||||
</a>
|
||||
.
|
||||
</li>
|
||||
) : (
|
||||
<div>WIP</div>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</BoardsBox>
|
||||
<BoardsBox>
|
||||
<div className='boxbar'>
|
||||
<h2>Recent Threads</h2>
|
||||
</div>
|
||||
<BoardsContent>
|
||||
{defaultSubplebbits.map((subplebbit, index) => (
|
||||
<div className='board' key={`board-${index}`}>
|
||||
<div className='board-title' key='board-title'>
|
||||
{subplebbit.title ?? <SubplebbitTitle address={subplebbit.address} />}
|
||||
</div>
|
||||
<div className='board-avatar-container' key='board-avatar-container'>
|
||||
<Link
|
||||
to={`/p/${subplebbit.address}`}
|
||||
key='link'
|
||||
onClick={() => {
|
||||
setSelectedTitle(subplebbit.title);
|
||||
setSelectedAddress(subplebbit.address);
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<BoardAvatar key='baordavatar' address={subplebbit.address} />
|
||||
</Link>
|
||||
<OfflineIndicator address={subplebbit.address} className='offline-indicator' tooltipPlace='top' key='oi2' />
|
||||
</div>
|
||||
<div className='board-text' key='bt'>
|
||||
<b key='b'>{subplebbit.address}</b>
|
||||
</div>
|
||||
</div>
|
||||
{sfwListCids.slice(0, 8).map((cid) => (
|
||||
<RecentThread commentCid={cid} />
|
||||
))}
|
||||
</BoardsContent>
|
||||
</Boards>
|
||||
</BoardsBox>
|
||||
</Page>
|
||||
<Footer>
|
||||
<ul>
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { Link } from "react-router-dom";
|
||||
import { Container, Header, Logo, Page, Boards, BoardsTitle } from '../styled/views/Home.styled';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Container, Header, Logo, Page, BoardsBox } from '../styled/views/Home.styled';
|
||||
import packageJson from '../../../package.json';
|
||||
const {version} = packageJson;
|
||||
const { version } = packageJson;
|
||||
const commitRef = process?.env?.REACT_APP_COMMIT_REF ? ` ${process.env.REACT_APP_COMMIT_REF.slice(0, 7)}` : '';
|
||||
|
||||
|
||||
const NotFound = () => {
|
||||
useEffect(() => {
|
||||
const yotsubaBodyStyle = {
|
||||
background: "#ffe url(assets/fade.png) top repeat-x",
|
||||
color: "maroon",
|
||||
fontFamily: "Arial, Helvetica, sans-serif"
|
||||
background: '#ffe url(assets/fade.png) top repeat-x',
|
||||
color: 'maroon',
|
||||
fontFamily: 'Arial, Helvetica, sans-serif',
|
||||
};
|
||||
const originalBodyStyles = {
|
||||
background: document.body.style.background,
|
||||
color: document.body.style.color,
|
||||
fontFamily: document.body.style.fontFamily
|
||||
fontFamily: document.body.style.fontFamily,
|
||||
};
|
||||
|
||||
for (const [key, value] of Object.entries(yotsubaBodyStyle)) {
|
||||
@@ -39,34 +38,41 @@ const NotFound = () => {
|
||||
<Container>
|
||||
<Header>
|
||||
<Logo>
|
||||
<Link to="/">
|
||||
<img alt="plebchan" src="assets/logo/logo-transparent.png" />
|
||||
<Link to='/'>
|
||||
<img alt='plebchan' src='assets/logo/logo-transparent.png' />
|
||||
</Link>
|
||||
</Logo>
|
||||
</Header>
|
||||
<Page>
|
||||
<Boards>
|
||||
<BoardsTitle>
|
||||
<h2 style={{textAlign: 'center'}}>404 Not Found</h2>
|
||||
</BoardsTitle>
|
||||
<img src="assets/plebchan-husbando.jpg" alt="plebchan" style={{
|
||||
display: "block",
|
||||
margin: "auto",
|
||||
padding: "15px",
|
||||
width: "50%"
|
||||
}}></img>
|
||||
</Boards>
|
||||
<BoardsBox>
|
||||
<div className='boxbar'>
|
||||
<h2 style={{ textAlign: 'center' }}>404 Not Found</h2>
|
||||
</div>
|
||||
<img
|
||||
src='assets/plebchan-husbando.jpg'
|
||||
alt='plebchan'
|
||||
style={{
|
||||
display: 'block',
|
||||
margin: 'auto',
|
||||
padding: '15px',
|
||||
width: '50%',
|
||||
}}
|
||||
></img>
|
||||
</BoardsBox>
|
||||
</Page>
|
||||
<div style={{
|
||||
textAlign: "center",
|
||||
fontSize: "11px",
|
||||
marginTop: "2em",
|
||||
}}>
|
||||
plebchan v{version}{commitRef}. GPL-2.0
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
fontSize: '11px',
|
||||
marginTop: '2em',
|
||||
}}
|
||||
>
|
||||
plebchan v{version}
|
||||
{commitRef}. GPL-2.0
|
||||
</div>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default NotFound;
|
||||
export default NotFound;
|
||||
|
||||
Reference in New Issue
Block a user