import { Season, Show } from "@/app/types"; import { FontAwesome } from "@expo/vector-icons"; import React from "react"; import { Dimensions, FlatList, LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, Pressable, StyleSheet, View } from "react-native"; const WINDOW_WIDTH = Dimensions.get("window").width; function clamp(n: number, min: number, max: number) { return Math.max(min, Math.min(max, n)); } export default function SeasonCarousel({ show, seasons, renderItem, }: { show: Show; seasons: Season[]; renderItem: (season: Season) => React.ReactNode; }) { const [currentIndex, setCurrentIndex] = React.useState(0); const [sliderWidth, setSliderWidth] = React.useState(Math.floor(WINDOW_WIDTH - 20)); const listRef = React.useRef | null>(null); const onLayout = (e: LayoutChangeEvent) => { const w = Math.max(0, Math.floor(e.nativeEvent.layout.width)); if (w) setSliderWidth(w); }; const onMomentumEnd = (e: NativeSyntheticEvent) => { const x = e.nativeEvent.contentOffset.x; const index = clamp(Math.round(x / sliderWidth), 0, Math.max(0, seasons.length - 1)); setCurrentIndex(index); }; const scrollTo = (target: number) => { const ref = listRef.current; if (!ref) return; try { ref.scrollToIndex({ index: target, animated: true }); } catch {} }; const goPrev = () => { setCurrentIndex((curr) => { const next = clamp(curr - 1, 0, Math.max(0, seasons.length - 1)); if (next !== curr) setTimeout(() => scrollTo(next), 0); return next; }); }; const goNext = () => { setCurrentIndex((curr) => { const next = clamp(curr + 1, 0, Math.max(0, seasons.length - 1)); if (next !== curr) setTimeout(() => scrollTo(next), 0); return next; }); }; return ( (listRef.current = r)} data={seasons} keyExtractor={(season, idx) => `${show.showId}-${(season as any)?.seasonId ?? `season-${idx}`}`} horizontal pagingEnabled showsHorizontalScrollIndicator={false} snapToAlignment="start" decelerationRate="fast" onMomentumScrollEnd={onMomentumEnd} renderItem={({ item }) => ( {renderItem(item)} )} /> {seasons.length > 1 && ( {seasons.map((_, i) => ( ))} = seasons.length - 1 && carouselStyles.arrowDisabled]} disabled={currentIndex >= seasons.length - 1} hitSlop={8}> )} ); } const carouselStyles = StyleSheet.create({ controls: { paddingHorizontal: 8, width: "100%", flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, dotsRow: { flexDirection: "row", alignItems: "center" }, dot: { width: 6, height: 6, borderRadius: 999, backgroundColor: "#888", opacity: 0.4, marginHorizontal: 3 }, dotActive: { opacity: 1 }, arrowButton: { padding: 6, opacity: 0.9 }, arrowDisabled: { opacity: 0.3 }, });