diff --git a/src/components/comment-content/comment-content.tsx b/src/components/comment-content/comment-content.tsx index efa07d8c..3450f05b 100644 --- a/src/components/comment-content/comment-content.tsx +++ b/src/components/comment-content/comment-content.tsx @@ -1,6 +1,7 @@ import { Fragment, useState } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import { Trans, useTranslation } from 'react-i18next'; +import { Comment } from '@plebbit/plebbit-react-hooks'; import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { isPostPageView } from '../../lib/utils/view-utils'; 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 Markdown from '../../components/markdown'; import Tooltip from '../../components/tooltip'; -import { Comment, useComment } from '@plebbit/plebbit-react-hooks'; import styles from '../../views/post/post.module.css'; import _ from 'lodash'; -const CommentContent = ({ comment: post }: { comment: Comment }) => { +const CommentContent = ({ comment: post, replies }: { comment: Comment; replies: Comment[] }) => { const { t } = useTranslation(); const params = useParams(); const location = useLocation(); @@ -34,9 +34,10 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => { ? content.slice(0, 2000) : content); - const quotelinkReply = useComment({ commentCid: parentCid }); - const isReply = parentCid; - const isReplyingToReply = (postCid && postCid !== parentCid) || quotelinkReply?.postCid !== parentCid; + const quotelinkReply = parentCid && replies?.find((reply) => reply.cid === parentCid); + + const isReply = !!parentCid; + const isReplyingToReply = isReply && parentCid !== postCid; const stateString = useStateString(post); @@ -44,7 +45,9 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => { return (
- {isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && } + {isReply && state !== 'failed' && isReplyingToReply && !(deleted || removed) && ( + + )} {removed ? ( reason ? ( <> diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 4aa2fb36..1cc2718a 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -1,7 +1,8 @@ import { useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; 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 styles from '../../views/post/post.module.css'; import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils'; @@ -47,7 +48,7 @@ const useShowOmittedReplies = create((set) => ({ })), })); -const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => { +const PostInfo = ({ post, postReplyCount = 0, roles, isHidden, replies: threadReplies }: PostProps) => { const { t } = useTranslation(); const { author, cid, deleted, locked, pinned, parentCid, postCid, reason, removed, shortCid, state, subplebbitAddress, timestamp } = post || {}; const title = post?.title?.trim(); @@ -218,7 +219,7 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => { (reply: Comment, index: number) => reply?.parentCid === cid && reply?.cid && - !(reply?.deleted || reply?.removed) && , + !(reply?.deleted || reply?.removed) && , )} @@ -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; // handle pending mod or author edit const { editedComment } = useEditedComment({ comment: reply }); @@ -326,7 +327,7 @@ const Reply = ({ postReplyCount, reply, roles }: PostProps) => {
{'>>'}
- + {link && !hidden && !(deleted || removed) && isValidURL(link) && ( { parentCid={parentCid} /> )} - {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && } + {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && }
); }; -const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostProps) => { +const PostDesktop = ({ post, roles, showAllReplies, showReplies = true, replies: threadReplies }: PostProps) => { const { t } = useTranslation(); 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 @@ -359,7 +360,8 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr const { hidden, unhide, hide } = useHide({ cid }); const isHidden = hidden && !isInPostPageView; - const replies = useReplies(post); + const commentReplies = useReplies(post); + const replies = threadReplies || commentReplies; const visiblelinksCount = useCountLinksInReplies(post, 5); const totalLinksCount = useCountLinksInReplies(post); const replyCount = replies?.length; @@ -370,7 +372,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr const stateString = useStateString(post) || t('loading_board'); - const subplebbit = useSubplebbit({ subplebbitAddress }); + const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]); const subplebbitRulesReply = { isRules: true, @@ -415,9 +417,9 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr parentCid={parentCid} /> )} - + {!isHidden && !content && !(deleted || removed) &&
} - {!isHidden && } + {!isHidden && }
{!isHidden && !isDescription && !isRules && !isInPendingPostView && (replyCount > 5 || (pinned && repliesCount > 0)) && !isInPostPageView && ( @@ -446,7 +448,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr showReplies && (showAllReplies || showOmittedReplies[cid] ? replies : replies.slice(-5)).map((reply, index) => (
- +
))} {isDescription && subplebbit?.rules && subplebbit?.rules.length > 0 && ( diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index 3b2c10ce..6541a6d0 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -1,7 +1,8 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; 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 styles from '../../views/post/post.module.css'; 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 replies = useReplies(post); @@ -245,14 +246,14 @@ const ReplyBacklinks = ({ post }: PostProps) => { (reply: Comment, index: number) => reply?.parentCid === cid && reply?.cid && - !(reply?.deleted || reply?.removed) && , + !(reply?.deleted || reply?.removed) && , )} ) ); }; -const Reply = ({ postReplyCount, reply, roles }: PostProps) => { +const Reply = ({ postReplyCount, reply, replies, roles }: PostProps) => { let post = reply; // handle pending mod or author edit const { editedComment } = useEditedComment({ comment: reply }); @@ -273,7 +274,7 @@ const Reply = ({ postReplyCount, reply, roles }: PostProps) => { data-post-cid={postCid} > - {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && } + {!hidden && (!(removed || deleted) || ((removed || deleted) && reason)) && } @@ -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 { author, cid, pinned, postCid, replyCount, state, subplebbitAddress } = post || {}; 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 isInPostView = isPostPageView(location.pathname, params); const linksCount = useCountLinksInReplies(post); - const replies = useReplies(post); + const commentReplies = useReplies(post); + const replies = threadReplies || commentReplies; const isInPostPageView = isPostPageView(location.pathname, params); const { hidden, unhide } = useHide({ cid }); 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 subplebbitRulesReply = { isRules: true, @@ -337,7 +339,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro > {shouldShowSnow() && } - + {!isInPostView && !isInPendingPostView && showReplies && (
@@ -360,7 +362,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro showReplies && (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => (
- +
))} {showRules && ( diff --git a/src/components/reply-quote-preview/reply-quote-preview.tsx b/src/components/reply-quote-preview/reply-quote-preview.tsx index c0fa61d1..0d68b05f 100644 --- a/src/components/reply-quote-preview/reply-quote-preview.tsx +++ b/src/components/reply-quote-preview/reply-quote-preview.tsx @@ -13,6 +13,7 @@ interface ReplyQuotePreviewProps { backlinkReply?: Comment; isQuotelinkReply?: boolean; quotelinkReply?: Comment; + replies?: Comment[]; } 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(null); const [outOfViewCid, setOutOfViewCid] = useState(null); const placementRef = useRef('right'); @@ -144,7 +145,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i outOfViewCid === backlinkReply?.cid && createPortal(
- +
, document.body, )} @@ -173,7 +174,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i outOfViewCid === quotelinkReply?.cid && createPortal(
- +
, document.body, )} @@ -183,7 +184,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink; }; -const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => { +const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => { const [hoveredCid, setHoveredCid] = useState(null); const [outOfViewCid, setOutOfViewCid] = useState(null); @@ -256,7 +257,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is outOfViewCid === backlinkReply?.cid && createPortal(
- +
, document.body, )} @@ -292,7 +293,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is outOfViewCid === quotelinkReply?.cid && createPortal(
- +
, document.body, )} @@ -302,13 +303,25 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is return isBacklinkReply ? replyBacklink : isQuotelinkReply && replyQuotelink; }; -const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply }: ReplyQuotePreviewProps) => { +const ReplyQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, isQuotelinkReply, replies }: ReplyQuotePreviewProps) => { const isMobile = useIsMobile(); return isMobile ? ( - + ) : ( - + ); }; diff --git a/src/hooks/use-author-privileges.ts b/src/hooks/use-author-privileges.ts index 2db69b80..571ef48c 100644 --- a/src/hooks/use-author-privileges.ts +++ b/src/hooks/use-author-privileges.ts @@ -1,5 +1,6 @@ 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 useAnonMode from './use-anon-mode'; @@ -12,7 +13,8 @@ interface AuthorPrivilegesProps { const useAuthorPrivileges = ({ commentAuthorAddress, subplebbitAddress, postCid }: AuthorPrivilegesProps) => { const account = useAccount(); const accountAuthorAddress = account?.author?.address; - const { roles } = useSubplebbit({ subplebbitAddress }) || {}; + const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]); + const { roles } = subplebbit || {}; const { getAddressSigner, getThreadSigner } = useAnonModeStore(); const { anonMode } = useAnonMode(postCid); diff --git a/src/views/home/boards-list/boards-list.tsx b/src/views/home/boards-list/boards-list.tsx index b07d6f99..0abd11b0 100644 --- a/src/views/home/boards-list/boards-list.tsx +++ b/src/views/home/boards-list/boards-list.tsx @@ -2,7 +2,8 @@ import { useState, useEffect } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; 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 useIsMobile from '../../../hooks/use-is-mobile'; 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 }); - const subplebbitData = useSubplebbit({ subplebbitAddress: address }); + const subplebbitData = useSubplebbitsStore((state) => state.subplebbits[address]); const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbitData); const displayAddress = address && Plebbit.getShortAddress(address); diff --git a/src/views/not-found/not-found.tsx b/src/views/not-found/not-found.tsx index d5c7bf28..5005a9e9 100644 --- a/src/views/not-found/not-found.tsx +++ b/src/views/not-found/not-found.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; +import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits'; import { HomeLogo } from '../home'; import styles from './not-found.module.css'; -import { useSubplebbit } from '@plebbit/plebbit-react-hooks'; const totalNotFoundImages = 2; @@ -18,7 +18,7 @@ const NotFoundImage = () => { const NotFound = () => { const location = useLocation(); 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 || {}; return ( diff --git a/src/views/post/post.tsx b/src/views/post/post.tsx index da16d3a3..3a12fd1d 100644 --- a/src/views/post/post.tsx +++ b/src/views/post/post.tsx @@ -1,6 +1,7 @@ import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; 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 { isAllView, isDescriptionView, isRulesView } from '../../lib/utils/view-utils'; import useIsMobile from '../../hooks/use-is-mobile'; @@ -9,7 +10,6 @@ import PostMobile from '../../components/post-mobile'; import SubplebbitDescription from '../../components/subplebbit-description'; import SubplebbitRules from '../../components/subplebbit-rules'; import styles from './post.module.css'; - export interface PostProps { index?: number; isHidden?: boolean; @@ -20,10 +20,11 @@ export interface PostProps { roles?: Role[]; showAllReplies?: boolean; showReplies?: boolean; + replies?: Comment[]; } -export const Post = ({ post, showAllReplies = false, showReplies = true }: PostProps) => { - const subplebbit = useSubplebbit({ subplebbitAddress: post?.subplebbitAddress }); +export const Post = ({ post, showAllReplies = false, showReplies = true, replies }: PostProps) => { + const subplebbit = useSubplebbitsStore((state) => state.subplebbits[post?.subplebbitAddress]); const isMobile = useIsMobile(); let comment = post; @@ -38,9 +39,9 @@ export const Post = ({ post, showAllReplies = false, showReplies = true }: PostP
{isMobile ? ( - + ) : ( - + )}