diff --git a/components/persons/TVActorPage.tsx b/components/persons/TVActorPage.tsx index eacfd7b1..f7062c61 100644 --- a/components/persons/TVActorPage.tsx +++ b/components/persons/TVActorPage.tsx @@ -19,17 +19,19 @@ import { Dimensions, Easing, FlatList, - Pressable, ScrollView, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { Text } from "@/components/common/Text"; import { getItemNavigation } from "@/components/common/TouchableItemRouter"; -import { ItemCardText } from "@/components/ItemCardText"; import { Loader } from "@/components/Loader"; import MoviePoster from "@/components/posters/MoviePoster.tv"; +import SeriesPoster from "@/components/posters/SeriesPoster.tv"; +import { TVFocusablePoster } from "@/components/tv/TVFocusablePoster"; +import { TVItemCardText } from "@/components/tv/TVItemCardText"; import { useScaledTVPosterSizes } from "@/constants/TVPosterSizes"; +import { useScaledTVTypography } from "@/constants/TVTypography"; import useRouter from "@/hooks/useAppRouter"; import { useTVItemActionModal } from "@/hooks/useTVItemActionModal"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; @@ -44,64 +46,6 @@ const ACTOR_IMAGE_SIZE = 250; const ITEM_GAP = 16; const SCALE_PADDING = 20; -// Focusable poster wrapper component for TV -const TVFocusablePoster: React.FC<{ - children: React.ReactNode; - onPress: () => void; - onLongPress?: () => void; - hasTVPreferredFocus?: boolean; - onFocus?: () => void; - onBlur?: () => void; -}> = ({ - children, - onPress, - onLongPress, - hasTVPreferredFocus, - onFocus, - onBlur, -}) => { - const [focused, setFocused] = useState(false); - const scale = useRef(new Animated.Value(1)).current; - - const animateTo = (value: number) => - Animated.timing(scale, { - toValue: value, - duration: 150, - easing: Easing.out(Easing.quad), - useNativeDriver: true, - }).start(); - - return ( - { - setFocused(true); - animateTo(1.05); - onFocus?.(); - }} - onBlur={() => { - setFocused(false); - animateTo(1); - onBlur?.(); - }} - hasTVPreferredFocus={hasTVPreferredFocus} - > - - {children} - - - ); -}; - interface TVActorPageProps { personId: string; } @@ -114,6 +58,7 @@ export const TVActorPage: React.FC = ({ personId }) => { const segments = useSegments(); const from = (segments as string[])[2] || "(home)"; const posterSizes = useScaledTVPosterSizes(); + const typography = useScaledTVTypography(); const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); @@ -294,29 +239,48 @@ export const TVActorPage: React.FC = ({ personId }) => { [], ); - // Render filmography item - const renderFilmographyItem = useCallback( - ( - { item: filmItem, index }: { item: BaseItemDto; index: number }, - isFirstSection: boolean, - ) => ( + // Render movie filmography item + const renderMovieItem = useCallback( + ({ item: filmItem, index }: { item: BaseItemDto; index: number }) => ( handleItemPress(filmItem)} onLongPress={() => showItemActions(filmItem)} onFocus={() => setFocusedItem(filmItem)} - hasTVPreferredFocus={isFirstSection && index === 0} + hasTVPreferredFocus={index === 0} > - - + + ), - [handleItemPress, showItemActions], + [handleItemPress, showItemActions, posterSizes.poster], + ); + + // Render series filmography item + const renderSeriesItem = useCallback( + ({ item: filmItem, index }: { item: BaseItemDto; index: number }) => ( + + handleItemPress(filmItem)} + onLongPress={() => showItemActions(filmItem)} + onFocus={() => setFocusedItem(filmItem)} + hasTVPreferredFocus={movies.length === 0 && index === 0} + > + + + + + + + + + ), + [handleItemPress, showItemActions, posterSizes.poster, movies.length], ); if (isLoadingActor) { @@ -386,28 +350,16 @@ export const TVActorPage: React.FC = ({ personId }) => { )} - {/* Gradient overlays for readability */} + {/* Gradient overlay for readability */} - @@ -471,7 +423,7 @@ export const TVActorPage: React.FC = ({ personId }) => { {/* Actor name */} = ({ personId }) => { {item.ProductionYear && ( = ({ personId }) => { {item.Overview && ( = ({ personId }) => { = ({ personId }) => { horizontal data={movies} keyExtractor={(filmItem) => filmItem.Id!} - renderItem={(props) => renderFilmographyItem(props, true)} + renderItem={renderMovieItem} showsHorizontalScrollIndicator={false} initialNumToRender={6} maxToRenderPerBatch={4} @@ -575,7 +527,7 @@ export const TVActorPage: React.FC = ({ personId }) => { = ({ personId }) => { horizontal data={series} keyExtractor={(filmItem) => filmItem.Id!} - renderItem={(props) => - renderFilmographyItem(props, movies.length === 0) - } + renderItem={renderSeriesItem} showsHorizontalScrollIndicator={false} initialNumToRender={6} maxToRenderPerBatch={4} @@ -615,7 +565,7 @@ export const TVActorPage: React.FC = ({ personId }) => {