2024-09-03 12:06:21 +02:00
|
|
|
import { useMemo } from 'react';
|
2024-03-22 16:15:38 +01:00
|
|
|
import { Comment, useAccountComments } from '@plebbit/plebbit-react-hooks';
|
2024-04-02 16:42:36 +02:00
|
|
|
import { flattenCommentsPages } from '@plebbit/plebbit-react-hooks/dist/lib/utils';
|
2024-03-22 16:15:38 +01:00
|
|
|
|
2024-06-06 20:55:05 +02:00
|
|
|
const useReplies = (comment: Comment) => {
|
2024-04-29 21:49:00 +02:00
|
|
|
// flatten all replies including nested ones from the original comment
|
2024-06-15 12:37:45 +02:00
|
|
|
const flattenedReplies = useMemo(() => flattenCommentsPages(comment?.replies), [comment?.replies]);
|
2024-03-22 16:15:38 +01:00
|
|
|
|
2024-04-29 22:37:08 +02:00
|
|
|
// generate a Set of CIDs from flattened replies for quick lookup
|
2024-06-15 12:37:45 +02:00
|
|
|
const replyCids = useMemo(() => new Set(flattenedReplies.map((reply) => reply?.cid)), [flattenedReplies]);
|
2024-04-29 21:49:00 +02:00
|
|
|
|
2024-09-01 17:10:14 +02:00
|
|
|
const { accountComments } = useAccountComments();
|
2024-08-30 12:19:18 +02:00
|
|
|
|
2024-09-01 17:10:14 +02:00
|
|
|
const filteredAccountComments = useMemo(() => {
|
2024-09-03 12:06:21 +02:00
|
|
|
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)) {
|
2024-08-30 12:19:18 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2024-09-03 12:06:21 +02:00
|
|
|
const parent = commentMap.get(currentCid);
|
|
|
|
|
if (!parent) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
currentCid = parent.parentCid;
|
|
|
|
|
}
|
|
|
|
|
return currentCid === comment?.cid;
|
|
|
|
|
});
|
|
|
|
|
}, [accountComments, comment?.cid, replyCids]);
|
2024-04-29 21:49:00 +02:00
|
|
|
|
2024-03-22 16:15:38 +01:00
|
|
|
// the account's replies have a delay before getting published, so get them locally from accountComments instead
|
|
|
|
|
const accountRepliesNotYetPublished = useMemo(() => {
|
2024-04-02 16:42:36 +02:00
|
|
|
const replies = flattenedReplies || [];
|
2024-03-22 16:15:38 +01:00
|
|
|
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
|
2024-08-30 12:19:18 +02:00
|
|
|
return filteredAccountComments.filter((accountReply) => !replyCids.has(accountReply?.cid));
|
|
|
|
|
}, [flattenedReplies, filteredAccountComments]);
|
2024-03-22 16:15:38 +01:00
|
|
|
|
|
|
|
|
const repliesAndNotYetPublishedReplies = useMemo(() => {
|
2024-06-02 20:51:15 +02:00
|
|
|
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;
|
|
|
|
|
});
|
2024-04-02 16:42:36 +02:00
|
|
|
}, [flattenedReplies, accountRepliesNotYetPublished]);
|
2024-03-22 16:15:38 +01:00
|
|
|
|
|
|
|
|
return repliesAndNotYetPublishedReplies;
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-06 20:55:05 +02:00
|
|
|
export default useReplies;
|