fix(popular-posts): base quota on loaded boards instead of total directories

The postsPerSub quota is now calculated from boards with actually loaded hot comments, not total filtered directories. This prevents the list from collapsing to a single post when many boards are empty or unavailable.
This commit is contained in:
plebeius
2026-02-15 14:52:27 +08:00
parent c667657e96
commit 2f563b441a
+10 -4
View File
@@ -15,13 +15,17 @@ const usePopularPosts = (subplebbits: Subplebbit[]) => {
const uniqueLinks: Set<string> = new Set(); const uniqueLinks: Set<string> = new Set();
const allPosts: Comment[] = []; const allPosts: Comment[] = [];
const postsPerSub = [0, 8, 4, 3, 2, 2, 2, 2, 1][Math.min(subplebbits.length, 8)]; // Base quota on boards that currently have loaded hot comments.
// Using total directory count can underfill the list when many boards are empty/unavailable.
const loadedSubplebbitsCount = subplebbits.filter((sub) => sub?.posts?.pages?.hot?.comments).length;
const postsPerSub = [0, 8, 4, 3, 2, 2, 2, 2, 1][Math.min(loadedSubplebbitsCount, 8)];
subplebbits.forEach((subplebbit: any) => { subplebbits.forEach((subplebbit: any) => {
let subplebbitPosts: Comment[] = []; let subplebbitPosts: Comment[] = [];
if (subplebbit?.posts?.pages?.hot?.comments) { if (subplebbit?.posts?.pages?.hot?.comments) {
for (const post of Object.values(subplebbit.posts.pages.hot.comments as Comment)) { const rawPosts = Object.values(subplebbit.posts.pages.hot.comments as Comment);
for (const post of rawPosts) {
const { deleted, link, linkHeight, linkWidth, locked, pinned, removed, replyCount, thumbnailUrl } = post; const { deleted, link, linkHeight, linkWidth, locked, pinned, removed, replyCount, thumbnailUrl } = post;
try { try {
@@ -38,7 +42,8 @@ const usePopularPosts = (subplebbits: Subplebbit[]) => {
} }
subplebbitPosts.sort((a: any, b: any) => b.timestamp - a.timestamp); subplebbitPosts.sort((a: any, b: any) => b.timestamp - a.timestamp);
allPosts.push(...subplebbitPosts.slice(0, postsPerSub)); const selectedPosts = subplebbitPosts.slice(0, postsPerSub);
allPosts.push(...selectedPosts);
} }
}); });
@@ -55,8 +60,9 @@ const usePopularPosts = (subplebbits: Subplebbit[]) => {
// Build a key from relevant mutable fields, not just CIDs // Build a key from relevant mutable fields, not just CIDs
const currentKey = popularPosts.map((p) => `${p.cid}:${p.replyCount}:${p.timestamp}:${p.locked}:${p.pinned}`).join(','); const currentKey = popularPosts.map((p) => `${p.cid}:${p.replyCount}:${p.timestamp}:${p.locked}:${p.pinned}`).join(',');
const stablePostsRef = useRef<Comment[]>(popularPosts); const stablePostsRef = useRef<Comment[]>(popularPosts);
const keyChanged = currentKey !== prevCidsRef.current;
if (currentKey !== prevCidsRef.current) { if (keyChanged) {
prevCidsRef.current = currentKey; prevCidsRef.current = currentKey;
stablePostsRef.current = popularPosts; stablePostsRef.current = popularPosts;
} }