import React from 'react';
import { View, Text, TouchableOpacity, ScrollView, ActivityIndicator, Dimensions } 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 { width } = Dimensions.get('window');
const MENU_WIDTH = Math.min(width * 0.85, 400);
const QualityBadge = ({ quality }: { quality: string | null }) => {
if (!quality) return null;
const qualityNum = parseInt(quality);
let color = '#8B5CF6'; // Default purple
let label = `${quality}p`;
if (qualityNum >= 2160) {
color = '#F59E0B'; // Gold for 4K
label = '4K';
} else if (qualityNum >= 1080) {
color = '#EF4444'; // Red for 1080p
label = 'FHD';
} else if (qualityNum >= 720) {
color = '#10B981'; // Green for 720p
label = 'HD';
}
return (
{label}
);
};
export const SourcesModal: React.FC = ({
showSourcesModal,
setShowSourcesModal,
availableStreams,
currentStreamUrl,
onSelectStream,
isChangingSource = false,
}) => {
const handleClose = () => {
setShowSourcesModal(false);
};
if (!showSourcesModal) return null;
const sortedProviders = Object.entries(availableStreams);
const handleStreamSelect = (stream: Stream) => {
if (stream.url !== currentStreamUrl && (!isChangingSource || isChangingSource === false)) {
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 */}
{/* Side Menu */}
{/* 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}`}
{quality && }
{(stream.size || stream.lang) && (
{stream.size && (
{(stream.size / (1024 * 1024 * 1024)).toFixed(1)} GB
)}
{stream.lang && (
{stream.lang.toUpperCase()}
)}
)}
{isSelected ? (
) : (
)}
);
})}
))
) : (
No sources available
Try searching for different content
)}
>
);
};