a tool for shared writing and social publishing
at update/reader 82 lines 2.4 kB view raw
1"use server"; 2 3import { getIdentityData } from "actions/getIdentityData"; 4import { supabaseServerClient } from "supabase/serverClient"; 5import type { 6 NormalizedDocument, 7 NormalizedPublication, 8} from "src/utils/normalizeRecords"; 9import { deduplicateByUriOrdered } from "src/utils/deduplicateRecords"; 10import { enrichDocumentToPost } from "./enrichPost"; 11 12export type Cursor = { 13 timestamp: string; 14 uri: string; 15}; 16 17export async function getReaderFeed( 18 cursor?: Cursor | null, 19): Promise<{ posts: Post[]; nextCursor: Cursor | null }> { 20 let auth_res = await getIdentityData(); 21 if (!auth_res?.atp_did) return { posts: [], nextCursor: null }; 22 let query = supabaseServerClient 23 .from("documents") 24 .select( 25 `*, 26 comments_on_documents(count), 27 document_mentions_in_bsky(count), 28 recommends_on_documents(count), 29 documents_in_publications!inner(publications!inner(*, publication_subscriptions!inner(*)))`, 30 ) 31 .eq( 32 "documents_in_publications.publications.publication_subscriptions.identity", 33 auth_res.atp_did, 34 ) 35 .order("sort_date", { ascending: false }) 36 .order("uri", { ascending: false }) 37 .limit(25); 38 if (cursor) { 39 query = query.or( 40 `sort_date.lt.${cursor.timestamp},and(sort_date.eq.${cursor.timestamp},uri.lt.${cursor.uri})`, 41 ); 42 } 43 let { data: rawFeed, error } = await query; 44 45 // Deduplicate records that may exist under both pub.leaflet and site.standard namespaces 46 const feed = deduplicateByUriOrdered(rawFeed || []); 47 48 let posts = ( 49 await Promise.all(feed.map((post) => enrichDocumentToPost(post as any))) 50 ).filter((post): post is Post => post !== null); 51 52 const nextCursor = 53 posts.length > 0 54 ? { 55 timestamp: posts[posts.length - 1].documents.sort_date, 56 uri: posts[posts.length - 1].documents.uri, 57 } 58 : null; 59 60 return { 61 posts, 62 nextCursor, 63 }; 64} 65 66export type Post = { 67 author: string | null; 68 publication?: { 69 href: string; 70 pubRecord: NormalizedPublication | null; 71 uri: string; 72 }; 73 documents: { 74 data: NormalizedDocument | null; 75 uri: string; 76 sort_date: string; 77 comments_on_documents: { count: number }[] | undefined; 78 document_mentions_in_bsky: { count: number }[] | undefined; 79 recommends_on_documents: { count: number }[] | undefined; 80 mentionsCount?: number; 81 }; 82};