POWR/components/VideoSplashScreen.tsx

102 lines
2.9 KiB
TypeScript
Raw Permalink Normal View History

// components/VideoSplashScreen.tsx
import React, { useEffect, useRef, useState } from 'react';
import { View, StyleSheet, ActivityIndicator } from 'react-native';
import { Video, ResizeMode, AVPlaybackStatus } from 'expo-av';
import * as SplashScreen from 'expo-splash-screen';
// Keep the splash screen visible while we fetch resources
SplashScreen.preventAutoHideAsync();
interface VideoSplashScreenProps {
onFinish: () => void;
}
const VideoSplashScreen: React.FC<VideoSplashScreenProps> = ({ onFinish }) => {
const videoRef = useRef<Video>(null);
const [isVideoLoaded, setIsVideoLoaded] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// Hide the native splash screen once our component is ready
if (isVideoLoaded) {
console.log('Video loaded, hiding native splash screen');
SplashScreen.hideAsync().catch(e => console.log('Error hiding splash screen:', e));
}
}, [isVideoLoaded]);
const handleVideoLoad = () => {
console.log('Video loaded successfully');
setIsVideoLoaded(true);
// Start playing the video once it's loaded
videoRef.current?.playAsync().catch(e => {
console.error('Error playing video:', e);
// If video fails to play, just call onFinish
onFinish();
});
};
const handleVideoError = (error: string) => {
console.error('Video error:', error);
setError(error);
// On error, skip the video and move to the app
onFinish();
};
const handlePlaybackStatusUpdate = (status: AVPlaybackStatus) => {
// Type-safe handling of playback status
if (!status.isLoaded) {
// Handle error state
if (status.error) {
handleVideoError(`Video error: ${status.error}`);
}
return;
}
// When video finishes playing, call the onFinish callback
if (status.didJustFinish) {
console.log('Video finished playing');
onFinish();
}
};
return (
<View style={styles.container}>
<Video
ref={videoRef}
source={require('../assets/splash.mov')}
style={styles.video}
resizeMode={ResizeMode.COVER}
onLoad={handleVideoLoad}
onError={(error) => handleVideoError(error.toString())}
onPlaybackStatusUpdate={handlePlaybackStatusUpdate}
shouldPlay={false} // We'll play it manually after load
progressUpdateIntervalMillis={50} // More frequent updates
/>
{!isVideoLoaded && (
<View style={styles.loaderContainer}>
<ActivityIndicator size="large" color="#ffffff" />
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000',
},
video: {
flex: 1,
width: '100%',
height: '100%',
},
loaderContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
});
export default VideoSplashScreen;