diff --git a/components/series/SeasonPicker.tsx b/components/series/SeasonPicker.tsx index 5e117437..9cef17a3 100644 --- a/components/series/SeasonPicker.tsx +++ b/components/series/SeasonPicker.tsx @@ -1,26 +1,33 @@ import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; +import { runtimeTicksToSeconds } from "@/utils/time"; import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { useQuery } from "@tanstack/react-query"; import { useRouter } from "expo-router"; import { atom, useAtom } from "jotai"; -import { useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; import { TouchableOpacity, View } from "react-native"; import * as DropdownMenu from "zeego/dropdown-menu"; import ContinueWatchingPoster from "../ContinueWatchingPoster"; -import { ItemCardText } from "../ItemCardText"; -import { HorizontalScroll } from "../common/HorrizontalScroll"; +import { DownloadItem } from "../DownloadItem"; +import { Loader } from "../Loader"; import { Text } from "../common/Text"; type Props = { item: BaseItemDto; }; -export const seasonIndexAtom = atom(1); +type SeasonIndexState = { + [seriesId: string]: number; +}; + +export const seasonIndexAtom = atom({}); export const SeasonPicker: React.FC = ({ item }) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); - const [seasonIndex, setSeasonIndex] = useAtom(seasonIndexAtom); + const [seasonIndexState, setSeasonIndexState] = useAtom(seasonIndexAtom); + + const seasonIndex = seasonIndexState[item.Id ?? ""]; const router = useRouter(); @@ -40,7 +47,7 @@ export const SeasonPicker: React.FC = ({ item }) => { headers: { Authorization: `MediaBrowser DeviceId="${api.deviceInfo.id}", Token="${api.accessToken}"`, }, - }, + } ); return response.data.Items; @@ -48,13 +55,24 @@ export const SeasonPicker: React.FC = ({ item }) => { enabled: !!api && !!user?.Id && !!item.Id, }); + useEffect(() => { + if (seasons && seasons.length > 0 && seasonIndex === undefined) { + const firstSeason = seasons[0]; + if (firstSeason.IndexNumber !== undefined) { + setSeasonIndexState((prev) => ({ + ...prev, + [item.Id ?? ""]: firstSeason.IndexNumber, + })); + } + } + }, [seasons, seasonIndex, setSeasonIndexState, item.Id]); const selectedSeasonId: string | null = useMemo( () => seasons?.find((season: any) => season.IndexNumber === seasonIndex)?.Id, - [seasons, seasonIndex], + [seasons, seasonIndex] ); - const { data: episodes } = useQuery({ + const { data: episodes, isFetching } = useQuery({ queryKey: ["episodes", item.Id, selectedSeasonId], queryFn: async () => { if (!api || !user?.Id || !item.Id) return []; @@ -70,7 +88,7 @@ export const SeasonPicker: React.FC = ({ item }) => { headers: { Authorization: `MediaBrowser DeviceId="${api.deviceInfo.id}", Token="${api.accessToken}"`, }, - }, + } ); return response.data.Items as BaseItemDto[]; @@ -78,8 +96,20 @@ export const SeasonPicker: React.FC = ({ item }) => { enabled: !!api && !!user?.Id && !!item.Id && !!selectedSeasonId, }); + // Used for height calculation + const [nrOfEpisodes, setNrOfEpisodes] = useState(0); + useEffect(() => { + if (episodes && episodes.length > 0) { + setNrOfEpisodes(episodes.length); + } + }, [episodes]); + return ( - + @@ -102,7 +132,10 @@ export const SeasonPicker: React.FC = ({ item }) => { { - setSeasonIndex(season.IndexNumber); + setSeasonIndexState((prev) => ({ + ...prev, + [item.Id ?? ""]: season.IndexNumber, + })); }} > {season.Name} @@ -110,7 +143,8 @@ export const SeasonPicker: React.FC = ({ item }) => { ))} - {episodes && ( + {/* Old View. Might have a setting later to manually select view. */} + {/* {episodes && ( data={episodes} @@ -128,7 +162,56 @@ export const SeasonPicker: React.FC = ({ item }) => { )} /> - )} + )} */} + + {isFetching ? ( + + + + ) : ( + episodes?.map((e: BaseItemDto) => ( + { + router.push(`/(auth)/items/${e.Id}`); + }} + className="flex flex-col mb-4" + > + + + + + + + {e.Name} + + + {`S${e.ParentIndexNumber?.toString()}:E${e.IndexNumber?.toString()}`} + + + {runtimeTicksToSeconds(e.RunTimeTicks)} + + + + + + + + + {e.Overview} + + + )) + )} + ); };