diff --git a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/items/page.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/items/page.tsx index b9c25493..4c7934a7 100644 --- a/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/items/page.tsx +++ b/app/(auth)/(tabs)/(home,libraries,search,favorites,watchlists)/items/page.tsx @@ -86,7 +86,7 @@ const Page: React.FC = () => { diff --git a/components/ItemContent.tv.tsx b/components/ItemContent.tv.tsx index 4611c979..17fec0be 100644 --- a/components/ItemContent.tv.tsx +++ b/components/ItemContent.tv.tsx @@ -838,23 +838,23 @@ export const ItemContentTV: React.FC = React.memo( }, [selectedOptions?.bitrate?.key, t]); // Format year and duration - const year = item.ProductionYear; - const duration = item.RunTimeTicks + const year = item?.ProductionYear; + const duration = item?.RunTimeTicks ? runtimeTicksToMinutes(item.RunTimeTicks) : null; - const hasProgress = (item.UserData?.PlaybackPositionTicks ?? 0) > 0; + const hasProgress = (item?.UserData?.PlaybackPositionTicks ?? 0) > 0; const remainingTime = hasProgress ? runtimeTicksToMinutes( - (item.RunTimeTicks || 0) - - (item.UserData?.PlaybackPositionTicks || 0), + (item?.RunTimeTicks || 0) - + (item?.UserData?.PlaybackPositionTicks || 0), ) : null; // Get director - const director = item.People?.find((p) => p.Type === "Director"); + const director = item?.People?.find((p) => p.Type === "Director"); // Get cast (first 3) - const cast = item.People?.filter((p) => p.Type === "Actor")?.slice(0, 3); + const cast = item?.People?.filter((p) => p.Type === "Actor")?.slice(0, 3); if (!item || !selectedOptions) return null; diff --git a/hooks/useDefaultPlaySettings.ts b/hooks/useDefaultPlaySettings.ts index 51b0e9ee..255a114d 100644 --- a/hooks/useDefaultPlaySettings.ts +++ b/hooks/useDefaultPlaySettings.ts @@ -7,7 +7,10 @@ import { getDefaultPlaySettings } from "@/utils/jellyfin/getDefaultPlaySettings" * React hook wrapper for getDefaultPlaySettings. * Used in UI components for initial playback (no previous track state). */ -const useDefaultPlaySettings = (item: BaseItemDto, settings: Settings | null) => +const useDefaultPlaySettings = ( + item: BaseItemDto | null | undefined, + settings: Settings | null, +) => useMemo(() => { const { mediaSource, audioIndex, subtitleIndex, bitrate } = getDefaultPlaySettings(item, settings); diff --git a/utils/jellyfin/getDefaultPlaySettings.ts b/utils/jellyfin/getDefaultPlaySettings.ts index d5ac5032..fba1dbe1 100644 --- a/utils/jellyfin/getDefaultPlaySettings.ts +++ b/utils/jellyfin/getDefaultPlaySettings.ts @@ -42,12 +42,17 @@ export interface PreviousIndexes { * @param previous - Optional previous track selections to carry over (for sequential play) */ export function getDefaultPlaySettings( - item: BaseItemDto, + item: BaseItemDto | null | undefined, settings: Settings | null, previous?: { indexes?: PreviousIndexes; source?: MediaSourceInfo }, ): PlaySettings { const bitrate = settings?.defaultBitrate ?? BITRATES[0]; + // Handle undefined/null item + if (!item) { + return { item: {} as BaseItemDto, bitrate }; + } + // Live TV programs don't have media sources if (item.Type === "Program") { return { item, bitrate };