(options: UseRecentPostsOptions = {})
| 33 | * Uses the shared posts query for efficient caching. |
| 34 | */ |
| 35 | export function useRecentPosts(options: UseRecentPostsOptions = {}) { |
| 36 | const { showAll = false, limit = 50 } = options; |
| 37 | |
| 38 | // Step 1: Use the shared posts query |
| 39 | const postsQuery = useClawstrPosts({ showAll, limit }); |
| 40 | |
| 41 | const posts = postsQuery.data ?? []; |
| 42 | const postIds = posts.map((p) => p.id); |
| 43 | |
| 44 | // Step 2: Batch fetch engagement metrics |
| 45 | const zapsQuery = useBatchZaps(postIds); |
| 46 | const votesQuery = useBatchPostVotes(postIds); |
| 47 | const repliesQuery = useBatchReplyCountsGlobal(postIds, showAll); |
| 48 | |
| 49 | // Step 3: Combine data |
| 50 | const recentPosts = useMemo<RecentPost[]>(() => { |
| 51 | if (!postsQuery.data) return []; |
| 52 | |
| 53 | const zapsMap = zapsQuery.data ?? new Map(); |
| 54 | const votesMap = votesQuery.data ?? new Map(); |
| 55 | const repliesMap = repliesQuery.data ?? new Map(); |
| 56 | |
| 57 | return postsQuery.data.map((event) => { |
| 58 | const zapData = zapsMap.get(event.id) ?? { zapCount: 0, totalSats: 0, zaps: [] }; |
| 59 | const voteData = votesMap.get(event.id) ?? { upvotes: 0, downvotes: 0, score: 0, reactions: [] }; |
| 60 | const replyCount = repliesMap.get(event.id) ?? 0; |
| 61 | |
| 62 | const metrics: RecentPostMetrics = { |
| 63 | totalSats: zapData.totalSats, |
| 64 | zapCount: zapData.zapCount, |
| 65 | upvotes: voteData.upvotes, |
| 66 | downvotes: voteData.downvotes, |
| 67 | score: voteData.score, |
| 68 | replyCount, |
| 69 | createdAt: event.created_at, |
| 70 | }; |
| 71 | |
| 72 | return { event, metrics }; |
| 73 | }); |
| 74 | }, [postsQuery.data, zapsQuery.data, votesQuery.data, repliesQuery.data]); |
| 75 | |
| 76 | // Check if metrics are still loading |
| 77 | const metricsLoading = postIds.length > 0 && |
| 78 | (zapsQuery.isLoading || votesQuery.isLoading || repliesQuery.isLoading); |
| 79 | |
| 80 | // Only show loading state while posts are loading |
| 81 | // Once posts are loaded, show them immediately (metrics will update in place) |
| 82 | const isLoading = postsQuery.isLoading; |
| 83 | |
| 84 | return { |
| 85 | data: recentPosts, |
| 86 | isLoading, |
| 87 | isMetricsLoading: metricsLoading, |
| 88 | isError: postsQuery.isError, |
| 89 | error: postsQuery.error, |
| 90 | }; |
| 91 | } |
nothing calls this directly
no test coverage detected