diff --git a/app/(auth)/(tabs)/(watchlists)/[watchlistId].tsx b/app/(auth)/(tabs)/(watchlists)/[watchlistId].tsx index 831feac7..b8a31190 100644 --- a/app/(auth)/(tabs)/(watchlists)/[watchlistId].tsx +++ b/app/(auth)/(tabs)/(watchlists)/[watchlistId].tsx @@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next"; import { ActivityIndicator, Alert, + Platform, RefreshControl, TouchableOpacity, useWindowDimensions, @@ -16,9 +17,17 @@ import { import { useSafeAreaInsets } from "react-native-safe-area-context"; import { HeaderBackButton } from "@/components/common/HeaderBackButton"; import { Text } from "@/components/common/Text"; -import { TouchableItemRouter } from "@/components/common/TouchableItemRouter"; +import { + getItemNavigation, + TouchableItemRouter, +} from "@/components/common/TouchableItemRouter"; import { ItemCardText } from "@/components/ItemCardText"; import { ItemPoster } from "@/components/posters/ItemPoster"; +import MoviePoster, { + TV_POSTER_WIDTH, +} from "@/components/posters/MoviePoster.tv"; +import SeriesPoster from "@/components/posters/SeriesPoster.tv"; +import { TVFocusablePoster } from "@/components/tv/TVFocusablePoster"; import useRouter from "@/hooks/useAppRouter"; import { useOrientation } from "@/hooks/useOrientation"; import { @@ -32,6 +41,20 @@ import { import * as ScreenOrientation from "@/packages/expo-screen-orientation"; import { userAtom } from "@/providers/JellyfinProvider"; +const TV_ITEM_GAP = 16; +const TV_SCALE_PADDING = 20; + +const TVItemCardText: React.FC<{ item: BaseItemDto }> = ({ item }) => ( + + + {item.Name} + + + {item.ProductionYear} + + +); + export default function WatchlistDetailScreen() { const { t } = useTranslation(); const router = useRouter(); @@ -47,6 +70,14 @@ export default function WatchlistDetailScreen() { : undefined; const nrOfCols = useMemo(() => { + if (Platform.isTV) { + // Calculate columns based on TV poster width + gap + const itemWidth = TV_POSTER_WIDTH + TV_ITEM_GAP; + return Math.max( + 1, + Math.floor((screenWidth - TV_SCALE_PADDING * 2) / itemWidth), + ); + } if (screenWidth < 300) return 2; if (screenWidth < 500) return 3; if (screenWidth < 800) return 5; @@ -153,6 +184,37 @@ export default function WatchlistDetailScreen() { [removeFromWatchlist, watchlistIdNum, watchlist?.name, t], ); + const renderTVItem = useCallback( + ({ item, index }: { item: BaseItemDto; index: number }) => { + const handlePress = () => { + const navigation = getItemNavigation(item, "(watchlists)"); + router.push(navigation as any); + }; + + return ( + + + {item.Type === "Movie" && } + {(item.Type === "Series" || item.Type === "Episode") && ( + + )} + + + + ); + }, + [router], + ); + const renderItem = useCallback( ({ item, index }: { item: BaseItemDto; index: number }) => ( } - renderItem={renderItem} + renderItem={Platform.isTV ? renderTVItem : renderItem} ItemSeparatorComponent={() => (