61 lines
2.8 KiB
TypeScript
61 lines
2.8 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { StyleSheet } from 'react-native';
|
|
import { Video, ResizeMode } from 'expo-av';
|
|
import * as SplashScreen from 'expo-splash-screen';
|
|
import Animated, { FadeOut } from 'react-native-reanimated';
|
|
import { useApp } from '../context/AppContext';
|
|
import { useColors } from '../constants/Colors';
|
|
|
|
interface Props {
|
|
isAppReady: boolean;
|
|
onAnimationComplete: () => void;
|
|
}
|
|
|
|
export function AnimatedSplashScreen({ isAppReady, onAnimationComplete }: Props) {
|
|
const [hasPlayedEnough, setHasPlayedEnough] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Ensure the video plays for at least 2 seconds before we allow it to finish,
|
|
// so it doesn't flash too fast and provides a premium feel.
|
|
const timer = setTimeout(() => {
|
|
setHasPlayedEnough(true);
|
|
}, 2000);
|
|
return () => clearTimeout(timer);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (isAppReady && hasPlayedEnough) {
|
|
onAnimationComplete();
|
|
}
|
|
}, [isAppReady, hasPlayedEnough, onAnimationComplete]);
|
|
|
|
// Determine the background color to blend perfectly
|
|
const { isDarkMode, colorPalette } = useApp();
|
|
const colors = useColors(isDarkMode, colorPalette);
|
|
return (
|
|
<Animated.View exiting={FadeOut.duration(600)} style={[StyleSheet.absoluteFill, { zIndex: 9999, backgroundColor: colors.background, alignItems: 'center', justifyContent: 'center' }]}>
|
|
<Animated.View style={{ width: 220, height: 220, borderRadius: 45, overflow: 'hidden', backgroundColor: colors.surface, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 15, elevation: 8, transform: [{ scale: 1 }] }}>
|
|
<Video
|
|
source={require('../assets/Make_some_light_leaf_animations_delpmaspu_.mp4')}
|
|
style={{ width: '100%', height: '100%' }}
|
|
resizeMode={ResizeMode.COVER}
|
|
shouldPlay
|
|
isMuted
|
|
isLooping
|
|
rate={2.0} // Play at 2x speed to make the 8-second video feel punchier as a loading screen
|
|
onReadyForDisplay={() => {
|
|
// Instantly hide the native static splash screen as soon as the video is painted
|
|
SplashScreen.hideAsync().catch(() => { });
|
|
}}
|
|
onError={(err) => {
|
|
console.error("Video loading error:", err);
|
|
// Fallback in case the video fails to load for any reason
|
|
SplashScreen.hideAsync().catch(() => { });
|
|
onAnimationComplete();
|
|
}}
|
|
/>
|
|
</Animated.View>
|
|
</Animated.View>
|
|
);
|
|
}
|