import { Ionicons } from "@expo/vector-icons"; import React from "react"; import { ActivityIndicator, Animated, Pressable, StyleSheet, View, } from "react-native"; import { Text } from "@/components/common/Text"; import { useScaledTVTypography } from "@/constants/TVTypography"; import type { SubtitleSearchResult } from "@/hooks/useRemoteSubtitles"; import { useTVFocusAnimation } from "./hooks/useTVFocusAnimation"; export interface TVSubtitleResultCardProps { result: SubtitleSearchResult; hasTVPreferredFocus?: boolean; isDownloading?: boolean; onPress: () => void; } export const TVSubtitleResultCard = React.forwardRef< View, TVSubtitleResultCardProps >(({ result, hasTVPreferredFocus, isDownloading, onPress }, ref) => { const typography = useScaledTVTypography(); const styles = createStyles(typography); const { focused, handleFocus, handleBlur, animatedStyle } = useTVFocusAnimation({ scaleAmount: 1.03 }); return ( {/* Provider/Source badge */} {result.providerName} {/* Name */} {result.name} {/* Meta info row */} {/* Format */} {result.format?.toUpperCase()} {/* Rating if available */} {result.communityRating !== undefined && result.communityRating > 0 && ( {result.communityRating.toFixed(1)} )} {/* Download count if available */} {result.downloadCount !== undefined && result.downloadCount > 0 && ( {result.downloadCount.toLocaleString()} )} {/* Flags */} {result.isHashMatch && ( Hash Match )} {result.hearingImpaired && ( )} {result.aiTranslated && ( AI )} {/* Loading indicator when downloading */} {isDownloading && ( )} ); }); const createStyles = (typography: ReturnType) => StyleSheet.create({ resultCard: { width: 220, minHeight: 120, borderRadius: 14, padding: 14, borderWidth: 1, }, providerBadge: { alignSelf: "flex-start", paddingHorizontal: 8, paddingVertical: 3, borderRadius: 6, marginBottom: 8, }, providerText: { fontSize: typography.callout, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.5, }, resultName: { fontSize: typography.callout, fontWeight: "500", marginBottom: 8, lineHeight: 18, }, resultMeta: { flexDirection: "row", alignItems: "center", gap: 12, marginBottom: 8, }, resultMetaText: { fontSize: typography.callout, }, ratingContainer: { flexDirection: "row", alignItems: "center", gap: 3, }, downloadCountContainer: { flexDirection: "row", alignItems: "center", gap: 3, }, flagsContainer: { flexDirection: "row", gap: 6, flexWrap: "wrap", }, flag: { paddingHorizontal: 6, paddingVertical: 2, borderRadius: 4, }, flagText: { fontSize: typography.callout, fontWeight: "600", color: "#fff", }, downloadingOverlay: { ...StyleSheet.absoluteFillObject, backgroundColor: "rgba(0,0,0,0.5)", borderRadius: 14, justifyContent: "center", alignItems: "center", }, });