implement useSubplebbitsPagesStore instead of prop from useReplies

This commit is contained in:
Tom (plebeius.eth)
2025-03-05 21:38:01 +01:00
parent 42e21c8ee9
commit 876af71e65
5 changed files with 35 additions and 51 deletions
@@ -2,6 +2,7 @@ import { Fragment, useState } from 'react';
import { useLocation, useParams } from 'react-router-dom'; import { useLocation, useParams } from 'react-router-dom';
import { Trans, useTranslation } from 'react-i18next'; import { Trans, useTranslation } from 'react-i18next';
import { Comment } from '@plebbit/plebbit-react-hooks'; import { Comment } from '@plebbit/plebbit-react-hooks';
import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages';
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isPostPageView } from '../../lib/utils/view-utils'; import { isPostPageView } from '../../lib/utils/view-utils';
import useIsMobile from '../../hooks/use-is-mobile'; import useIsMobile from '../../hooks/use-is-mobile';
@@ -13,7 +14,7 @@ import Tooltip from '../../components/tooltip';
import styles from '../../views/post/post.module.css'; import styles from '../../views/post/post.module.css';
import _ from 'lodash'; import _ from 'lodash';
const CommentContent = ({ comment: post, replies }: { comment: Comment; replies: Comment[] }) => { const CommentContent = ({ comment: post }: { comment: Comment }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const params = useParams(); const params = useParams();
const location = useLocation(); const location = useLocation();
@@ -34,7 +35,7 @@ const CommentContent = ({ comment: post, replies }: { comment: Comment; replies:
? content.slice(0, 2000) ? content.slice(0, 2000)
: content); : content);
const quotelinkReply = parentCid && replies?.find((reply) => reply.cid === parentCid); const quotelinkReply = useSubplebbitsPagesStore((state) => state.comments[parentCid]);
const isReply = !!parentCid; const isReply = !!parentCid;
const isReplyingToReply = isReply && parentCid !== postCid; const isReplyingToReply = isReply && parentCid !== postCid;
@@ -45,9 +46,7 @@ const CommentContent = ({ comment: post, replies }: { comment: Comment; replies:
return ( return (
<blockquote className={`${styles.postMessage} ${!isReply && isMobile && styles.clampLines} ${isRules && styles.rulesMessage}`}> <blockquote className={`${styles.postMessage} ${!isReply && isMobile && styles.clampLines} ${isRules && styles.rulesMessage}`}>
{isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && ( {isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && <ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} />}
<ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} replies={replies} />
)}
{removed ? ( {removed ? (
reason ? ( reason ? (
<> <>
+10 -11
View File
@@ -48,7 +48,7 @@ const useShowOmittedReplies = create<ShowOmittedRepliesState>((set) => ({
})), })),
})); }));
const PostInfo = ({ post, postReplyCount = 0, roles, isHidden, replies: threadReplies }: PostProps) => { const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, cid, deleted, locked, pinned, parentCid, postCid, reason, removed, shortCid, state, subplebbitAddress, timestamp } = post || {}; const { author, cid, deleted, locked, pinned, parentCid, postCid, reason, removed, shortCid, state, subplebbitAddress, timestamp } = post || {};
const title = post?.title?.trim(); const title = post?.title?.trim();
@@ -219,7 +219,7 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden, replies: threadRe
(reply: Comment, index: number) => (reply: Comment, index: number) =>
reply?.parentCid === cid && reply?.parentCid === cid &&
reply?.cid && reply?.cid &&
!(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} replies={threadReplies} />, !(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} />,
)} )}
</span> </span>
</div> </div>
@@ -306,7 +306,7 @@ const PostMedia = ({ commentMediaInfo, hasThumbnail, isDescription, isRules, spo
); );
}; };
const Reply = ({ postReplyCount, reply, roles, replies }: PostProps) => { const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
let post = reply; let post = reply;
// handle pending mod or author edit // handle pending mod or author edit
const { editedComment } = useEditedComment({ comment: reply }); const { editedComment } = useEditedComment({ comment: reply });
@@ -327,7 +327,7 @@ const Reply = ({ postReplyCount, reply, roles, replies }: PostProps) => {
<div className={styles.replyDesktop}> <div className={styles.replyDesktop}>
<div className={styles.sideArrows}>{'>>'}</div> <div className={styles.sideArrows}>{'>>'}</div>
<div className={`${styles.reply} ${isRouteLinkToReply && styles.highlight}`} data-cid={cid} data-author-address={author?.shortAddress} data-post-cid={postCid}> <div className={`${styles.reply} ${isRouteLinkToReply && styles.highlight}`} data-cid={cid} data-author-address={author?.shortAddress} data-post-cid={postCid}>
<PostInfo post={post} postReplyCount={postReplyCount} roles={roles} isHidden={hidden} replies={replies} /> <PostInfo post={post} postReplyCount={postReplyCount} roles={roles} isHidden={hidden} />
{link && !hidden && !(deleted || removed) && isValidURL(link) && ( {link && !hidden && !(deleted || removed) && isValidURL(link) && (
<PostMedia <PostMedia
commentMediaInfo={commentMediaInfo} commentMediaInfo={commentMediaInfo}
@@ -342,13 +342,13 @@ const Reply = ({ postReplyCount, reply, roles, replies }: PostProps) => {
parentCid={parentCid} parentCid={parentCid}
/> />
)} )}
{!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} replies={replies || []} />} {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} />}
</div> </div>
</div> </div>
); );
}; };
const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies: threadReplies }: PostProps) => { const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, cid, content, deleted, link, linkHeight, linkWidth, pinned, postCid, removed, spoiler, state, subplebbitAddress, thumbnailUrl, parentCid } = post || {}; const { author, cid, content, deleted, link, linkHeight, linkWidth, pinned, postCid, removed, spoiler, state, subplebbitAddress, thumbnailUrl, parentCid } = post || {};
const { isDescription, isRules } = post || {}; // custom properties, not from api const { isDescription, isRules } = post || {}; // custom properties, not from api
@@ -360,8 +360,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies:
const { hidden, unhide, hide } = useHide({ cid }); const { hidden, unhide, hide } = useHide({ cid });
const isHidden = hidden && !isInPostPageView; const isHidden = hidden && !isInPostPageView;
const commentReplies = useReplies(post); const replies = useReplies(post);
const replies = threadReplies || commentReplies;
const visiblelinksCount = useCountLinksInReplies(post, 5); const visiblelinksCount = useCountLinksInReplies(post, 5);
const totalLinksCount = useCountLinksInReplies(post); const totalLinksCount = useCountLinksInReplies(post);
const replyCount = replies?.length; const replyCount = replies?.length;
@@ -417,9 +416,9 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies:
parentCid={parentCid} parentCid={parentCid}
/> />
)} )}
<PostInfo isHidden={hidden} post={post} postReplyCount={replyCount} roles={roles} replies={replies} /> <PostInfo isHidden={hidden} post={post} postReplyCount={replyCount} roles={roles} />
{!isHidden && !content && !(deleted || removed) && <div className={styles.spacer} />} {!isHidden && !content && !(deleted || removed) && <div className={styles.spacer} />}
{!isHidden && <CommentContent comment={post} replies={replies} />} {!isHidden && <CommentContent comment={post} />}
</div> </div>
{!isHidden && !isDescription && !isRules && !isInPendingPostView && (replyCount > 5 || (pinned && repliesCount > 0)) && !isInPostPageView && ( {!isHidden && !isDescription && !isRules && !isInPendingPostView && (replyCount > 5 || (pinned && repliesCount > 0)) && !isInPostPageView && (
<span className={styles.summary}> <span className={styles.summary}>
@@ -453,7 +452,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies:
showReplies && showReplies &&
(showAllReplies || showOmittedReplies[cid] ? replies : replies.slice(-5)).map((reply, index) => ( (showAllReplies || showOmittedReplies[cid] ? replies : replies.slice(-5)).map((reply, index) => (
<div key={index} className={styles.replyContainer}> <div key={index} className={styles.replyContainer}>
<Reply reply={reply} roles={roles} postReplyCount={replyCount} replies={replies} /> <Reply reply={reply} roles={roles} postReplyCount={replyCount} />
</div> </div>
))} ))}
{isDescription && subplebbit?.rules && subplebbit?.rules.length > 0 && ( {isDescription && subplebbit?.rules && subplebbit?.rules.length > 0 && (
+8 -9
View File
@@ -233,7 +233,7 @@ const PostMediaContent = ({ post, link }: { post: any; link: string }) => {
); );
}; };
const ReplyBacklinks = ({ post, replies: threadReplies }: PostProps) => { const ReplyBacklinks = ({ post }: PostProps) => {
const { cid, parentCid } = post || {}; const { cid, parentCid } = post || {};
const replies = useReplies(post); const replies = useReplies(post);
@@ -246,14 +246,14 @@ const ReplyBacklinks = ({ post, replies: threadReplies }: PostProps) => {
(reply: Comment, index: number) => (reply: Comment, index: number) =>
reply?.parentCid === cid && reply?.parentCid === cid &&
reply?.cid && reply?.cid &&
!(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} replies={threadReplies} />, !(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} />,
)} )}
</div> </div>
) )
); );
}; };
const Reply = ({ postReplyCount, reply, replies, roles }: PostProps) => { const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
let post = reply; let post = reply;
// handle pending mod or author edit // handle pending mod or author edit
const { editedComment } = useEditedComment({ comment: reply }); const { editedComment } = useEditedComment({ comment: reply });
@@ -274,7 +274,7 @@ const Reply = ({ postReplyCount, reply, replies, roles }: PostProps) => {
data-post-cid={postCid} data-post-cid={postCid}
> >
<PostInfoAndMedia post={post} postReplyCount={postReplyCount} roles={roles} /> <PostInfoAndMedia post={post} postReplyCount={postReplyCount} roles={roles} />
{!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} replies={replies || []} />} {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} />}
<ReplyBacklinks post={reply} /> <ReplyBacklinks post={reply} />
</div> </div>
</div> </div>
@@ -282,7 +282,7 @@ const Reply = ({ postReplyCount, reply, replies, roles }: PostProps) => {
); );
}; };
const PostMobile = ({ post, roles, showAllReplies, showReplies = true, replies: threadReplies }: PostProps) => { const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, cid, pinned, postCid, replyCount, state, subplebbitAddress } = post || {}; const { author, cid, pinned, postCid, replyCount, state, subplebbitAddress } = post || {};
const { isDescription, isRules } = post || {}; // custom properties, not from api const { isDescription, isRules } = post || {}; // custom properties, not from api
@@ -292,8 +292,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true, replies:
const isInPendingPostView = isPendingPostView(location.pathname, params); const isInPendingPostView = isPendingPostView(location.pathname, params);
const isInPostView = isPostPageView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params);
const linksCount = useCountLinksInReplies(post); const linksCount = useCountLinksInReplies(post);
const commentReplies = useReplies(post); const replies = useReplies(post);
const replies = threadReplies || commentReplies;
const isInPostPageView = isPostPageView(location.pathname, params); const isInPostPageView = isPostPageView(location.pathname, params);
const { hidden, unhide } = useHide({ cid }); const { hidden, unhide } = useHide({ cid });
@@ -339,7 +338,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true, replies:
> >
{shouldShowSnow() && <img src={`${process.env.PUBLIC_URL}/assets/xmashat.gif`} className={styles.xmasHat} alt='' />} {shouldShowSnow() && <img src={`${process.env.PUBLIC_URL}/assets/xmashat.gif`} className={styles.xmasHat} alt='' />}
<PostInfoAndMedia post={post} postReplyCount={replyCount} roles={roles} /> <PostInfoAndMedia post={post} postReplyCount={replyCount} roles={roles} />
<CommentContent comment={post} replies={replies} /> <CommentContent comment={post} />
</div> </div>
{!isInPostView && !isInPendingPostView && showReplies && ( {!isInPostView && !isInPendingPostView && showReplies && (
<div className={styles.postLink}> <div className={styles.postLink}>
@@ -362,7 +361,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true, replies:
showReplies && showReplies &&
(showAllReplies ? replies : replies.slice(-5)).map((reply, index) => ( (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => (
<div key={index} className={styles.replyContainer}> <div key={index} className={styles.replyContainer}>
<Reply postReplyCount={replyCount} reply={reply} roles={roles} replies={replies} /> <Reply postReplyCount={replyCount} reply={reply} roles={roles} />
</div> </div>
))} ))}
{showRules && ( {showRules && (
@@ -13,7 +13,6 @@ interface ReplyQuotePreviewProps {
backlinkReply?: Comment; backlinkReply?: Comment;
isQuotelinkReply?: boolean; isQuotelinkReply?: boolean;
quotelinkReply?: Comment; quotelinkReply?: Comment;
replies?: Comment[];
} }
const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => { const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
@@ -54,7 +53,7 @@ const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
} }
}; };
const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => { const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const [hoveredCid, setHoveredCid] = useState<string | null>(null); const [hoveredCid, setHoveredCid] = useState<string | null>(null);
const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null); const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null);
const placementRef = useRef<Placement>('right'); const placementRef = useRef<Placement>('right');
@@ -145,7 +144,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
outOfViewCid === backlinkReply?.cid && outOfViewCid === backlinkReply?.cid &&
createPortal( createPortal(
<div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}> <div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}>
<Post post={backlinkReply} showReplies={false} replies={replies} /> <Post post={backlinkReply} showReplies={false} />
</div>, </div>,
document.body, document.body,
)} )}
@@ -174,7 +173,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
outOfViewCid === quotelinkReply?.cid && outOfViewCid === quotelinkReply?.cid &&
createPortal( createPortal(
<div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}> <div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}>
<Post post={quotelinkReply} showReplies={false} replies={replies} /> <Post post={quotelinkReply} showReplies={false} />
</div>, </div>,
document.body, document.body,
)} )}
@@ -184,7 +183,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink; return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
}; };
const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => { const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const [hoveredCid, setHoveredCid] = useState<string | null>(null); const [hoveredCid, setHoveredCid] = useState<string | null>(null);
const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null); const [outOfViewCid, setOutOfViewCid] = useState<string | null>(null);
@@ -257,7 +256,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
outOfViewCid === backlinkReply?.cid && outOfViewCid === backlinkReply?.cid &&
createPortal( createPortal(
<div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}> <div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}>
<Post post={backlinkReply} showReplies={false} replies={replies} /> <Post post={backlinkReply} showReplies={false} />
</div>, </div>,
document.body, document.body,
)} )}
@@ -293,7 +292,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
outOfViewCid === quotelinkReply?.cid && outOfViewCid === quotelinkReply?.cid &&
createPortal( createPortal(
<div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}> <div className={styles.replyQuotePreview} ref={refs.setFloating} style={floatingStyles}>
<Post post={quotelinkReply} showReplies={false} replies={replies} /> <Post post={quotelinkReply} showReplies={false} />
</div>, </div>,
document.body, document.body,
)} )}
@@ -303,25 +302,13 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink; return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
}; };
const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => { const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return isMobile ? ( return isMobile ? (
<MobileQuotePreview <MobileQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
backlinkReply={backlinkReply}
quotelinkReply={quotelinkReply}
isBacklinkReply={isBacklinkReply}
isQuotelinkReply={isQuotelinkReply}
replies={replies}
/>
) : ( ) : (
<DesktopQuotePreview <DesktopQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
backlinkReply={backlinkReply}
quotelinkReply={quotelinkReply}
isBacklinkReply={isBacklinkReply}
isQuotelinkReply={isQuotelinkReply}
replies={replies}
/>
); );
}; };
+4 -4
View File
@@ -10,6 +10,7 @@ import PostMobile from '../../components/post-mobile';
import SubplebbitDescription from '../../components/subplebbit-description'; import SubplebbitDescription from '../../components/subplebbit-description';
import SubplebbitRules from '../../components/subplebbit-rules'; import SubplebbitRules from '../../components/subplebbit-rules';
import styles from './post.module.css'; import styles from './post.module.css';
export interface PostProps { export interface PostProps {
index?: number; index?: number;
isHidden?: boolean; isHidden?: boolean;
@@ -20,10 +21,9 @@ export interface PostProps {
roles?: Role[]; roles?: Role[];
showAllReplies?: boolean; showAllReplies?: boolean;
showReplies?: boolean; showReplies?: boolean;
replies?: Comment[];
} }
export const Post = ({ post, showAllReplies = false, showReplies = true, replies }: PostProps) => { export const Post = ({ post, showAllReplies = false, showReplies = true }: PostProps) => {
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[post?.subplebbitAddress]); const subplebbit = useSubplebbitsStore((state) => state.subplebbits[post?.subplebbitAddress]);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@@ -39,9 +39,9 @@ export const Post = ({ post, showAllReplies = false, showReplies = true, replies
<div className={styles.thread}> <div className={styles.thread}>
<div className={styles.postContainer}> <div className={styles.postContainer}>
{isMobile ? ( {isMobile ? (
<PostMobile post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} replies={replies} /> <PostMobile post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} />
) : ( ) : (
<PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} replies={replies} /> <PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} />
)} )}
</div> </div>
</div> </div>