import React from 'react'; import { View, Text, TouchableOpacity, ScrollView, ActivityIndicator, StyleSheet, Platform, useWindowDimensions } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import Animated, { FadeIn, FadeOut, SlideInRight, SlideOutRight, } from 'react-native-reanimated'; import { Stream } from '../../../types/streams'; interface SourcesModalProps { showSourcesModal: boolean; setShowSourcesModal: (show: boolean) => void; availableStreams: { [providerId: string]: { streams: Stream[]; addonName: string } }; currentStreamUrl: string; onSelectStream: (stream: Stream) => void; isChangingSource?: boolean; } const QualityBadge = ({ quality }: { quality: string | null | undefined }) => { if (!quality) return null; const qualityNum = parseInt(quality); let color = '#8B5CF6'; let label = `${quality}p`; if (qualityNum >= 2160) { color = '#F59E0B'; label = '4K'; } else if (qualityNum >= 1080) { color = '#3B82F6'; label = '1080p'; } else if (qualityNum >= 720) { color = '#10B981'; label = '720p'; } return ( {label} ); }; export const SourcesModal: React.FC = ({ showSourcesModal, setShowSourcesModal, availableStreams, currentStreamUrl, onSelectStream, isChangingSource = false, }) => { const { width } = useWindowDimensions(); const MENU_WIDTH = Math.min(width * 0.85, 400); const handleClose = () => { setShowSourcesModal(false); }; if (!showSourcesModal) return null; const sortedProviders = Object.entries(availableStreams); const handleStreamSelect = (stream: Stream) => { if (stream.url !== currentStreamUrl && !isChangingSource) { onSelectStream(stream); } }; const getQualityFromTitle = (title?: string): string | null => { if (!title) return null; const match = title.match(/(\d+)p/); return match ? match[1] : null; }; const isStreamSelected = (stream: Stream): boolean => { return stream.url === currentStreamUrl; }; return ( {/* Backdrop */} {/* Header */} Change Source {isChangingSource && ( Switching source... )} {sortedProviders.length > 0 ? ( sortedProviders.map(([providerId, providerData]) => ( {providerData.addonName} ({providerData.streams.length}) {providerData.streams.map((stream, index) => { const isSelected = isStreamSelected(stream); const quality = getQualityFromTitle(stream.title) || stream.quality; return ( handleStreamSelect(stream)} activeOpacity={0.7} disabled={isChangingSource === true} > {stream.title || stream.name || `Stream ${index + 1}`} {(stream.size || stream.lang) && ( {stream.size && ( {(stream.size / (1024 * 1024 * 1024)).toFixed(1)} GB )} {stream.lang && ( {stream.lang.toUpperCase()} )} )} {isSelected ? ( ) : ( )} ); })} )) ) : ( No sources found )} ); }; export default SourcesModal;