mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
quote links are clickable, added on replies
This commit is contained in:
@@ -237,6 +237,17 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// scroll to post when quote is clicked
|
||||||
|
function handleQuoteClick(reply, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const cid = reply.cid.slice(0, 8);
|
||||||
|
const targetElement = [...document.querySelectorAll('.post-reply')]
|
||||||
|
.find(el => el.innerHTML.includes(cid));
|
||||||
|
if (targetElement) {
|
||||||
|
targetElement.scrollIntoView({ behavior: "instant" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleStyleChange = (event) => {
|
const handleStyleChange = (event) => {
|
||||||
switch (event.target.value) {
|
switch (event.target.value) {
|
||||||
@@ -534,15 +545,13 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
.map((reply) => (
|
.map((reply) => (
|
||||||
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
||||||
<Link key={`ql-${Math.random()}`}
|
<Link key={`ql-${Math.random()}`}
|
||||||
to="" className="quote-link" onClick={handleVoidClick}>
|
to={handleVoidClick} className="quote-link"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
c/{reply.cid.slice(0, 8)}</Link>
|
c/{reply.cid.slice(0, 8)}</Link>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
{/* <span key={`ql1-${Math.random()}`}>
|
|
||||||
<Link to="" key={`ql2-${Math.random()}`} className="quote-link" onClick={handleVoidClick}>c/{thread.cid.slice(0, 8)}</Link>
|
|
||||||
</span> */}
|
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
{thread.content ? (
|
{thread.content ? (
|
||||||
@@ -623,6 +632,20 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
<Link to="" key={`pl2-${Math.random()}`} onClick={handleVoidClick} title="Reply to this post">{reply.cid.slice(0, 8)}</Link>
|
<Link to="" key={`pl2-${Math.random()}`} onClick={handleVoidClick} title="Reply to this post">{reply.cid.slice(0, 8)}</Link>
|
||||||
</span>
|
</span>
|
||||||
<Link to="" key={`pmb-${Math.random()}`} className="post-menu-button" onClick={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</Link>
|
<Link to="" key={`pmb-${Math.random()}`} className="post-menu-button" onClick={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</Link>
|
||||||
|
<div id="backlink-id" className="backlink">
|
||||||
|
{reply.replies?.pages.topAll.comments
|
||||||
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
|
.map((reply) => (
|
||||||
|
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
||||||
|
<Link to={handleVoidClick} key={`ql-${Math.random()}`}
|
||||||
|
className="quote-link"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
|
c/{reply.cid.slice(0, 8)}</Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{reply.content ? (
|
{reply.content ? (
|
||||||
reply.content.length > 1000 ?
|
reply.content.length > 1000 ?
|
||||||
@@ -640,7 +663,7 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
: <blockquote key={`pm-${Math.random()}`} className="post-message">
|
: <blockquote key={`pm-${Math.random()}`} className="post-message">
|
||||||
<Link to="" key={`r-pm-${Math.random()}`} className="quotelink" onClick={handleVoidClick}>
|
<Link to={handleVoidClick} key={`r-pm-${Math.random()}`} className="quotelink" onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
||||||
</Link>
|
</Link>
|
||||||
{reply.content}
|
{reply.content}
|
||||||
@@ -806,7 +829,7 @@ const Board = ({ setBodyStyle }) => {
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
: <blockquote key={`mob-pm-${Math.random()}`} className="post-message">
|
: <blockquote key={`mob-pm-${Math.random()}`} className="post-message">
|
||||||
<Link to="" key={`mob-r-pm-${Math.random()}`} className="quotelink" onClick={handleVoidClick}>
|
<Link to={handleVoidClick} key={`mob-r-pm-${Math.random()}`} className="quotelink" onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
||||||
</Link>
|
</Link>
|
||||||
{reply.content}
|
{reply.content}
|
||||||
|
|||||||
+41
-30
@@ -7,6 +7,7 @@ import { useComment } from '@plebbit/plebbit-react-hooks';
|
|||||||
import ImageBanner from './ImageBanner';
|
import ImageBanner from './ImageBanner';
|
||||||
import { Tooltip } from 'react-tooltip';
|
import { Tooltip } from 'react-tooltip';
|
||||||
import getDate from '../utils/getDate';
|
import getDate from '../utils/getDate';
|
||||||
|
import renderThreadComments from '../utils/renderThreadComments';
|
||||||
|
|
||||||
|
|
||||||
const Thread = ({ setBodyStyle }) => {
|
const Thread = ({ setBodyStyle }) => {
|
||||||
@@ -22,7 +23,7 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
const { subplebbitAddress, threadCid } = useParams();
|
const { subplebbitAddress, threadCid } = useParams();
|
||||||
|
|
||||||
|
|
||||||
|
// temporary title from JSON, gets subplebbitAddress and threadCid from URL
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedAddress(subplebbitAddress);
|
setSelectedAddress(subplebbitAddress);
|
||||||
setSelectedThread(threadCid);
|
setSelectedThread(threadCid);
|
||||||
@@ -32,7 +33,7 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
}
|
}
|
||||||
}, [subplebbitAddress, setSelectedAddress, setSelectedTitle, defaultSubplebbits]);
|
}, [subplebbitAddress, setSelectedAddress, setSelectedTitle, defaultSubplebbits]);
|
||||||
|
|
||||||
|
// fetches default subplebbits from JSON
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let didCancel = false;
|
let didCancel = false;
|
||||||
fetch(
|
fetch(
|
||||||
@@ -50,7 +51,7 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// mobile navbar scroll effect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
const currentScrollPos = window.pageYOffset;
|
const currentScrollPos = window.pageYOffset;
|
||||||
@@ -80,13 +81,13 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
|
|
||||||
const handleVoidClick = () => {}
|
const handleVoidClick = () => {}
|
||||||
|
|
||||||
|
// desktop navbar board select functionality
|
||||||
const handleClickTitle = (title, address) => {
|
const handleClickTitle = (title, address) => {
|
||||||
setSelectedTitle(title);
|
setSelectedTitle(title);
|
||||||
setSelectedAddress(address);
|
setSelectedAddress(address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// mobile navbar board select functionality
|
||||||
const handleSelectChange = (event) => {
|
const handleSelectChange = (event) => {
|
||||||
const selected = event.target.value;
|
const selected = event.target.value;
|
||||||
const selectedTitle = defaultSubplebbits.find((subplebbit) => subplebbit.address === selected).title;
|
const selectedTitle = defaultSubplebbits.find((subplebbit) => subplebbit.address === selected).title;
|
||||||
@@ -117,6 +118,17 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
window.scrollTo(0, document.body.scrollHeight);
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scroll to post when quote is clicked
|
||||||
|
function handleQuoteClick(reply, event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const cid = reply.cid.slice(0, 8);
|
||||||
|
const targetElement = [...document.querySelectorAll('.post-reply')]
|
||||||
|
.find(el => el.innerHTML.includes(cid));
|
||||||
|
if (targetElement) {
|
||||||
|
targetElement.scrollIntoView({ behavior: "instant" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleStyleChange = (event) => {
|
const handleStyleChange = (event) => {
|
||||||
switch (event.target.value) {
|
switch (event.target.value) {
|
||||||
@@ -186,24 +198,6 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function renderComments(comments) {
|
|
||||||
const commentKeys = Object.keys(comments);
|
|
||||||
const renderedComments = commentKeys.map(key => {
|
|
||||||
const comment = comments[key];
|
|
||||||
const { replies: { pages: { topAll: { comments: nestedComments } } } } = comment;
|
|
||||||
if (comment.replyCount > 0 && nestedComments) {
|
|
||||||
const renderedNestedComments = renderComments(nestedComments);
|
|
||||||
return [comment, ...renderedNestedComments];
|
|
||||||
}
|
|
||||||
return [comment];
|
|
||||||
}).flat();
|
|
||||||
|
|
||||||
const sortedComments = renderedComments.sort((a, b) => a.timestamp - b.timestamp);
|
|
||||||
return sortedComments;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<NavBar selectedStyle={selectedStyle}>
|
<NavBar selectedStyle={selectedStyle}>
|
||||||
@@ -447,8 +441,9 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
.sort((a, b) => a.timestamp - b.timestamp)
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
.map((reply) => (
|
.map((reply) => (
|
||||||
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
||||||
<Link key={`ql-${Math.random()}`}
|
<Link to={handleVoidClick} key={`ql-${Math.random()}`}
|
||||||
to="" className="quote-link" onClick={handleVoidClick}>
|
className="quote-link"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
c/{reply.cid.slice(0, 8)}</Link>
|
c/{reply.cid.slice(0, 8)}</Link>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -464,12 +459,12 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
</div>
|
</div>
|
||||||
{comment.replyCount > 0 &&
|
{comment.replyCount > 0 &&
|
||||||
Object.keys(comment.replies.pages.topAll.comments).map(() => {
|
Object.keys(comment.replies.pages.topAll.comments).map(() => {
|
||||||
const renderedComments = renderComments(comment.replies.pages.topAll.comments);
|
const renderedComments = renderThreadComments(comment.replies.pages.topAll.comments);
|
||||||
return renderedComments.map(reply => {
|
return renderedComments.map(reply => {
|
||||||
return (
|
return (
|
||||||
<div key={`pc-${Math.random()}`} className="reply-container">
|
<div key={`pc-${Math.random()}`} className="reply-container">
|
||||||
<div key={`sa-${Math.random()}`} className="side-arrows">{'>>'}</div>
|
<div key={`sa-${Math.random()}`} className="side-arrows">{'>>'}</div>
|
||||||
<div key={`pr-${Math.random()}`} className="post-reply">
|
<div key={`pr-${Math.random()}`} className="post-reply" id="post-reply">
|
||||||
<div key={`pi-${Math.random()}`} className="post-info">
|
<div key={`pi-${Math.random()}`} className="post-info">
|
||||||
|
|
||||||
<span key={`nb-${Math.random()}`} className="nameblock">
|
<span key={`nb-${Math.random()}`} className="nameblock">
|
||||||
@@ -514,9 +509,24 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
<Link to="" key={`pl2-${Math.random()}`} onClick={handleVoidClick} title="Reply to this post">{reply.cid.slice(0, 8)}</Link>
|
<Link to="" key={`pl2-${Math.random()}`} onClick={handleVoidClick} title="Reply to this post">{reply.cid.slice(0, 8)}</Link>
|
||||||
</span>
|
</span>
|
||||||
<Link to="" key={`pmb-${Math.random()}`} className="post-menu-button" onClick={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</Link>
|
<Link to="" key={`pmb-${Math.random()}`} className="post-menu-button" onClick={handleVoidClick} title="Post menu" data-cmd="post-menu">▶</Link>
|
||||||
|
<div id="backlink-id" className="backlink">
|
||||||
|
{reply.replies?.pages.topAll.comments
|
||||||
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
|
.map((reply) => (
|
||||||
|
<div key={`div-${Math.random()}`} style={{display: 'inline-block'}}>
|
||||||
|
<Link to={handleVoidClick} key={`ql-${Math.random()}`}
|
||||||
|
className="quote-link"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
|
c/{reply.cid.slice(0, 8)}</Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<blockquote key={`pm-${Math.random()}`} className="post-message">
|
<blockquote key={`pm-${Math.random()}`} className="post-message">
|
||||||
<Link to="" className="quotelink" onClick={handleVoidClick}>
|
<Link to={handleVoidClick} className="quote-link"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
||||||
</Link>
|
</Link>
|
||||||
{reply.content}
|
{reply.content}
|
||||||
@@ -607,7 +617,7 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
</div>
|
</div>
|
||||||
{comment.replyCount > 0 &&
|
{comment.replyCount > 0 &&
|
||||||
Object.keys(comment.replies.pages.topAll.comments).map(() => {
|
Object.keys(comment.replies.pages.topAll.comments).map(() => {
|
||||||
const renderedComments = renderComments(comment.replies.pages.topAll.comments);
|
const renderedComments = renderThreadComments(comment.replies.pages.topAll.comments);
|
||||||
return renderedComments.map(reply => {
|
return renderedComments.map(reply => {
|
||||||
return (
|
return (
|
||||||
<div key={`mob-rc-${Math.random()}`} className="reply-container">
|
<div key={`mob-rc-${Math.random()}`} className="reply-container">
|
||||||
@@ -657,7 +667,8 @@ const Thread = ({ setBodyStyle }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<blockquote key={`mob-pm-${Math.random()}`} className="post-message-mobile">
|
<blockquote key={`mob-pm-${Math.random()}`} className="post-message-mobile">
|
||||||
<Link to="" key={`mob-ql-${Math.random()}`} className="quotelink-mobile" onClick={handleVoidClick}>
|
<Link to={handleVoidClick} key={`mob-ql-${Math.random()}`} className="quotelink-mobile"
|
||||||
|
onClick={(event) => handleQuoteClick(reply, event)}>
|
||||||
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
{`c/${reply.parentCid.slice(0, 8)}`}{<br />}
|
||||||
</Link>
|
</Link>
|
||||||
{reply.content}
|
{reply.content}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
function renderThreadComments(comments) {
|
||||||
|
const commentKeys = Object.keys(comments);
|
||||||
|
const renderedComments = commentKeys.map(key => {
|
||||||
|
const comment = comments[key];
|
||||||
|
const { replies: { pages: { topAll: { comments: nestedComments } } } } = comment;
|
||||||
|
if (comment.replyCount > 0 && nestedComments) {
|
||||||
|
const renderedNestedComments = renderThreadComments(nestedComments);
|
||||||
|
return [comment, ...renderedNestedComments];
|
||||||
|
}
|
||||||
|
return [comment];
|
||||||
|
}).flat();
|
||||||
|
|
||||||
|
const sortedComments = renderedComments.sort((a, b) => a.timestamp - b.timestamp);
|
||||||
|
return sortedComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default renderThreadComments;
|
||||||
Reference in New Issue
Block a user