quote links are clickable, added on replies

This commit is contained in:
plebbitor
2023-03-08 09:49:42 +01:00
parent 8f160eed57
commit 47390fce99
3 changed files with 87 additions and 36 deletions
+29 -6
View File
@@ -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>
&nbsp; &nbsp;
</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>
&nbsp;
</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
View File
@@ -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>
&nbsp; &nbsp;
</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">
&nbsp; &nbsp;
<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>
&nbsp;
</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}
+17
View File
@@ -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;