|
|
@ -4,7 +4,7 @@ import { Search as SearchInput } from "@/components/Search";
|
|
|
|
import { useClient } from "@/hooks/useClient";
|
|
|
|
import { useClient } from "@/hooks/useClient";
|
|
|
|
import { Component } from "@/typings/component";
|
|
|
|
import { Component } from "@/typings/component";
|
|
|
|
import { Spacer } from "@nextui-org/spacer";
|
|
|
|
import { Spacer } from "@nextui-org/spacer";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
|
|
import { useSearchParams } from "next/navigation";
|
|
|
|
import { useSearchParams } from "next/navigation";
|
|
|
|
import { Channel } from "./Channel";
|
|
|
|
import { Channel } from "./Channel";
|
|
|
|
import { Container } from "@/components/Container";
|
|
|
|
import { Container } from "@/components/Container";
|
|
|
@ -12,6 +12,10 @@ import { LoadingPage } from "@/components/LoadingPage";
|
|
|
|
import { Button } from "@nextui-org/button";
|
|
|
|
import { Button } from "@nextui-org/button";
|
|
|
|
import { Video } from "./Video";
|
|
|
|
import { Video } from "./Video";
|
|
|
|
import { Playlist } from "./Playlist";
|
|
|
|
import { Playlist } from "./Playlist";
|
|
|
|
|
|
|
|
import { Fragment, useCallback } from "react";
|
|
|
|
|
|
|
|
import { CircularProgress } from "@nextui-org/progress";
|
|
|
|
|
|
|
|
import { useVisibility } from "reactjs-visibility";
|
|
|
|
|
|
|
|
import { Loading } from "./Loading";
|
|
|
|
|
|
|
|
|
|
|
|
export const Search: Component = () => {
|
|
|
|
export const Search: Component = () => {
|
|
|
|
const searchParams = useSearchParams();
|
|
|
|
const searchParams = useSearchParams();
|
|
|
@ -20,23 +24,41 @@ export const Search: Component = () => {
|
|
|
|
|
|
|
|
|
|
|
|
const client = useClient();
|
|
|
|
const client = useClient();
|
|
|
|
|
|
|
|
|
|
|
|
const { isLoading, error, refetch, data } = useQuery({
|
|
|
|
const {
|
|
|
|
|
|
|
|
data,
|
|
|
|
|
|
|
|
error,
|
|
|
|
|
|
|
|
fetchNextPage,
|
|
|
|
|
|
|
|
hasNextPage,
|
|
|
|
|
|
|
|
refetch,
|
|
|
|
|
|
|
|
isFetching,
|
|
|
|
|
|
|
|
isFetchingNextPage
|
|
|
|
|
|
|
|
} = useInfiniteQuery({
|
|
|
|
queryKey: ["search", query],
|
|
|
|
queryKey: ["search", query],
|
|
|
|
queryFn: () => {
|
|
|
|
queryFn: async ({ pageParam }) => {
|
|
|
|
if (query === null) return;
|
|
|
|
return await client.getSearch(query ?? "", { pageParam: pageParam });
|
|
|
|
|
|
|
|
},
|
|
|
|
return client.getSearch(query);
|
|
|
|
enabled: query !== null,
|
|
|
|
}
|
|
|
|
initialPageParam: "",
|
|
|
|
|
|
|
|
getNextPageParam: (lastPage, pages) => lastPage.nextCursor
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const results = data ?? [];
|
|
|
|
const handleUserReachedPageEnd = useCallback(
|
|
|
|
|
|
|
|
(visiblity: boolean) => {
|
|
|
|
|
|
|
|
console.log(visiblity);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(visiblity, !isFetchingNextPage, hasNextPage);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (visiblity && !isFetchingNextPage) fetchNextPage();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
[hasNextPage, isFetchingNextPage]
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<Container>
|
|
|
|
<Container>
|
|
|
|
<SearchInput initialQueryValue={query ?? undefined} />
|
|
|
|
<SearchInput initialQueryValue={query ?? undefined} />
|
|
|
|
<Spacer y={4} />
|
|
|
|
<Spacer y={4} />
|
|
|
|
{isLoading && <LoadingPage />}
|
|
|
|
{isFetching && <LoadingPage />}
|
|
|
|
{error && (
|
|
|
|
{error && (
|
|
|
|
<div className="flex-1 flex items-center justify-center">
|
|
|
|
<div className="flex-1 flex items-center justify-center">
|
|
|
|
<div className="text-center">
|
|
|
|
<div className="text-center">
|
|
|
@ -52,8 +74,10 @@ export const Search: Component = () => {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<div className="flex flex-col gap-4">
|
|
|
|
<div className="flex flex-col gap-4">
|
|
|
|
{results.length != 0 &&
|
|
|
|
{data?.pages.map((page, i) => {
|
|
|
|
results.map((result) => {
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Fragment key={i}>
|
|
|
|
|
|
|
|
{page.items.map((result) => {
|
|
|
|
switch (result.type) {
|
|
|
|
switch (result.type) {
|
|
|
|
case "channel":
|
|
|
|
case "channel":
|
|
|
|
return <Channel key={result.id} data={result} />;
|
|
|
|
return <Channel key={result.id} data={result} />;
|
|
|
@ -65,6 +89,18 @@ export const Search: Component = () => {
|
|
|
|
return <Playlist key={result.id} data={result} />;
|
|
|
|
return <Playlist key={result.id} data={result} />;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Loading
|
|
|
|
|
|
|
|
isFetching={isFetchingNextPage}
|
|
|
|
|
|
|
|
onVisible={handleUserReachedPageEnd}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* {!isFetching && !isFetchingNextPage && !error && (
|
|
|
|
|
|
|
|
<Button onClick={() => fetchNextPage()}>Load more</Button>
|
|
|
|
|
|
|
|
)} */}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Container>
|
|
|
|
</Container>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|