/** * Episode List for Chromecast Player * Displays list of episodes for TV shows with thumbnails */ import { Ionicons } from "@expo/vector-icons"; import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client"; import { Image } from "expo-image"; import React from "react"; import { FlatList, Modal, Pressable, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { Text } from "@/components/common/Text"; import { truncateTitle } from "@/utils/chromecast/helpers"; interface ChromecastEpisodeListProps { visible: boolean; onClose: () => void; currentItem: BaseItemDto | null; episodes: BaseItemDto[]; onSelectEpisode: (episode: BaseItemDto) => void; } export const ChromecastEpisodeList: React.FC = ({ visible, onClose, currentItem, episodes, onSelectEpisode, }) => { const insets = useSafeAreaInsets(); const renderEpisode = ({ item }: { item: BaseItemDto }) => { const isCurrentEpisode = item.Id === currentItem?.Id; return ( { onSelectEpisode(item); onClose(); }} style={{ flexDirection: "row", padding: 12, backgroundColor: isCurrentEpisode ? "#e50914" : "transparent", borderRadius: 8, marginBottom: 8, }} > {/* Thumbnail */} {item.ImageTags?.Primary && ( )} {!item.ImageTags?.Primary && ( )} {/* Episode info */} {item.IndexNumber}. {truncateTitle(item.Name || "Unknown", 30)} {item.Overview || "No description available"} {item.RunTimeTicks && ( {Math.round((item.RunTimeTicks / 600000000) * 10) / 10} min )} {isCurrentEpisode && ( )} ); }; return ( {/* Header */} Episodes {/* Episode list */} item.Id || ""} contentContainerStyle={{ padding: 16, paddingBottom: insets.bottom + 16, }} showsVerticalScrollIndicator={false} /> ); };