"use client" import { useInfiniteQuery } from "@tanstack/react-query" import { createSupabaseBrowserClient } from "@/lib/supabase/client" import { queryKeys } from "./query-keys" import type { TimelineEntry } from "@/lib/types/timeline" const TIMELINE_PAGE_SIZE = 50 interface TimelineRow { entry_id: string feed_id: string feed_title: string custom_title: string | null entry_title: string entry_url: string author: string | null summary: string | null image_url: string | null published_at: string is_read: boolean is_saved: boolean enclosure_url: string | null enclosure_type: string | null } function mapRowToTimelineEntry(row: TimelineRow): TimelineEntry { return { entryIdentifier: row.entry_id, feedIdentifier: row.feed_id, feedTitle: row.feed_title, customTitle: row.custom_title, entryTitle: row.entry_title, entryUrl: row.entry_url, author: row.author, summary: row.summary, imageUrl: row.image_url, publishedAt: row.published_at, isRead: row.is_read, isSaved: row.is_saved, enclosureUrl: row.enclosure_url, enclosureType: row.enclosure_type, } } export function useTimeline( folderIdentifier?: string | null, feedIdentifier?: string | null, unreadOnly?: boolean ) { const supabaseClient = createSupabaseBrowserClient() return useInfiniteQuery({ queryKey: queryKeys.timeline.list(folderIdentifier, feedIdentifier, unreadOnly), queryFn: async ({ pageParam, }: { pageParam: string | undefined }) => { const { data, error } = await supabaseClient.rpc("get_timeline", { target_folder_id: folderIdentifier ?? undefined, target_feed_id: feedIdentifier ?? undefined, result_limit: TIMELINE_PAGE_SIZE, pagination_cursor: pageParam ?? undefined, unread_only: unreadOnly ?? false, }) if (error) throw error return ((data as TimelineRow[]) ?? []).map(mapRowToTimelineEntry) }, initialPageParam: undefined as string | undefined, getNextPageParam: (lastPage: TimelineEntry[]) => { if (lastPage.length < TIMELINE_PAGE_SIZE) return undefined return lastPage[lastPage.length - 1].publishedAt }, }) }