You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.1 KiB

import { useInfiniteQuery } from "@tanstack/react-query";
import { FC, Fragment, useCallback } from "react";
import { useClient } from "@/hooks/useClient";
import { SearchType } from "@/client/typings/search/options";
import { LoadingPage } from "@/components/LoadingPage";
import { ErrorPage } from "../ErrorPage";
import { Channel } from "./Channel";
import { LoadingNextPage } from "./LoadingNextPage";
import { Playlist } from "./Playlist";
import { Video } from "./Video";
export const SearchPageBody: FC<{ query: string; filter: SearchType }> = ({
filter,
query
}) => {
const client = useClient();
const {
data,
error,
fetchNextPage,
refetch,
isPending: isFetchingInitialData,
isFetchingNextPage
} = useInfiniteQuery({
queryKey: ["search", query, filter],
queryFn: async ({ pageParam }) => {
return await client.getSearch(query, {
pageParam: pageParam,
type: filter
});
},
initialPageParam: "",
getNextPageParam: (lastPage) => lastPage.nextCursor
});
const isFetchingNewPage = isFetchingNextPage && !isFetchingInitialData;
const fetchNewData = useCallback(
(visiblity: boolean) => {
if (visiblity && !isFetchingNextPage) fetchNextPage();
},
[isFetchingNextPage, fetchNextPage]
);
return (
<>
{isFetchingInitialData && (
<LoadingPage text={`Fetching search results for query \`${query}\``} />
)}
{data && (
<div className="flex flex-col gap-4 mt-4">
{data.pages.map((page, i) => {
return (
<Fragment key={i}>
{page.items.map((result) => {
switch (result.type) {
case "channel":
return <Channel key={result.id} data={result} />;
case "video":
return <Video key={result.id} data={result} />;
case "playlist":
return <Playlist key={result.id} data={result} />;
}
})}
</Fragment>
);
})}
{error === null && (
<LoadingNextPage
isFetching={isFetchingNewPage}
onVisible={fetchNewData}
/>
)}
</div>
)}
{error !== null && <ErrorPage data={error} refetch={refetch} />}
</>
);
};