2026-01-02 16:42:16 +01:00
|
|
|
import { useMemo, useRef } from 'react';
|
2024-05-10 21:47:00 +02:00
|
|
|
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
|
|
|
|
|
import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
|
|
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
/**
|
|
|
|
|
* Extracts popular posts from subplebbits.
|
|
|
|
|
* Uses memoization to avoid recomputing when only updatingState changes.
|
|
|
|
|
*/
|
2024-05-10 21:47:00 +02:00
|
|
|
const usePopularPosts = (subplebbits: Subplebbit[]) => {
|
2026-01-02 16:42:16 +01:00
|
|
|
// Track the previous CID list to detect actual content changes vs transient state changes
|
|
|
|
|
const prevCidsRef = useRef<string>('');
|
2024-05-10 21:47:00 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
const { popularPosts, error } = useMemo(() => {
|
|
|
|
|
try {
|
|
|
|
|
const uniqueLinks: Set<string> = new Set();
|
|
|
|
|
const allPosts: Comment[] = [];
|
2024-06-03 17:26:47 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
const postsPerSub = [0, 8, 4, 3, 2, 2, 2, 2, 1][Math.min(subplebbits.length, 8)];
|
2024-05-10 21:47:00 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
subplebbits.forEach((subplebbit: any) => {
|
|
|
|
|
let subplebbitPosts: Comment[] = [];
|
2024-05-10 21:47:00 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
if (subplebbit?.posts?.pages?.hot?.comments) {
|
|
|
|
|
for (const post of Object.values(subplebbit.posts.pages.hot.comments as Comment)) {
|
|
|
|
|
const { deleted, link, linkHeight, linkWidth, locked, pinned, removed, replyCount, thumbnailUrl } = post;
|
2024-05-10 21:47:00 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
try {
|
|
|
|
|
const commentMediaInfo = getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight);
|
|
|
|
|
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
|
2024-10-12 17:09:23 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
if (hasThumbnail && replyCount > 1 && !deleted && !removed && !locked && !pinned && !uniqueLinks.has(link)) {
|
|
|
|
|
subplebbitPosts.push(post);
|
|
|
|
|
uniqueLinks.add(link);
|
2024-10-12 17:09:23 +02:00
|
|
|
}
|
2026-01-02 16:42:16 +01:00
|
|
|
} catch (err) {
|
|
|
|
|
console.error('Error processing post:', err);
|
2024-10-12 17:09:23 +02:00
|
|
|
}
|
2024-05-10 21:47:00 +02:00
|
|
|
}
|
|
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
subplebbitPosts.sort((a: any, b: any) => b.timestamp - a.timestamp);
|
|
|
|
|
allPosts.push(...subplebbitPosts.slice(0, postsPerSub));
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-10-12 17:09:23 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
const sortedPosts = allPosts.sort((a: any, b: any) => b.timestamp - a.timestamp).slice(0, 8);
|
2024-05-10 21:47:00 +02:00
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
return { popularPosts: sortedPosts, error: null };
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('Error in usePopularPosts:', err);
|
|
|
|
|
return { popularPosts: [], error: 'Failed to fetch popular posts' };
|
|
|
|
|
}
|
2024-05-10 21:47:00 +02:00
|
|
|
}, [subplebbits]);
|
|
|
|
|
|
2026-01-02 16:42:16 +01:00
|
|
|
// Create stable reference: only update if the CIDs actually change
|
|
|
|
|
// This prevents unnecessary rerenders when only updatingState changes
|
|
|
|
|
const currentCids = popularPosts.map((p: any) => p.cid).join(',');
|
|
|
|
|
const stablePostsRef = useRef<Comment[]>(popularPosts);
|
|
|
|
|
|
|
|
|
|
if (currentCids !== prevCidsRef.current) {
|
|
|
|
|
prevCidsRef.current = currentCids;
|
|
|
|
|
stablePostsRef.current = popularPosts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isLoading = stablePostsRef.current.length === 0;
|
|
|
|
|
|
|
|
|
|
return { popularPosts: stablePostsRef.current, isLoading, error };
|
2024-05-10 21:47:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default usePopularPosts;
|