mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
perf(app): optimize loading times by using stored values of subplebbits and comments instead of fetching them multiple times
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { Fragment, useState } from 'react';
|
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 { 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';
|
||||||
@@ -9,11 +10,10 @@ import LoadingEllipsis from '../../components/loading-ellipsis';
|
|||||||
import ReplyQuotePreview from '../../components/reply-quote-preview';
|
import ReplyQuotePreview from '../../components/reply-quote-preview';
|
||||||
import Markdown from '../../components/markdown';
|
import Markdown from '../../components/markdown';
|
||||||
import Tooltip from '../../components/tooltip';
|
import Tooltip from '../../components/tooltip';
|
||||||
import { Comment, useComment } from '@plebbit/plebbit-react-hooks';
|
|
||||||
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 }: { comment: Comment }) => {
|
const CommentContent = ({ comment: post, replies }: { comment: Comment; replies: Comment[] }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -34,9 +34,10 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => {
|
|||||||
? content.slice(0, 2000)
|
? content.slice(0, 2000)
|
||||||
: content);
|
: content);
|
||||||
|
|
||||||
const quotelinkReply = useComment({ commentCid: parentCid });
|
const quotelinkReply = parentCid && replies?.find((reply) => reply.cid === parentCid);
|
||||||
const isReply = parentCid;
|
|
||||||
const isReplyingToReply = (postCid && postCid !== parentCid) || quotelinkReply?.postCid !== parentCid;
|
const isReply = !!parentCid;
|
||||||
|
const isReplyingToReply = isReply && parentCid !== postCid;
|
||||||
|
|
||||||
const stateString = useStateString(post);
|
const stateString = useStateString(post);
|
||||||
|
|
||||||
@@ -44,7 +45,9 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => {
|
|||||||
|
|
||||||
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) && <ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} />}
|
{isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && (
|
||||||
|
<ReplyQuotePreview isQuotelinkReply={true} quotelinkReply={quotelinkReply} replies={replies} />
|
||||||
|
)}
|
||||||
{removed ? (
|
{removed ? (
|
||||||
reason ? (
|
reason ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import { Comment, useAuthorAvatar, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Comment, useAuthorAvatar, useEditedComment } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||||
import styles from '../../views/post/post.module.css';
|
import styles from '../../views/post/post.module.css';
|
||||||
import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils';
|
import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils';
|
||||||
@@ -47,7 +48,7 @@ const useShowOmittedReplies = create<ShowOmittedRepliesState>((set) => ({
|
|||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => {
|
const PostInfo = ({ post, postReplyCount = 0, roles, isHidden, replies: threadReplies }: 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();
|
||||||
@@ -218,7 +219,7 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: 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} />,
|
!(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} replies={threadReplies} />,
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -305,7 +306,7 @@ const PostMedia = ({ commentMediaInfo, hasThumbnail, isDescription, isRules, spo
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
|
const Reply = ({ postReplyCount, reply, roles, replies }: 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 });
|
||||||
@@ -326,7 +327,7 @@ const Reply = ({ postReplyCount, reply, roles }: 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} />
|
<PostInfo post={post} postReplyCount={postReplyCount} roles={roles} isHidden={hidden} replies={replies} />
|
||||||
{link && !hidden && !(deleted || removed) && isValidURL(link) && (
|
{link && !hidden && !(deleted || removed) && isValidURL(link) && (
|
||||||
<PostMedia
|
<PostMedia
|
||||||
commentMediaInfo={commentMediaInfo}
|
commentMediaInfo={commentMediaInfo}
|
||||||
@@ -341,13 +342,13 @@ const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
|
|||||||
parentCid={parentCid}
|
parentCid={parentCid}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} />}
|
{!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} replies={replies || []} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostProps) => {
|
const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies: threadReplies }: 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
|
||||||
@@ -359,7 +360,8 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr
|
|||||||
const { hidden, unhide, hide } = useHide({ cid });
|
const { hidden, unhide, hide } = useHide({ cid });
|
||||||
const isHidden = hidden && !isInPostPageView;
|
const isHidden = hidden && !isInPostPageView;
|
||||||
|
|
||||||
const replies = useReplies(post);
|
const commentReplies = 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;
|
||||||
@@ -370,7 +372,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr
|
|||||||
|
|
||||||
const stateString = useStateString(post) || t('loading_board');
|
const stateString = useStateString(post) || t('loading_board');
|
||||||
|
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]);
|
||||||
|
|
||||||
const subplebbitRulesReply = {
|
const subplebbitRulesReply = {
|
||||||
isRules: true,
|
isRules: true,
|
||||||
@@ -415,9 +417,9 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr
|
|||||||
parentCid={parentCid}
|
parentCid={parentCid}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<PostInfo isHidden={hidden} post={post} postReplyCount={replyCount} roles={roles} />
|
<PostInfo isHidden={hidden} post={post} postReplyCount={replyCount} roles={roles} replies={replies} />
|
||||||
{!isHidden && !content && !(deleted || removed) && <div className={styles.spacer} />}
|
{!isHidden && !content && !(deleted || removed) && <div className={styles.spacer} />}
|
||||||
{!isHidden && <CommentContent comment={post} />}
|
{!isHidden && <CommentContent comment={post} replies={replies} />}
|
||||||
</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}>
|
||||||
@@ -446,7 +448,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr
|
|||||||
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} />
|
<Reply reply={reply} roles={roles} postReplyCount={replyCount} replies={replies} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{isDescription && subplebbit?.rules && subplebbit?.rules.length > 0 && (
|
{isDescription && subplebbit?.rules && subplebbit?.rules.length > 0 && (
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import { Comment, useAuthorAvatar, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Comment, useAuthorAvatar, useEditedComment } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||||
import styles from '../../views/post/post.module.css';
|
import styles from '../../views/post/post.module.css';
|
||||||
import { shouldShowSnow } from '../../lib/snow';
|
import { shouldShowSnow } from '../../lib/snow';
|
||||||
@@ -232,7 +233,7 @@ const PostMediaContent = ({ post, link }: { post: any; link: string }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ReplyBacklinks = ({ post }: PostProps) => {
|
const ReplyBacklinks = ({ post, replies: threadReplies }: PostProps) => {
|
||||||
const { cid, parentCid } = post || {};
|
const { cid, parentCid } = post || {};
|
||||||
const replies = useReplies(post);
|
const replies = useReplies(post);
|
||||||
|
|
||||||
@@ -245,14 +246,14 @@ const ReplyBacklinks = ({ post }: 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} />,
|
!(reply?.deleted || reply?.removed) && <ReplyQuotePreview key={index} isBacklinkReply={true} backlinkReply={reply} replies={threadReplies} />,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
|
const Reply = ({ postReplyCount, reply, replies, 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 });
|
||||||
@@ -273,7 +274,7 @@ const Reply = ({ postReplyCount, reply, 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} />}
|
{!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && <CommentContent comment={post} replies={replies || []} />}
|
||||||
<ReplyBacklinks post={reply} />
|
<ReplyBacklinks post={reply} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -281,7 +282,7 @@ const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostProps) => {
|
const PostMobile = ({ post, roles, showAllReplies, showReplies = true, replies: threadReplies }: 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
|
||||||
@@ -291,14 +292,15 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro
|
|||||||
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 replies = useReplies(post);
|
const commentReplies = 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 });
|
||||||
|
|
||||||
const stateString = useStateString(post) || t('loading_post');
|
const stateString = useStateString(post) || t('loading_post');
|
||||||
|
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]);
|
||||||
const showRules = isDescription && subplebbit?.rules && subplebbit?.rules.length > 0;
|
const showRules = isDescription && subplebbit?.rules && subplebbit?.rules.length > 0;
|
||||||
const subplebbitRulesReply = {
|
const subplebbitRulesReply = {
|
||||||
isRules: true,
|
isRules: true,
|
||||||
@@ -337,7 +339,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro
|
|||||||
>
|
>
|
||||||
{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} />
|
<CommentContent comment={post} replies={replies} />
|
||||||
</div>
|
</div>
|
||||||
{!isInPostView && !isInPendingPostView && showReplies && (
|
{!isInPostView && !isInPendingPostView && showReplies && (
|
||||||
<div className={styles.postLink}>
|
<div className={styles.postLink}>
|
||||||
@@ -360,7 +362,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro
|
|||||||
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} />
|
<Reply postReplyCount={replyCount} reply={reply} roles={roles} replies={replies} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{showRules && (
|
{showRules && (
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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) => {
|
||||||
@@ -53,7 +54,7 @@ const handleQuoteHover = (cid: string, onElementOutOfView: () => void) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
|
const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: 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');
|
||||||
@@ -144,7 +145,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} />
|
<Post post={backlinkReply} showReplies={false} replies={replies} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
)}
|
)}
|
||||||
@@ -173,7 +174,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} />
|
<Post post={quotelinkReply} showReplies={false} replies={replies} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
)}
|
)}
|
||||||
@@ -183,7 +184,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
|
|||||||
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
|
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
|
const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: 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);
|
||||||
|
|
||||||
@@ -256,7 +257,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} />
|
<Post post={backlinkReply} showReplies={false} replies={replies} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
)}
|
)}
|
||||||
@@ -292,7 +293,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} />
|
<Post post={quotelinkReply} showReplies={false} replies={replies} />
|
||||||
</div>,
|
</div>,
|
||||||
document.body,
|
document.body,
|
||||||
)}
|
)}
|
||||||
@@ -302,13 +303,25 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
|
|||||||
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
|
return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => {
|
const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
return isMobile ? (
|
return isMobile ? (
|
||||||
<MobileQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
|
<MobileQuotePreview
|
||||||
|
backlinkReply={backlinkReply}
|
||||||
|
quotelinkReply={quotelinkReply}
|
||||||
|
isBacklinkReply={isBacklinkReply}
|
||||||
|
isQuotelinkReply={isQuotelinkReply}
|
||||||
|
replies={replies}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<DesktopQuotePreview backlinkReply={backlinkReply} quotelinkReply={quotelinkReply} isBacklinkReply={isBacklinkReply} isQuotelinkReply={isQuotelinkReply} />
|
<DesktopQuotePreview
|
||||||
|
backlinkReply={backlinkReply}
|
||||||
|
quotelinkReply={quotelinkReply}
|
||||||
|
isBacklinkReply={isBacklinkReply}
|
||||||
|
isQuotelinkReply={isQuotelinkReply}
|
||||||
|
replies={replies}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { useAccount } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import useAnonModeStore from '../stores/use-anon-mode-store';
|
import useAnonModeStore from '../stores/use-anon-mode-store';
|
||||||
import useAnonMode from './use-anon-mode';
|
import useAnonMode from './use-anon-mode';
|
||||||
|
|
||||||
@@ -12,7 +13,8 @@ interface AuthorPrivilegesProps {
|
|||||||
const useAuthorPrivileges = ({ commentAuthorAddress, subplebbitAddress, postCid }: AuthorPrivilegesProps) => {
|
const useAuthorPrivileges = ({ commentAuthorAddress, subplebbitAddress, postCid }: AuthorPrivilegesProps) => {
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const accountAuthorAddress = account?.author?.address;
|
const accountAuthorAddress = account?.author?.address;
|
||||||
const { roles } = useSubplebbit({ subplebbitAddress }) || {};
|
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]);
|
||||||
|
const { roles } = subplebbit || {};
|
||||||
const { getAddressSigner, getThreadSigner } = useAnonModeStore();
|
const { getAddressSigner, getThreadSigner } = useAnonModeStore();
|
||||||
const { anonMode } = useAnonMode(postCid);
|
const { anonMode } = useAnonMode(postCid);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { useState, useEffect } from 'react';
|
|||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||||
import { Subplebbit, useSubplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
|
import { Subplebbit, useSubplebbitStats } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import { useDefaultSubplebbitsState, useDefaultSubplebbitTags } from '../../../hooks/use-default-subplebbits';
|
import { useDefaultSubplebbitsState, useDefaultSubplebbitTags } from '../../../hooks/use-default-subplebbits';
|
||||||
import useIsMobile from '../../../hooks/use-is-mobile';
|
import useIsMobile from '../../../hooks/use-is-mobile';
|
||||||
import useIsSubplebbitOffline from '../../../hooks/use-is-subplebbit-offline';
|
import useIsSubplebbitOffline from '../../../hooks/use-is-subplebbit-offline';
|
||||||
@@ -18,7 +19,7 @@ const Board = ({ subplebbit, isMobile }: { subplebbit: Subplebbit; isMobile: boo
|
|||||||
|
|
||||||
let stats = useSubplebbitStats({ subplebbitAddress: address });
|
let stats = useSubplebbitStats({ subplebbitAddress: address });
|
||||||
|
|
||||||
const subplebbitData = useSubplebbit({ subplebbitAddress: address });
|
const subplebbitData = useSubplebbitsStore((state) => state.subplebbits[address]);
|
||||||
const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbitData);
|
const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbitData);
|
||||||
|
|
||||||
const displayAddress = address && Plebbit.getShortAddress(address);
|
const displayAddress = address && Plebbit.getShortAddress(address);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import { HomeLogo } from '../home';
|
import { HomeLogo } from '../home';
|
||||||
import styles from './not-found.module.css';
|
import styles from './not-found.module.css';
|
||||||
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
|
||||||
|
|
||||||
const totalNotFoundImages = 2;
|
const totalNotFoundImages = 2;
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ const NotFoundImage = () => {
|
|||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const subplebbitAddress = location.pathname.startsWith('/p/') ? location.pathname.split('/')[2] : '';
|
const subplebbitAddress = location.pathname.startsWith('/p/') ? location.pathname.split('/')[2] : '';
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress });
|
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]);
|
||||||
const { address, shortAddress } = subplebbit || {};
|
const { address, shortAddress } = subplebbit || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Comment, Role, useComment, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Comment, Role, useComment, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { isAllView, isDescriptionView, isRulesView } from '../../lib/utils/view-utils';
|
import { isAllView, isDescriptionView, isRulesView } from '../../lib/utils/view-utils';
|
||||||
import useIsMobile from '../../hooks/use-is-mobile';
|
import useIsMobile from '../../hooks/use-is-mobile';
|
||||||
@@ -9,7 +10,6 @@ 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 +20,11 @@ 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 }: PostProps) => {
|
export const Post = ({ post, showAllReplies = false, showReplies = true, replies }: PostProps) => {
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress: post?.subplebbitAddress });
|
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[post?.subplebbitAddress]);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
let comment = post;
|
let comment = post;
|
||||||
@@ -38,9 +39,9 @@ export const Post = ({ post, showAllReplies = false, showReplies = true }: PostP
|
|||||||
<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} />
|
<PostMobile post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} replies={replies} />
|
||||||
) : (
|
) : (
|
||||||
<PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} />
|
<PostDesktop post={comment} roles={subplebbit?.roles} showAllReplies={showAllReplies} showReplies={showReplies} replies={replies} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user