mirror of https://github.com/buster-so/buster.git
added infinite scroll functionality
This commit is contained in:
parent
9a9b5fb674
commit
02ce6d6b3a
|
@ -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 = <T = SearchTextResponse>(
|
||||
|
@ -31,17 +27,10 @@ export const useSearchInfinite = (
|
|||
) => {
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
|
||||
const queryResult = useInfiniteQuery({
|
||||
const queryResult = useInfiniteScroll<SearchTextData>({
|
||||
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 };
|
||||
|
|
|
@ -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<HTMLDivElement>(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 (
|
||||
<div
|
||||
|
|
Loading…
Reference in New Issue