diff --git a/apps/web/src/api/buster_rest/search/queryRequests.ts b/apps/web/src/api/buster_rest/search/queryRequests.ts index 8b56a69a6..850e364ac 100644 --- a/apps/web/src/api/buster_rest/search/queryRequests.ts +++ b/apps/web/src/api/buster_rest/search/queryRequests.ts @@ -1,13 +1,9 @@ -import type { SearchTextResponse } from '@buster/server-shared/search'; -import { - keepPreviousData, - type UseQueryOptions, - useInfiniteQuery, - useQuery, -} from '@tanstack/react-query'; +import type { SearchTextData, SearchTextResponse } from '@buster/server-shared/search'; +import { keepPreviousData, type UseQueryOptions, useQuery } from '@tanstack/react-query'; import { useState } from 'react'; import type { ApiError } from '@/api/errors'; import { getSearchResultInfinite, searchQueryKeys } from '@/api/query_keys/search'; +import { useInfiniteScroll } from '@/api/query-helpers'; import { search } from './requests'; export const useSearch = ( @@ -31,17 +27,10 @@ export const useSearchInfinite = ( ) => { const [searchQuery, setSearchQuery] = useState(''); - const queryResult = useInfiniteQuery({ + const queryResult = useInfiniteScroll({ queryKey: ['search', 'results', 'infinite', params] as const, - staleTime: 1000 * 30, // 30 seconds, + staleTime: 1000 * 30, // 30 seconds queryFn: ({ pageParam = 1 }) => search({ query: searchQuery, page: pageParam, ...params }), - getNextPageParam: (lastPage) => { - if (!lastPage.pagination.has_more) { - return undefined; - } - return lastPage.pagination.page + 1; - }, - initialPageParam: 1, }); return { ...queryResult, setSearchQuery, searchQuery }; diff --git a/apps/web/src/routes/app/_app/test-pagination.tsx b/apps/web/src/routes/app/_app/test-pagination.tsx index 6732d1b0d..6034e5891 100644 --- a/apps/web/src/routes/app/_app/test-pagination.tsx +++ b/apps/web/src/routes/app/_app/test-pagination.tsx @@ -1,36 +1,19 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; import { createFileRoute } from '@tanstack/react-router'; -import { useEffect, useRef } from 'react'; -import { search, useSearchInfinite } from '@/api/buster_rest/search'; +import { useSearchInfinite } from '@/api/buster_rest/search'; export const Route = createFileRoute('/app/_app/test-pagination')({ component: RouteComponent, }); function RouteComponent() { - const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useSearchInfinite(); - const scrollContainerRef = useRef(null); - - // Combine all pages into a single array of results - const allResults = data?.pages.flatMap((page) => page.data) ?? []; - - useEffect(() => { - const container = scrollContainerRef.current; - if (!container) return; - - const handleScroll = () => { - const { scrollTop, scrollHeight, clientHeight } = container; - // Trigger when user is within 100px of the bottom - if (scrollHeight - scrollTop - clientHeight < 100) { - if (hasNextPage && !isFetchingNextPage) { - fetchNextPage(); - } - } - }; - - container.addEventListener('scroll', handleScroll); - return () => container.removeEventListener('scroll', handleScroll); - }, [hasNextPage, isFetchingNextPage, fetchNextPage]); + const { + scrollContainerRef, + allResults, + hasNextPage, + isFetchingNextPage, + isLoading, + fetchNextPage, + } = useSearchInfinite(); return (