diff --git a/app/(auth)/series/[id]/page.tsx b/app/(auth)/series/[id]/page.tsx index d0f72916..fcdfcb26 100644 --- a/app/(auth)/series/[id]/page.tsx +++ b/app/(auth)/series/[id]/page.tsx @@ -38,7 +38,7 @@ const page: React.FC = () => { itemId: seriesId, }), enabled: !!seriesId && !!api, - staleTime: 0, + staleTime: 60, }); const backdropUrl = useMemo( diff --git a/components/series/NextEpisodeButton.tsx b/components/series/NextEpisodeButton.tsx new file mode 100644 index 00000000..d5d95faa --- /dev/null +++ b/components/series/NextEpisodeButton.tsx @@ -0,0 +1,107 @@ +import { Ionicons } from "@expo/vector-icons"; +import { Button } from "../Button"; +import { useRouter } from "expo-router"; +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; +import { useQuery } from "@tanstack/react-query"; +import { useAtom } from "jotai"; +import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; +import { getItemsApi } from "@jellyfin/sdk/lib/utils/api"; +import { useMemo } from "react"; + +interface Props extends React.ComponentProps { + item: BaseItemDto; + type?: "next" | "previous"; +} + +export const NextEpisodeButton: React.FC = ({ + item, + type = "next", + ...props +}) => { + const router = useRouter(); + + const [user] = useAtom(userAtom); + const [api] = useAtom(apiAtom); + + // const { data: seasons } = useQuery({ + // queryKey: ["seasons", item.SeriesId], + // queryFn: async () => { + // if ( + // !api || + // !user?.Id || + // !item?.Id || + // !item?.SeriesId || + // !item?.IndexNumber + // ) + // return []; + + // const response = await getItemsApi(api).getItems({ + // parentId: item?.SeriesId, + // }); + + // console.log("seasons ~", type, response.data); + + // return (response.data.Items as BaseItemDto[]) ?? []; + // }, + // enabled: Boolean(api && user?.Id && item?.Id && item.SeasonId), + // }); + + // const nextSeason = useMemo(() => { + // if (!seasons) return null; + // const currentSeasonIndex = seasons.findIndex( + // (season) => season.Id === item.SeasonId, + // ); + + // if (currentSeasonIndex === seasons.length - 1) return null; + + // return seasons[currentSeasonIndex + 1]; + // }, [seasons]); + + const { data: nextEpisode } = useQuery({ + queryKey: ["nextEpisode", item.Id, item.ParentId, type], + queryFn: async () => { + if ( + !api || + !user?.Id || + !item?.Id || + !item?.ParentId || + !item?.IndexNumber + ) + return null; + + const response = await getItemsApi(api).getItems({ + parentId: item?.ParentId, + limit: 1, + startIndex: type === "next" ? item.IndexNumber : item.IndexNumber - 2, + }); + + console.log("NextEpisode ~", type, response.data); + + return (response.data.Items?.[0] as BaseItemDto) || null; + }, + enabled: Boolean(api && user?.Id && item?.Id && item.SeasonId), + }); + + const disabled = useMemo(() => { + if (!nextEpisode) return true; + if (nextEpisode.Id === item.Id) return true; + return false; + }, [nextEpisode, type]); + + if (item.Type !== "Episode") return null; + + return ( + + ); +};