mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-23 01:01:27 +00:00
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
// 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; |