import React from 'react'; import { View, Text, TouchableOpacity, Animated, StyleSheet, Platform } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; import Slider from '@react-native-community/slider'; import { styles } from '../utils/playerStyles'; import { getTrackDisplayName } from '../utils/playerUtils'; import { useTheme } from '../../../contexts/ThemeContext'; interface PlayerControlsProps { showControls: boolean; fadeAnim: Animated.Value; paused: boolean; title: string; episodeTitle?: string; season?: number; episode?: number; quality?: string; year?: number; streamProvider?: string; streamName?: string; currentTime: number; duration: number; zoomScale: number; currentResizeMode?: string; ksAudioTracks: Array<{id: number, name: string, language?: string}>; selectedAudioTrack: number | null; availableStreams?: { [providerId: string]: { streams: any[]; addonName: string } }; togglePlayback: () => void; skip: (seconds: number) => void; handleClose: () => void; cycleAspectRatio: () => void; cyclePlaybackSpeed: () => void; setShowAudioModal: (show: boolean) => void; setShowSubtitleModal: (show: boolean) => void; isSubtitleModalOpen?: boolean; setShowSourcesModal?: (show: boolean) => void; // Slider-specific props onSliderValueChange: (value: number) => void; onSlidingStart: () => void; onSlidingComplete: (value: number) => void; buffered: number; formatTime: (seconds: number) => string; playerBackend?: string; } export const PlayerControls: React.FC = ({ showControls, fadeAnim, paused, title, episodeTitle, season, episode, quality, year, streamProvider, streamName, currentTime, duration, zoomScale, currentResizeMode, ksAudioTracks, selectedAudioTrack, availableStreams, togglePlayback, skip, handleClose, cycleAspectRatio, cyclePlaybackSpeed, setShowAudioModal, setShowSubtitleModal, isSubtitleModalOpen, setShowSourcesModal, onSliderValueChange, onSlidingStart, onSlidingComplete, buffered, formatTime, playerBackend, }) => { const { currentTheme } = useTheme(); return ( {/* Progress slider with native iOS slider */} {formatTime(currentTime)} {formatTime(duration)} {/* Controls Overlay */} {/* Top Gradient & Header */} {/* Title Section - Enhanced with metadata */} {title} {/* Show season and episode for series */} {season && episode && ( S{season}E{episode} {episodeTitle && `• ${episodeTitle}`} )} {/* Show year and provider (quality chip removed) */} {year && {year}} {streamName && via {streamName}} {playerBackend && ( {playerBackend} )} {/* Center Controls (Play/Pause, Skip) */} skip(-10)} style={styles.skipButton}> 10 skip(10)} style={styles.skipButton}> 10 {/* Bottom Gradient */} {/* Bottom Buttons Row */} {/* Fill/Cover Button - Updated to show fill/cover modes */} {currentResizeMode ? (currentResizeMode === 'none' ? 'Original' : currentResizeMode.charAt(0).toUpperCase() + currentResizeMode.slice(1)) : (zoomScale === 1.1 ? 'Fill' : 'Cover') } {/* Playback Speed Button */} Speed {/* Audio Button - Updated to use ksAudioTracks */} setShowAudioModal(true)} disabled={ksAudioTracks.length <= 1} > {(() => { const trackName = getTrackDisplayName( ksAudioTracks.find(t => t.id === selectedAudioTrack) || { id: -1, name: 'Default' } ); // Truncate long audio track names to prevent UI cramping const maxLength = 12; // Limit to 12 characters return trackName.length > maxLength ? `${trackName.substring(0, maxLength)}...` : trackName; })()} {/* Subtitle Button - Always available for external subtitle search */} setShowSubtitleModal(!isSubtitleModalOpen)} > Subtitles {/* Change Source Button */} {setShowSourcesModal && ( setShowSourcesModal(true)} > Change Source )} ); }; export default PlayerControls;