diff --git a/src/components/player/android/components/PauseOverlay.tsx b/src/components/player/android/components/PauseOverlay.tsx deleted file mode 100644 index ad7fdbb74..000000000 --- a/src/components/player/android/components/PauseOverlay.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React, { useState, useRef } from 'react'; -import { View, Text, TouchableOpacity, ScrollView, Animated, StyleSheet } from 'react-native'; -import { LinearGradient } from 'expo-linear-gradient'; -import FastImage from '@d11/react-native-fast-image'; -import { MaterialIcons } from '@expo/vector-icons'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; - -interface PauseOverlayProps { - visible: boolean; - onClose: () => void; - title: string; - episodeTitle?: string; - season?: number; - episode?: number; - year?: string | number; - type: string; - description: string; - cast: any[]; - screenDimensions: { width: number, height: number }; -} - -export const PauseOverlay: React.FC = ({ - visible, - onClose, - title, - episodeTitle, - season, - episode, - year, - type, - description, - cast, - screenDimensions -}) => { - const insets = useSafeAreaInsets(); - - // Internal Animation State - const pauseOverlayOpacity = useRef(new Animated.Value(visible ? 1 : 0)).current; - const pauseOverlayTranslateY = useRef(new Animated.Value(12)).current; - const metadataOpacity = useRef(new Animated.Value(1)).current; - const metadataScale = useRef(new Animated.Value(1)).current; - - // Cast Details State - const [selectedCastMember, setSelectedCastMember] = useState(null); - const [showCastDetails, setShowCastDetails] = useState(false); - const castDetailsOpacity = useRef(new Animated.Value(0)).current; - const castDetailsScale = useRef(new Animated.Value(0.95)).current; - - React.useEffect(() => { - Animated.timing(pauseOverlayOpacity, { - toValue: visible ? 1 : 0, - duration: 250, - useNativeDriver: true - }).start(); - }, [visible]); - - if (!visible && !showCastDetails) return null; - - return ( - - - {/* Horizontal Fade */} - - - - - - - {showCastDetails && selectedCastMember ? ( - - - { - Animated.parallel([ - Animated.timing(castDetailsOpacity, { toValue: 0, duration: 250, useNativeDriver: true }), - Animated.timing(castDetailsScale, { toValue: 0.95, duration: 250, useNativeDriver: true }) - ]).start(() => { - setShowCastDetails(false); - setSelectedCastMember(null); - Animated.parallel([ - Animated.timing(metadataOpacity, { toValue: 1, duration: 400, useNativeDriver: true }), - Animated.spring(metadataScale, { toValue: 1, tension: 80, friction: 8, useNativeDriver: true }) - ]).start(); - }); - }} - > - - Back to details - - - - {selectedCastMember.profile_path && ( - - - - )} - - - {selectedCastMember.name} - - {selectedCastMember.character && ( - - as {selectedCastMember.character} - - )} - {selectedCastMember.biography && ( - - {selectedCastMember.biography} - - )} - - - - - ) : ( - - - You're watching - - {title} - - {!!year && ( - - {`${year}${type === 'series' && season && episode ? ` • S${season}E${episode}` : ''}`} - - )} - {!!episodeTitle && ( - - {episodeTitle} - - )} - {description && ( - - {description} - - )} - {cast && cast.length > 0 && ( - - Cast - - {cast.slice(0, 6).map((castMember: any, index: number) => ( - { - setSelectedCastMember(castMember); - Animated.parallel([ - Animated.timing(metadataOpacity, { toValue: 0, duration: 250, useNativeDriver: true }), - Animated.timing(metadataScale, { toValue: 0.95, duration: 250, useNativeDriver: true }) - ]).start(() => { - setShowCastDetails(true); - Animated.parallel([ - Animated.timing(castDetailsOpacity, { toValue: 1, duration: 400, useNativeDriver: true }), - Animated.spring(castDetailsScale, { toValue: 1, tension: 80, friction: 8, useNativeDriver: true }) - ]).start(); - }); - }} - > - - {castMember.name} - - - ))} - - - )} - - - )} - - - - ); -}; diff --git a/src/components/player/android/components/SpeedActivatedOverlay.tsx b/src/components/player/android/components/SpeedActivatedOverlay.tsx deleted file mode 100644 index 54ad9faa2..000000000 --- a/src/components/player/android/components/SpeedActivatedOverlay.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import { View, Text, Animated, StyleSheet } from 'react-native'; -import { MaterialIcons } from '@expo/vector-icons'; -import { styles } from '../../utils/playerStyles'; - -interface SpeedActivatedOverlayProps { - visible: boolean; - opacity: Animated.Value; - speed: number; -} - -export const SpeedActivatedOverlay: React.FC = ({ - visible, - opacity, - speed -}) => { - if (!visible) return null; - - return ( - - - - {speed}x Speed - - - ); -}; diff --git a/src/components/player/ios/components/PauseOverlay.tsx b/src/components/player/ios/components/PauseOverlay.tsx deleted file mode 100644 index 932089a0e..000000000 --- a/src/components/player/ios/components/PauseOverlay.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React, { useState, useRef } from 'react'; -import { View, Text, TouchableOpacity, Animated, StyleSheet } from 'react-native'; -import { LinearGradient } from 'expo-linear-gradient'; -import FastImage from '@d11/react-native-fast-image'; -import { MaterialIcons } from '@expo/vector-icons'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; - -interface PauseOverlayProps { - visible: boolean; - onClose: () => void; - title: string; - episodeTitle?: string; - season?: number; - episode?: number; - year?: string | number; - type: string; - description: string; - cast: any[]; - screenDimensions: { width: number, height: number }; -} - -export const PauseOverlay: React.FC = ({ - visible, - onClose, - title, - episodeTitle, - season, - episode, - year, - type, - description, - cast, - screenDimensions -}) => { - const insets = useSafeAreaInsets(); - - // Internal Animation State - const pauseOverlayOpacity = useRef(new Animated.Value(visible ? 1 : 0)).current; - const pauseOverlayTranslateY = useRef(new Animated.Value(12)).current; - const metadataOpacity = useRef(new Animated.Value(1)).current; - const metadataScale = useRef(new Animated.Value(1)).current; - - // Cast Details State - const [selectedCastMember, setSelectedCastMember] = useState(null); - const [showCastDetails, setShowCastDetails] = useState(false); - const castDetailsOpacity = useRef(new Animated.Value(0)).current; - const castDetailsScale = useRef(new Animated.Value(0.95)).current; - - React.useEffect(() => { - Animated.timing(pauseOverlayOpacity, { - toValue: visible ? 1 : 0, - duration: 250, - useNativeDriver: true - }).start(); - }, [visible]); - - if (!visible && !showCastDetails) return null; - - return ( - - - {/* Horizontal Fade */} - - - - - - - {showCastDetails && selectedCastMember ? ( - - - { - Animated.parallel([ - Animated.timing(castDetailsOpacity, { toValue: 0, duration: 250, useNativeDriver: true }), - Animated.timing(castDetailsScale, { toValue: 0.95, duration: 250, useNativeDriver: true }) - ]).start(() => { - setShowCastDetails(false); - setSelectedCastMember(null); - Animated.parallel([ - Animated.timing(metadataOpacity, { toValue: 1, duration: 400, useNativeDriver: true }), - Animated.spring(metadataScale, { toValue: 1, tension: 80, friction: 8, useNativeDriver: true }) - ]).start(); - }); - }} - > - - Back to details - - - - {selectedCastMember.profile_path && ( - - - - )} - - - {selectedCastMember.name} - - {selectedCastMember.character && ( - - as {selectedCastMember.character} - - )} - {selectedCastMember.biography && ( - - {selectedCastMember.biography} - - )} - - - - - ) : ( - - - You're watching - - {title} - - {!!year && ( - - {`${year}${type === 'series' && season && episode ? ` • S${season}E${episode}` : ''}`} - - )} - {!!episodeTitle && ( - - {episodeTitle} - - )} - {description && ( - - {description} - - )} - {cast && cast.length > 0 && ( - - Cast - - {cast.slice(0, 6).map((castMember: any, index: number) => ( - { - setSelectedCastMember(castMember); - Animated.parallel([ - Animated.timing(metadataOpacity, { toValue: 0, duration: 250, useNativeDriver: true }), - Animated.timing(metadataScale, { toValue: 0.95, duration: 250, useNativeDriver: true }) - ]).start(() => { - setShowCastDetails(true); - Animated.parallel([ - Animated.timing(castDetailsOpacity, { toValue: 1, duration: 400, useNativeDriver: true }), - Animated.spring(castDetailsScale, { toValue: 1, tension: 80, friction: 8, useNativeDriver: true }) - ]).start(); - }); - }} - > - - {castMember.name} - - - ))} - - - )} - - - )} - - - - ); -}; diff --git a/src/components/player/ios/components/SpeedActivatedOverlay.tsx b/src/components/player/ios/components/SpeedActivatedOverlay.tsx deleted file mode 100644 index b8353644c..000000000 --- a/src/components/player/ios/components/SpeedActivatedOverlay.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import { View, Text, Animated } from 'react-native'; -import { MaterialIcons } from '@expo/vector-icons'; -import { styles } from '../../utils/playerStyles'; - -interface SpeedActivatedOverlayProps { - visible: boolean; - opacity: Animated.Value; - speed: number; -} - -export const SpeedActivatedOverlay: React.FC = ({ - visible, - opacity, - speed -}) => { - if (!visible) return null; - - return ( - - - - {speed}x Speed - - - ); -}; diff --git a/src/components/player/overlays/ParentalGuideOverlay.tsx b/src/components/player/overlays/ParentalGuideOverlay.tsx index 186d52017..a1981e42c 100644 --- a/src/components/player/overlays/ParentalGuideOverlay.tsx +++ b/src/components/player/overlays/ParentalGuideOverlay.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from 'react'; -import { View, Text, StyleSheet } from 'react-native'; +import { View, Text, StyleSheet, Dimensions } from 'react-native'; import Animated, { useSharedValue, useAnimatedStyle, @@ -10,6 +10,7 @@ import Animated, { } from 'react-native-reanimated'; import { parentalGuideService } from '../../../services/parentalGuideService'; import { logger } from '../../../utils/logger'; +import { useTheme } from '../../../contexts/ThemeContext'; interface ParentalGuideOverlayProps { imdbId: string | undefined; @@ -42,16 +43,17 @@ const ROW_HEIGHT = 18; const WarningItemView: React.FC<{ item: WarningItem; opacity: SharedValue; -}> = ({ item, opacity }) => { + fontSize: number; +}> = ({ item, opacity, fontSize }) => { const animatedStyle = useAnimatedStyle(() => ({ opacity: opacity.value, })); return ( - {item.label} - · - {item.severity} + {item.label} + · + {item.severity} ); }; @@ -63,6 +65,8 @@ export const ParentalGuideOverlay: React.FC = ({ episode, shouldShow, }) => { + const { currentTheme } = useTheme(); + const screenWidth = Dimensions.get('window').width; const [warnings, setWarnings] = useState([]); const [isVisible, setIsVisible] = useState(false); const hasShownRef = useRef(false); @@ -222,10 +226,15 @@ export const ParentalGuideOverlay: React.FC = ({ return null; } + // Responsive sizing + const fontSize = Math.min(11, screenWidth * 0.014); + const lineWidth = Math.min(3, screenWidth * 0.0038); + const containerPadding = Math.min(20, screenWidth * 0.025); + return ( - + {/* Vertical line - animates height */} - + {/* Warning items */} @@ -234,6 +243,7 @@ export const ParentalGuideOverlay: React.FC = ({ key={item.label} item={item} opacity={itemOpacities[index]} + fontSize={fontSize} /> ))} @@ -244,15 +254,11 @@ export const ParentalGuideOverlay: React.FC = ({ const styles = StyleSheet.create({ container: { position: 'absolute', - top: 50, - left: 16, flexDirection: 'row', alignItems: 'flex-start', zIndex: 100, }, line: { - width: 2, - backgroundColor: 'rgba(255, 255, 255, 0.5)', borderRadius: 1, marginRight: 10, },