summaryrefslogtreecommitdiff
path: root/apps/web/lib/queries/use-custom-feed-timeline.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/lib/queries/use-custom-feed-timeline.ts')
-rw-r--r--apps/web/lib/queries/use-custom-feed-timeline.ts76
1 files changed, 76 insertions, 0 deletions
diff --git a/apps/web/lib/queries/use-custom-feed-timeline.ts b/apps/web/lib/queries/use-custom-feed-timeline.ts
new file mode 100644
index 0000000..4224123
--- /dev/null
+++ b/apps/web/lib/queries/use-custom-feed-timeline.ts
@@ -0,0 +1,76 @@
+"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 useCustomFeedTimeline(customFeedIdentifier: string | null) {
+ const supabaseClient = createSupabaseBrowserClient()
+
+ return useInfiniteQuery({
+ queryKey: queryKeys.customFeeds.timeline(customFeedIdentifier ?? ""),
+ queryFn: async ({
+ pageParam,
+ }: {
+ pageParam: string | undefined
+ }) => {
+ const { data, error } = await supabaseClient.rpc(
+ "get_custom_feed_timeline",
+ {
+ p_custom_feed_id: customFeedIdentifier!,
+ p_result_limit: TIMELINE_PAGE_SIZE,
+ p_pagination_cursor: pageParam ?? undefined,
+ }
+ )
+
+ 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
+ },
+ enabled: !!customFeedIdentifier,
+ })
+}