implement useReplies

This commit is contained in:
plebeius
2025-12-27 17:47:17 +01:00
parent 391e49a62e
commit 6e9202a604
4 changed files with 17 additions and 79 deletions
+3 -4
View File
@@ -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,
+3 -4
View File
@@ -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');
@@ -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;
+3 -4
View File
@@ -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';
@@ -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 });
-59
View File
@@ -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;