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
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} />}
|
|
</>
|
|
);
|
|
};
|