mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
some ui changes
This commit is contained in:
parent
3a182b5982
commit
99424d37be
1 changed files with 102 additions and 15 deletions
|
|
@ -7,6 +7,7 @@ import {
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
Platform,
|
Platform,
|
||||||
InteractionManager,
|
InteractionManager,
|
||||||
|
StatusBar,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { MaterialIcons } from '@expo/vector-icons';
|
import { MaterialIcons } from '@expo/vector-icons';
|
||||||
import { LinearGradient } from 'expo-linear-gradient';
|
import { LinearGradient } from 'expo-linear-gradient';
|
||||||
|
|
@ -702,6 +703,7 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
const [isTrailerPlaying, setIsTrailerPlaying] = useState(false);
|
const [isTrailerPlaying, setIsTrailerPlaying] = useState(false);
|
||||||
const [trailerReady, setTrailerReady] = useState(false);
|
const [trailerReady, setTrailerReady] = useState(false);
|
||||||
const [trailerPreloaded, setTrailerPreloaded] = useState(false);
|
const [trailerPreloaded, setTrailerPreloaded] = useState(false);
|
||||||
|
const [isTrailerFullscreen, setIsTrailerFullscreen] = useState(false);
|
||||||
const imageOpacity = useSharedValue(1);
|
const imageOpacity = useSharedValue(1);
|
||||||
const imageLoadOpacity = useSharedValue(0);
|
const imageLoadOpacity = useSharedValue(0);
|
||||||
const shimmerOpacity = useSharedValue(0.3);
|
const shimmerOpacity = useSharedValue(0.3);
|
||||||
|
|
@ -745,6 +747,13 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
trailerOpacity.value = withTiming(0, { duration: 300 });
|
trailerOpacity.value = withTiming(0, { duration: 300 });
|
||||||
thumbnailOpacity.value = withTiming(1, { duration: 300 });
|
thumbnailOpacity.value = withTiming(1, { duration: 300 });
|
||||||
}, [trailerOpacity, thumbnailOpacity]);
|
}, [trailerOpacity, thumbnailOpacity]);
|
||||||
|
|
||||||
|
// Handle trailer fullscreen toggle
|
||||||
|
const handleTrailerFullscreenToggle = useCallback(() => {
|
||||||
|
setIsTrailerFullscreen(true);
|
||||||
|
// Hide status bar when entering fullscreen
|
||||||
|
StatusBar.setHidden(true, 'slide');
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Memoized image source
|
// Memoized image source
|
||||||
const imageSource = useMemo(() =>
|
const imageSource = useMemo(() =>
|
||||||
|
|
@ -951,6 +960,9 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
imageLoadOpacity.value = 0;
|
imageLoadOpacity.value = 0;
|
||||||
shimmerOpacity.value = 0.3;
|
shimmerOpacity.value = 0.3;
|
||||||
interactionComplete.current = false;
|
interactionComplete.current = false;
|
||||||
|
|
||||||
|
// Restore status bar when component unmounts
|
||||||
|
StatusBar.setHidden(false, 'slide');
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
@ -968,6 +980,38 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Don't render hero content when trailer is in fullscreen
|
||||||
|
if (isTrailerFullscreen) {
|
||||||
|
return (
|
||||||
|
<View style={styles.fullscreenTrailerContainer}>
|
||||||
|
{/* Back button for fullscreen mode */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.fullscreenBackButton}
|
||||||
|
onPress={() => {
|
||||||
|
setIsTrailerFullscreen(false);
|
||||||
|
// Restore status bar when exiting fullscreen
|
||||||
|
StatusBar.setHidden(false, 'slide');
|
||||||
|
}}
|
||||||
|
activeOpacity={0.7}
|
||||||
|
>
|
||||||
|
<MaterialIcons name="arrow-back" size={28} color="white" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{trailerUrl && (
|
||||||
|
<TrailerPlayer
|
||||||
|
trailerUrl={trailerUrl}
|
||||||
|
autoPlay={true}
|
||||||
|
muted={trailerMuted}
|
||||||
|
style={styles.fullscreenTrailerPlayer}
|
||||||
|
hideLoadingSpinner={false}
|
||||||
|
onLoad={handleTrailerReady}
|
||||||
|
onError={handleTrailerError}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View style={[styles.heroSection, heroAnimatedStyle]}>
|
<Animated.View style={[styles.heroSection, heroAnimatedStyle]}>
|
||||||
{/* Optimized Background */}
|
{/* Optimized Background */}
|
||||||
|
|
@ -1048,21 +1092,32 @@ const HeroSection: React.FC<HeroSectionProps> = memo(({
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
opacity: trailerOpacity
|
opacity: trailerOpacity
|
||||||
}}>
|
}}>
|
||||||
<TouchableOpacity
|
<View style={styles.trailerControlsContainer}>
|
||||||
onPress={() => setTrailerMuted(!trailerMuted)}
|
<TouchableOpacity
|
||||||
activeOpacity={0.7}
|
onPress={() => setTrailerMuted(!trailerMuted)}
|
||||||
style={{
|
activeOpacity={0.7}
|
||||||
padding: 8,
|
style={styles.trailerControlButton}
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
>
|
||||||
borderRadius: 20,
|
<MaterialIcons
|
||||||
}}
|
name={trailerMuted ? 'volume-off' : 'volume-up'}
|
||||||
>
|
size={24}
|
||||||
<MaterialIcons
|
color="white"
|
||||||
name={trailerMuted ? 'volume-off' : 'volume-up'}
|
/>
|
||||||
size={24}
|
</TouchableOpacity>
|
||||||
color="white"
|
|
||||||
/>
|
{/* Fullscreen button */}
|
||||||
</TouchableOpacity>
|
<TouchableOpacity
|
||||||
|
onPress={handleTrailerFullscreenToggle}
|
||||||
|
activeOpacity={0.7}
|
||||||
|
style={styles.trailerControlButton}
|
||||||
|
>
|
||||||
|
<MaterialIcons
|
||||||
|
name="fullscreen"
|
||||||
|
size={24}
|
||||||
|
color="white"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -1173,6 +1228,20 @@ const styles = StyleSheet.create({
|
||||||
backgroundColor: '#000',
|
backgroundColor: '#000',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
|
fullscreenTrailerContainer: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
zIndex: 9999,
|
||||||
|
backgroundColor: '#000',
|
||||||
|
},
|
||||||
|
fullscreenTrailerPlayer: {
|
||||||
|
flex: 1,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
absoluteFill: {
|
absoluteFill: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 0,
|
top: 0,
|
||||||
|
|
@ -1194,6 +1263,15 @@ const styles = StyleSheet.create({
|
||||||
textShadowOffset: { width: 0, height: 2 },
|
textShadowOffset: { width: 0, height: 2 },
|
||||||
textShadowRadius: 3,
|
textShadowRadius: 3,
|
||||||
},
|
},
|
||||||
|
fullscreenBackButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: Platform.OS === 'android' ? 40 : 50,
|
||||||
|
left: isTablet ? 32 : 16,
|
||||||
|
zIndex: 10,
|
||||||
|
padding: 8,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
borderRadius: 20,
|
||||||
|
},
|
||||||
|
|
||||||
heroGradient: {
|
heroGradient: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|
@ -1708,6 +1786,15 @@ const styles = StyleSheet.create({
|
||||||
opacity: 0.8,
|
opacity: 0.8,
|
||||||
marginBottom: 1,
|
marginBottom: 1,
|
||||||
},
|
},
|
||||||
|
trailerControlsContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
gap: 10,
|
||||||
|
},
|
||||||
|
trailerControlButton: {
|
||||||
|
padding: 8,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
borderRadius: 20,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default HeroSection;
|
export default HeroSection;
|
||||||
Loading…
Reference in a new issue