diff options
| -rw-r--r-- | apps/mobile/app/dashboard/search.tsx | 15 | ||||
| -rw-r--r-- | apps/web/app/dashboard/search/page.tsx | 10 | ||||
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx | 2 | ||||
| -rw-r--r-- | apps/web/lib/hooks/bookmark-search.ts | 32 | ||||
| -rw-r--r-- | packages/trpc/routers/bookmarks.ts | 35 |
5 files changed, 75 insertions, 19 deletions
diff --git a/apps/mobile/app/dashboard/search.tsx b/apps/mobile/app/dashboard/search.tsx index 884345e7..de3d0f46 100644 --- a/apps/mobile/app/dashboard/search.tsx +++ b/apps/mobile/app/dashboard/search.tsx @@ -17,10 +17,15 @@ export default function Search() { const onRefresh = api.useUtils().bookmarks.searchBookmarks.invalidate; - const { data, error, refetch, isPending } = - api.bookmarks.searchBookmarks.useQuery( + const { data, error, refetch, isPending, fetchNextPage, isFetchingNextPage } = + api.bookmarks.searchBookmarks.useInfiniteQuery( { text: query }, - { placeholderData: keepPreviousData }, + { + placeholderData: keepPreviousData, + gcTime: 0, + initialCursor: null, + getNextPageParam: (lastPage) => lastPage.nextCursor, + }, ); if (error) { @@ -45,7 +50,9 @@ export default function Search() { {!data && <FullPageSpinner />} {data && ( <BookmarkList - bookmarks={data.bookmarks} + bookmarks={data.pages.flatMap((p) => p.bookmarks)} + fetchNextPage={fetchNextPage} + isFetchingNextPage={isFetchingNextPage} onRefresh={onRefresh} isRefreshing={isPending} /> diff --git a/apps/web/app/dashboard/search/page.tsx b/apps/web/app/dashboard/search/page.tsx index a239550c..beae73b8 100644 --- a/apps/web/app/dashboard/search/page.tsx +++ b/apps/web/app/dashboard/search/page.tsx @@ -6,12 +6,18 @@ import { FullPageSpinner } from "@/components/ui/full-page-spinner"; import { useBookmarkSearch } from "@/lib/hooks/bookmark-search"; function SearchComp() { - const { data } = useBookmarkSearch(); + const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = + useBookmarkSearch(); return ( <div className="flex flex-col gap-3"> {data ? ( - <BookmarksGrid bookmarks={data.bookmarks} /> + <BookmarksGrid + hasNextPage={hasNextPage} + fetchNextPage={fetchNextPage} + isFetchingNextPage={isFetchingNextPage} + bookmarks={data.pages.flatMap((b) => b.bookmarks)} + /> ) : ( <FullPageSpinner /> )} diff --git a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx index bc6cd6db..d18eeb1b 100644 --- a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx @@ -38,7 +38,7 @@ export default function UpdatableBookmarksGrid({ <BookmarksGrid bookmarks={data!.pages.flatMap((b) => b.bookmarks)} hasNextPage={hasNextPage} - fetchNextPage={() => fetchNextPage()} + fetchNextPage={fetchNextPage} isFetchingNextPage={isFetchingNextPage} showEditorCard={showEditorCard} /> diff --git a/apps/web/lib/hooks/bookmark-search.ts b/apps/web/lib/hooks/bookmark-search.ts index ffdf402d..9890ac6f 100644 --- a/apps/web/lib/hooks/bookmark-search.ts +++ b/apps/web/lib/hooks/bookmark-search.ts @@ -50,16 +50,25 @@ export function useDoBookmarkSearch() { export function useBookmarkSearch() { const { searchQuery } = useSearchQuery(); - const { data, isPending, isPlaceholderData, error } = - api.bookmarks.searchBookmarks.useQuery( - { - text: searchQuery, - }, - { - placeholderData: keepPreviousData, - gcTime: 0, - }, - ); + const { + data, + isPending, + isPlaceholderData, + error, + hasNextPage, + fetchNextPage, + isFetchingNextPage, + } = api.bookmarks.searchBookmarks.useInfiniteQuery( + { + text: searchQuery, + }, + { + placeholderData: keepPreviousData, + gcTime: 0, + initialCursor: null, + getNextPageParam: (lastPage) => lastPage.nextCursor, + }, + ); if (error) { throw error; @@ -71,5 +80,8 @@ export function useBookmarkSearch() { data, isPending, isPlaceholderData, + hasNextPage, + fetchNextPage, + isFetchingNextPage, }; } diff --git a/packages/trpc/routers/bookmarks.ts b/packages/trpc/routers/bookmarks.ts index 9708706a..8a4170cd 100644 --- a/packages/trpc/routers/bookmarks.ts +++ b/packages/trpc/routers/bookmarks.ts @@ -515,9 +515,25 @@ export const bookmarksAppRouter = router({ .input( z.object({ text: z.string(), + cursor: z + .object({ + offset: z.number(), + limit: z.number(), + }) + .nullish(), + }), + ) + .output( + z.object({ + bookmarks: z.array(zBookmarkSchema), + nextCursor: z + .object({ + offset: z.number(), + limit: z.number(), + }) + .nullable(), }), ) - .output(zGetBookmarksResponseSchema) .query(async ({ input, ctx }) => { const client = await getSearchIdxClient(); if (!client) { @@ -531,6 +547,12 @@ export const bookmarksAppRouter = router({ showRankingScore: true, attributesToRetrieve: ["id"], sort: ["createdAt:desc"], + ...(input.cursor + ? { + offset: input.cursor.offset, + limit: input.cursor.limit, + } + : {}), }); if (resp.hits.length == 0) { @@ -562,7 +584,16 @@ export const bookmarksAppRouter = router({ }); results.sort((a, b) => idToRank[b.id] - idToRank[a.id]); - return { bookmarks: results.map(toZodSchema), nextCursor: null }; + return { + bookmarks: results.map(toZodSchema), + nextCursor: + resp.hits.length + resp.offset >= resp.estimatedTotalHits + ? null + : { + offset: resp.hits.length + resp.offset, + limit: resp.limit, + }, + }; }), getBookmarks: authedProcedure .input(zGetBookmarksRequestSchema) |
