diff --git a/app/reader/ReaderContent.tsx b/app/reader/ReaderContent.tsx index 4f68ab41..09ab23b5 100644 --- a/app/reader/ReaderContent.tsx +++ b/app/reader/ReaderContent.tsx @@ -14,7 +14,7 @@ import { useSmoker } from "components/Toast"; import { PubLeafletDocument, PubLeafletPublication } from "lexicons/api"; import { blobRefToSrc } from "src/utils/blobRefToSrc"; import { Json } from "supabase/database.types"; -import type { Post } from "./getReaderFeed"; +import type { Cursor, Post } from "./getReaderFeed"; import useSWRInfinite from "swr/infinite"; import { getReaderFeed } from "./getReaderFeed"; import { useEffect, useRef } from "react"; @@ -23,20 +23,20 @@ import { useRouter } from "next/navigation"; export const ReaderContent = (props: { root_entity: string; posts: Post[]; - nextCursor: string | null; + nextCursor: Cursor | null; }) => { const getKey = ( pageIndex: number, - previousPageData: { posts: Post[]; nextCursor: string | null } | null, + previousPageData: { posts: Post[]; nextCursor: Cursor | null } | null, ) => { // Reached the end if (previousPageData && !previousPageData.nextCursor) return null; // First page, we don't have previousPageData - if (pageIndex === 0) return ["reader-feed", null]; + if (pageIndex === 0) return ["reader-feed", null] as const; // Add the cursor to the key - return ["reader-feed", previousPageData?.nextCursor]; + return ["reader-feed", previousPageData?.nextCursor] as const; }; const { data, error, size, setSize, isValidating } = useSWRInfinite( diff --git a/app/reader/SubscriptionsContent.tsx b/app/reader/SubscriptionsContent.tsx index 57522c19..512867de 100644 --- a/app/reader/SubscriptionsContent.tsx +++ b/app/reader/SubscriptionsContent.tsx @@ -6,26 +6,27 @@ import { Json } from "supabase/database.types"; import { PublicationSubscription, getSubscriptions } from "./getSubscriptions"; import useSWRInfinite from "swr/infinite"; import { useEffect, useRef } from "react"; +import { Cursor } from "./getReaderFeed"; export const SubscriptionsContent = (props: { publications: PublicationSubscription[]; - nextCursor: string | null; + nextCursor: Cursor | null; }) => { const getKey = ( pageIndex: number, previousPageData: { subscriptions: PublicationSubscription[]; - nextCursor: string | null; + nextCursor: Cursor | null; } | null, ) => { // Reached the end if (previousPageData && !previousPageData.nextCursor) return null; // First page, we don't have previousPageData - if (pageIndex === 0) return ["subscriptions", null]; + if (pageIndex === 0) return ["subscriptions", null] as const; // Add the cursor to the key - return ["subscriptions", previousPageData?.nextCursor]; + return ["subscriptions", previousPageData?.nextCursor] as const; }; const { data, error, size, setSize, isValidating } = useSWRInfinite( @@ -72,7 +73,7 @@ export const SubscriptionsContent = (props: { return (
- {allPublications?.map((p) => )} + {allPublications?.map((p, index) => )}
{/* Trigger element for loading more subscriptions */}
{ + cursor?: Cursor | null, +): Promise<{ posts: Post[]; nextCursor: Cursor | null }> { let auth_res = await getIdentityData(); if (!auth_res?.atp_did) return { posts: [], nextCursor: null }; let query = supabaseServerClient @@ -28,8 +33,11 @@ export async function getReaderFeed( auth_res.atp_did, ) .order("indexed_at", { ascending: false }) + .order("uri", { ascending: false }) .limit(25); - if (cursor) query.lt("indexed_at", cursor); + if (cursor) { + query = query.lt("indexed_at", cursor.timestamp).lte("uri", cursor.uri); + } let { data: feed, error } = await query; let posts = await Promise.all( @@ -55,9 +63,17 @@ export async function getReaderFeed( return p; }) || [], ); + const nextCursor = + posts.length > 0 + ? { + timestamp: posts[posts.length - 1].documents.indexed_at, + uri: posts[posts.length - 1].documents.uri, + } + : null; + return { posts, - nextCursor: posts[posts.length - 1]?.documents.indexed_at || null, + nextCursor, }; } diff --git a/app/reader/getSubscriptions.ts b/app/reader/getSubscriptions.ts index 0c6b5fd9..18e1f70a 100644 --- a/app/reader/getSubscriptions.ts +++ b/app/reader/getSubscriptions.ts @@ -6,17 +6,19 @@ import { getIdentityData } from "actions/getIdentityData"; import { Json } from "supabase/database.types"; import { supabaseServerClient } from "supabase/serverClient"; import { idResolver } from "./idResolver"; +import { Cursor } from "./getReaderFeed"; -export async function getSubscriptions(cursor?: string | null): Promise<{ - nextCursor: null | string; +export async function getSubscriptions(cursor?: Cursor | null): Promise<{ + nextCursor: null | Cursor; subscriptions: PublicationSubscription[]; }> { let auth_res = await getIdentityData(); if (!auth_res?.atp_did) return { subscriptions: [], nextCursor: null }; let query = supabaseServerClient .from("publication_subscriptions") - .select(`publications(*, documents_in_publications(*, documents(*)))`) + .select(`*, publications(*, documents_in_publications(*, documents(*)))`) .order(`created_at`, { ascending: false }) + .order(`uri`, { ascending: false }) .order("indexed_at", { referencedTable: "publications.documents_in_publications", }) @@ -24,8 +26,11 @@ export async function getSubscriptions(cursor?: string | null): Promise<{ .limit(25) .eq("identity", auth_res.atp_did); - if (cursor) query.lt("indexed_at", cursor); + if (cursor) { + query = query.lt("created_at", cursor.timestamp).lte("uri", cursor.uri); + } let { data: pubs, error } = await query; + console.log(cursor); const actors: string[] = [ ...new Set( @@ -46,8 +51,10 @@ export async function getSubscriptions(cursor?: string | null): Promise<{ const nextCursor = pubs && pubs.length > 0 - ? pubs[pubs.length - 1].publications?.documents_in_publications?.[0] - ?.indexed_at || null + ? { + timestamp: pubs[pubs.length - 1].created_at, + uri: pubs[pubs.length - 1].uri, + } : null; return {