diff --git a/src/components/catalog-row/catalog-row.tsx b/src/components/catalog-row/catalog-row.tsx index f655fb9d..440e65ec 100644 --- a/src/components/catalog-row/catalog-row.tsx +++ b/src/components/catalog-row/catalog-row.tsx @@ -3,7 +3,7 @@ import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; import { Link, useLocation, useParams } from 'react-router-dom'; import { useFloating, offset, size, autoUpdate, Placement } from '@floating-ui/react'; -import { Comment } from '@plebbit/plebbit-react-hooks'; +import { Comment, useReplies } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js'; import { shouldShowSnow } from '../../lib/snow'; import { getHasThumbnail } from '../../lib/utils/media-utils'; @@ -19,7 +19,6 @@ import useCountLinksInReplies from '../../hooks/use-count-links-in-replies'; import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; import useHide from '../../hooks/use-hide'; import useWindowWidth from '../../hooks/use-window-width'; -import useReplies from '../../hooks/use-replies'; import { ContentPreview } from '../../views/home/popular-threads-box'; import PostMenuDesktop from '../post-desktop/post-menu-desktop'; import styles from './catalog-row.module.css'; @@ -181,8 +180,8 @@ const CatalogPost = ({ post }: { post: Comment }) => { update(); }, [update, windowWidth]); - const replies = useReplies(post); - const lastReply = replies.length > 0 ? replies[replies.length - 1] : null; + const { replies } = useReplies({ comment: post }); + const lastReply = replies?.length > 0 ? replies[replies.length - 1] : null; const { isCommentAuthorMod: isCatalogPostAuthorMod, commentAuthorRole: catalogPostAuthorRole } = useEditCommentPrivileges({ commentAuthorAddress: author?.address, diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 7c4dbcdb..4086853f 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -1,7 +1,7 @@ import { useMemo, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Link, useLocation, useParams } from 'react-router-dom'; -import { Comment, useAuthorAvatar, useEditedComment } from '@plebbit/plebbit-react-hooks'; +import { Comment, useAuthorAvatar, useEditedComment, useReplies } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js'; import styles from '../../views/post/post.module.css'; import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils'; @@ -17,7 +17,6 @@ import { useCommentMediaInfo } from '../../hooks/use-comment-media-info'; import useCountLinksInReplies from '../../hooks/use-count-links-in-replies'; import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; import useHide from '../../hooks/use-hide'; -import useReplies from '../../hooks/use-replies'; import useStateString from '../../hooks/use-state-string'; import CommentContent from '../comment-content'; import CommentMedia from '../comment-media'; @@ -54,7 +53,7 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => { const { t } = useTranslation(); const { author, cid, deleted, locked, pinned, parentCid, postCid, reason, removed, state, subplebbitAddress, timestamp } = post || {}; const title = post?.title?.trim(); - const replies = useReplies(post); + const { replies } = useReplies({ comment: post }); const { address, shortAddress } = author || {}; const displayName = author?.displayName?.trim(); const authorRole = roles?.[address]?.role?.replace('moderator', 'mod'); @@ -88,10 +87,10 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => { ? alert(t('this_reply_was_deleted')) : alert(t('this_thread_was_deleted')) : removed - ? isReply - ? alert(t('this_reply_was_removed')) - : alert(t('this_thread_was_removed')) - : openReplyModal && openReplyModal(cid, postCid, subplebbitAddress); + ? isReply + ? alert(t('this_reply_was_removed')) + : alert(t('this_thread_was_removed')) + : openReplyModal && openReplyModal(cid, postCid, subplebbitAddress); }; return ( @@ -387,7 +386,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr const { hidden, unhide, hide } = useHide({ cid }); const isHidden = hidden && !isInPostPageView; - const replies = useReplies(post); + const { replies } = useReplies({ comment: post }); const visiblelinksCount = useCountLinksInReplies(post, 5); const totalLinksCount = useCountLinksInReplies(post); const replyCount = replies?.length; diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index 04e7896f..1c47a810 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -1,7 +1,7 @@ import { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Link, useLocation, useParams } from 'react-router-dom'; -import { Comment, useAuthorAvatar, useEditedComment } from '@plebbit/plebbit-react-hooks'; +import { Comment, useAuthorAvatar, useEditedComment, useReplies } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js'; import styles from '../../views/post/post.module.css'; import { shouldShowSnow } from '../../lib/snow'; @@ -16,7 +16,6 @@ import useAuthorAddressClick from '../../hooks/use-author-address-click'; import { useCommentMediaInfo } from '../../hooks/use-comment-media-info'; import useCountLinksInReplies from '../../hooks/use-count-links-in-replies'; import useHide from '../../hooks/use-hide'; -import useReplies from '../../hooks/use-replies'; import useStateString from '../../hooks/use-state-string'; import CommentContent from '../comment-content'; import CommentMedia from '../comment-media'; @@ -72,10 +71,10 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles }: PostProps) => { ? alert(t('this_reply_was_deleted')) : alert(t('this_thread_was_deleted')) : removed - ? isReply - ? alert(t('this_reply_was_removed')) - : alert(t('this_thread_was_removed')) - : openReplyModal && openReplyModal(cid, postCid, subplebbitAddress); + ? isReply + ? alert(t('this_reply_was_removed')) + : alert(t('this_thread_was_removed')) + : openReplyModal && openReplyModal(cid, postCid, subplebbitAddress); }; return ( @@ -228,7 +227,7 @@ const PostMediaContent = ({ post, link }: { post: any; link: string }) => { const ReplyBacklinks = ({ post }: PostProps) => { const { cid, parentCid } = post || {}; - const replies = useReplies(post); + const { replies } = useReplies({ comment: post }); return ( cid && @@ -289,7 +288,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro const defaultSubplebbits = useDefaultSubplebbits(); const boardPath = subplebbitAddress ? getBoardPath(subplebbitAddress, defaultSubplebbits) : undefined; const linksCount = useCountLinksInReplies(post); - const replies = useReplies(post); + const { replies } = useReplies({ comment: post }); const isInPostPageView = isPostPageView(location.pathname, params); const { hidden, unhide } = useHide({ cid }); diff --git a/src/hooks/use-replies.ts b/src/hooks/use-replies.ts deleted file mode 100644 index 3da6f700..00000000 --- a/src/hooks/use-replies.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { useMemo } from 'react'; -import { Comment, useAccountComments } from '@plebbit/plebbit-react-hooks'; -import { flattenCommentsPages } from '@plebbit/plebbit-react-hooks/dist/lib/utils'; - -const useReplies = (comment: Comment) => { - // flatten all replies including nested ones from the original comment - const flattenedReplies = useMemo(() => flattenCommentsPages(comment?.replies), [comment?.replies]); - - // generate a Set of CIDs from flattened replies for quick lookup - const replyCids = useMemo(() => new Set(flattenedReplies.map((reply) => reply?.cid)), [flattenedReplies]); - - const { accountComments } = useAccountComments(); - - const filteredAccountComments = useMemo(() => { - const commentMap = new Map(accountComments.map((c) => [c.cid, c])); - - return accountComments.filter((accountComment) => { - let currentCid = accountComment.parentCid; - while (currentCid && currentCid !== comment?.cid) { - if (replyCids.has(currentCid)) { - return true; - } - const parent = commentMap.get(currentCid); - if (!parent) { - return false; - } - currentCid = parent.parentCid; - } - return currentCid === comment?.cid; - }); - }, [accountComments, comment?.cid, replyCids]); - - // the account's replies have a delay before getting published, so get them locally from accountComments instead - const accountRepliesNotYetPublished = useMemo(() => { - const replies = flattenedReplies || []; - const replyCids = new Set(replies.map((reply: Comment) => reply?.cid)); - // filter out the account comments already in comment.replies, so they don't appear twice - return filteredAccountComments.filter((accountReply) => !replyCids.has(accountReply?.cid)); - }, [flattenedReplies, filteredAccountComments]); - - const repliesAndNotYetPublishedReplies = useMemo(() => { - const repliesSortedByPinnedAndTimestamp = [...accountRepliesNotYetPublished.reverse(), ...(flattenedReplies || [])]; - - return repliesSortedByPinnedAndTimestamp.sort((a: Comment, b: Comment) => { - // Sort by pinned status first, with pinned comments at the top - if (a.pinned && !b.pinned) { - return -1; - } else if (!a.pinned && b.pinned) { - return 1; - } - // If both are pinned or both are not pinned, sort by timestamp - return a.timestamp - b.timestamp; - }); - }, [flattenedReplies, accountRepliesNotYetPublished]); - - return repliesAndNotYetPublishedReplies; -}; - -export default useReplies;