mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
added state, hook and context for thread view
This commit is contained in:
+3
-2
@@ -28,6 +28,7 @@ export default function App() {
|
|||||||
|
|
||||||
const [selectedTitle, setSelectedTitle] = useState('');
|
const [selectedTitle, setSelectedTitle] = useState('');
|
||||||
const [selectedAddress, setSelectedAddress] = useState('');
|
const [selectedAddress, setSelectedAddress] = useState('');
|
||||||
|
const [selectedThread, setSelectedThread] = useState('');
|
||||||
const [selectedStyle, setSelectedStyle] = useState('Yotsuba');
|
const [selectedStyle, setSelectedStyle] = useState('Yotsuba');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -45,13 +46,13 @@ export default function App() {
|
|||||||
color={bodyStyle.color}
|
color={bodyStyle.color}
|
||||||
fontFamily={bodyStyle.fontFamily}
|
fontFamily={bodyStyle.fontFamily}
|
||||||
/>
|
/>
|
||||||
<BoardContext.Provider value={{ selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedStyle, setSelectedStyle }}>
|
<BoardContext.Provider value={{ selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedThread, setSelectedThread, selectedStyle, setSelectedStyle }}>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route exact path='/' element={<Home setBodyStyle={setBodyStyle} />} />
|
<Route exact path='/' element={<Home setBodyStyle={setBodyStyle} />} />
|
||||||
<Route path={`/${selectedAddress}`} element={<Board setBodyStyle={setBodyStyle} />}>
|
<Route path={`/${selectedAddress}`} element={<Board setBodyStyle={setBodyStyle} />}>
|
||||||
<Route path='post' element={<Board />} />
|
<Route path='post' element={<Board />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={`/${selectedAddress}/thread`} element={<Thread setBodyStyle={setBodyStyle} />}>
|
<Route path={`/${selectedAddress}/thread/${selectedThread}`} element={<Thread setBodyStyle={setBodyStyle} />}>
|
||||||
<Route path='post' element={<Thread />} />
|
<Route path='post' element={<Thread />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={`/${selectedAddress}/catalog`} element={<Catalog setBodyStyle={setBodyStyle} /> }>
|
<Route path={`/${selectedAddress}/catalog`} element={<Catalog setBodyStyle={setBodyStyle} /> }>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import InfiniteScroll from 'react-infinite-scroller';
|
|||||||
|
|
||||||
const Board = ({ setBodyStyle }) => {
|
const Board = ({ setBodyStyle }) => {
|
||||||
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
||||||
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedThread, setSelectedThread, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
||||||
const [showPostFormLink, setShowPostFormLink] = useState(true);
|
const [showPostFormLink, setShowPostFormLink] = useState(true);
|
||||||
const [showPostForm, setShowPostForm] = useState(false);
|
const [showPostForm, setShowPostForm] = useState(false);
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
@@ -124,6 +124,10 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
setShowPostForm(true);
|
setShowPostForm(true);
|
||||||
navigate(`/${selectedAddress}/post`);
|
navigate(`/${selectedAddress}/post`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClickThread = (thread) => {
|
||||||
|
setSelectedThread(thread);
|
||||||
|
}
|
||||||
|
|
||||||
const handlePublishComment = async () => {
|
const handlePublishComment = async () => {
|
||||||
// Event.preventDefault();
|
// Event.preventDefault();
|
||||||
@@ -330,10 +334,9 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
loader={<div>Loading...</div>}
|
loader={<div>Loading...</div>}
|
||||||
>
|
>
|
||||||
{feed.map(object => {
|
{feed.map(thread => {
|
||||||
let counter = 1;
|
let counter = 1;
|
||||||
const thread = object;
|
const { replies: { pages: { topAll: { comments } } } } = thread;
|
||||||
const { replies: { pages: { topAll: { comments } } } } = object;
|
|
||||||
const renderedComments = renderComments(comments);
|
const renderedComments = renderComments(comments);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -358,7 +361,7 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
|
|
||||||
<span key={`rl1-${thread.cid}`}>
|
<span key={`rl1-${thread.cid}`}>
|
||||||
[
|
[
|
||||||
<Link key={`rl2-${thread.cid}`} to={`/${selectedAddress}/thread`} className="reply-link" >Reply</Link>
|
<Link key={`rl2-${thread.cid}`} to={`/${selectedAddress}/thread/${thread.cid}`} onClick={() => handleClickThread(thread.cid)} className="reply-link" >Reply</Link>
|
||||||
]
|
]
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import InfiniteScroll from 'react-infinite-scroller';
|
|||||||
|
|
||||||
const Catalog = ({ setBodyStyle }) => {
|
const Catalog = ({ setBodyStyle }) => {
|
||||||
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
||||||
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedThread, setSelectedThread, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
||||||
const [showPostFormLink, setShowPostFormLink] = useState(true);
|
const [showPostFormLink, setShowPostFormLink] = useState(true);
|
||||||
const [showPostForm, setShowPostForm] = useState(false);
|
const [showPostForm, setShowPostForm] = useState(false);
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
@@ -124,6 +124,10 @@ const Catalog = ({ setBodyStyle }) => {
|
|||||||
navigate(`/${selectedAddress}/catalog/post`);
|
navigate(`/${selectedAddress}/catalog/post`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClickThread = (thread) => {
|
||||||
|
setSelectedThread(thread);
|
||||||
|
}
|
||||||
|
|
||||||
const handlePublishComment = async () => {
|
const handlePublishComment = async () => {
|
||||||
// Event.preventDefault();
|
// Event.preventDefault();
|
||||||
try {
|
try {
|
||||||
@@ -320,9 +324,9 @@ const Catalog = ({ setBodyStyle }) => {
|
|||||||
{feed.map(thread => {
|
{feed.map(thread => {
|
||||||
return (
|
return (
|
||||||
<div key={`${thread.cid}`} className="thread">
|
<div key={`${thread.cid}`} className="thread">
|
||||||
<a key={`a-${thread.cid}`} href={handleVoidClick}>
|
<Link key={`a-${thread.cid}`} to={`/${selectedAddress}/thread/${thread.cid}`} onClick={() => handleClickThread(thread.cid)}>
|
||||||
<img key={`img-${thread.cid}`} alt="" src="/assets/plebchan-psycho.png" />
|
<img key={`img-${thread.cid}`} alt="" src="/assets/plebchan-psycho.png" />
|
||||||
</a>
|
</Link>
|
||||||
<div key={`ti-${thread.cid}`} className="thread-icons" >
|
<div key={`ti-${thread.cid}`} className="thread-icons" >
|
||||||
<span key={`si-${thread.cid}`} className="thread-icon sticky-icon" title="Sticky"></span>
|
<span key={`si-${thread.cid}`} className="thread-icon sticky-icon" title="Sticky"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -332,7 +336,7 @@ const Catalog = ({ setBodyStyle }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div key={`t-${thread.cid}`} className="teaser">
|
<div key={`t-${thread.cid}`} className="teaser">
|
||||||
<b>{thread.title ? `${thread.title}` : null}</b>
|
<b>{thread.title ? `${thread.title}` : null}</b>
|
||||||
{thread.content ? `${thread.content}` : null}
|
{thread.content ? `: ${thread.content}` : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)})}
|
)})}
|
||||||
|
|||||||
+123
-4
@@ -1,17 +1,19 @@
|
|||||||
import React, { useState, useEffect, useContext } from 'react';
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { Container, NavBar, Header, Break, PostForm } from './styles/Board.styled';
|
import { Container, NavBar, Header, Break, PostForm, BoardForm } from './styles/Board.styled';
|
||||||
import { ReplyFormTable, ReplyFormLink, TopBar } from './styles/Thread.styled';
|
import { ReplyFormTable, ReplyFormLink, TopBar } from './styles/Thread.styled';
|
||||||
import { BoardContext } from '../App';
|
import { BoardContext } from '../App';
|
||||||
|
import { useComment, useAccountsActions } from '@plebbit/plebbit-react-hooks';
|
||||||
import ImageBanner from './ImageBanner';
|
import ImageBanner from './ImageBanner';
|
||||||
|
|
||||||
const Thread = ({ setBodyStyle }) => {
|
const Thread = ({ setBodyStyle }) => {
|
||||||
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
const [defaultSubplebbits, setDefaultSubplebbits] = useState([]);
|
||||||
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, selectedThread, setSelectedThread, selectedStyle, setSelectedStyle } = useContext(BoardContext);
|
||||||
const [showReplyFormLink, setShowReplyFormLink] = useState(true);
|
const [showReplyFormLink, setShowReplyFormLink] = useState(true);
|
||||||
const [showReplyForm, setShowReplyForm] = useState(false);
|
const [showReplyForm, setShowReplyForm] = useState(false);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const comment = useComment(`${selectedThread}`);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let didCancel = false;
|
let didCancel = false;
|
||||||
@@ -44,7 +46,7 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
const handleClickForm = () => {
|
const handleClickForm = () => {
|
||||||
setShowReplyFormLink(false);
|
setShowReplyFormLink(false);
|
||||||
setShowReplyForm(true);
|
setShowReplyForm(true);
|
||||||
navigate(`/${selectedAddress}/thread/post`);
|
navigate(`/${selectedAddress}/thread/${selectedThread}/post`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStyleChange = (event) => {
|
const handleStyleChange = (event) => {
|
||||||
@@ -113,6 +115,19 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderComments(comments) {
|
||||||
|
return comments.map(comment => {
|
||||||
|
const { replyCount, replies: { pages: { topAll: { comments: nestedComments } } } } = comment;
|
||||||
|
|
||||||
|
if (replyCount > 0 && nestedComments.length > 0) {
|
||||||
|
const renderedNestedComments = renderComments(nestedComments);
|
||||||
|
return [comment, ...renderedNestedComments];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [comment];
|
||||||
|
}).flat();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<NavBar selectedStyle={selectedStyle}>
|
<NavBar selectedStyle={selectedStyle}>
|
||||||
@@ -210,6 +225,110 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
</span>
|
</span>
|
||||||
<hr />
|
<hr />
|
||||||
</TopBar>
|
</TopBar>
|
||||||
|
<BoardForm selectedStyle={selectedStyle}>
|
||||||
|
{comment ? (
|
||||||
|
<>
|
||||||
|
<div className="thread">
|
||||||
|
<div className="post-container op-container">
|
||||||
|
<div className="post op">
|
||||||
|
<div className="post-info">
|
||||||
|
|
||||||
|
<span className="name-block">
|
||||||
|
<span className="name">{comment.author.displayName || "Anonymous"}</span>
|
||||||
|
|
||||||
|
<span className="poster-address">
|
||||||
|
(User: {comment.author.address})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span className="date-time" data-utc="data">2 weeks ago</span>
|
||||||
|
|
||||||
|
<span className="post-number">
|
||||||
|
<a href={handleVoidClick} title="Link to this post">No.</a>
|
||||||
|
<a href={handleVoidClick} title="Reply to this post">00000001</a>
|
||||||
|
</span>
|
||||||
|
<a key={`pmb-${comment.cid}`} className="post-menu-button" href={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</a>
|
||||||
|
<div id="backlink-id" className="backlink">
|
||||||
|
<span>
|
||||||
|
<a className="quote-link" href={handleVoidClick}>{'>>'}00000002</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<blockquote>
|
||||||
|
{comment.title ?
|
||||||
|
<>
|
||||||
|
<span key={`q-${comment.cid}`} className="title">{comment.title}</span>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</>
|
||||||
|
: null}
|
||||||
|
{comment.content ? (
|
||||||
|
<>
|
||||||
|
{comment.content}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{comment.replyCount > 0 ? (
|
||||||
|
<div>there are {comment.replyCount} replies</div>
|
||||||
|
) : (
|
||||||
|
<div>No replies yet</div>
|
||||||
|
)}
|
||||||
|
{/* {comment ? (
|
||||||
|
comment.map(thread => {
|
||||||
|
let counter = 1;
|
||||||
|
const { replies: { pages: { topAll: { comments } } } } = thread;
|
||||||
|
const renderedComments = renderComments(comments);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{renderedComments.map(reply => {
|
||||||
|
counter++;
|
||||||
|
const counterString = counter.toString().padStart(8, '0');
|
||||||
|
return (
|
||||||
|
<div key={`pc-${reply.cid}`} className="post-container reply-container">
|
||||||
|
<div key={`sa-${reply.cid}`} className="side-arrows">{'>>'}</div>
|
||||||
|
<div key={`pr-${reply.cid}`} className="post-reply">
|
||||||
|
<div key={`pi-${reply.cid}`} className="post-info">
|
||||||
|
|
||||||
|
<span key={`nb-${reply.cid}`} className="nameblock">
|
||||||
|
<span key={`n-${reply.cid}`} className="name">{reply.author.displayName || "Anonymous"}</span>
|
||||||
|
|
||||||
|
<span key={`pa-${reply.cid}`} className="poster-address">
|
||||||
|
(User: {reply.author.address})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span key={`dt-${reply.cid}`} className="date-time" data-utc="data">2 weeks ago</span>
|
||||||
|
|
||||||
|
<span key={`pn-${reply.cid}`} className="post-number">
|
||||||
|
<a key={`pl1-${reply.cid}`} href={handleVoidClick} title="Link to this post">No.</a>
|
||||||
|
<a key={`pl2-${reply.cid}`} href={handleVoidClick} title="Reply to this post">{counterString}</a>
|
||||||
|
</span>
|
||||||
|
<a key={`pmb-${reply.cid}`} className="post-menu-button" href={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</a>
|
||||||
|
</div>
|
||||||
|
<blockquote key={`pm-${reply.cid}`} className="post-message">
|
||||||
|
<a className="quotelink" href={handleVoidClick}>
|
||||||
|
{`>>${counterString}`}{<br />}
|
||||||
|
</a>
|
||||||
|
{reply.content}
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<div>Loading...</div>
|
||||||
|
)} */}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div>Loading...</div>
|
||||||
|
)}
|
||||||
|
</BoardForm>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user