@fto-consult/expo-ui
Version:
Bibliothèque de composants UI Expo,react-native
132 lines (126 loc) • 4.48 kB
JavaScript
/* @flow */
/*** fork of https://www.npmjs.com/package/react-native-animated-splash-screen */
import PropTypes from "prop-types"
import React from "$react"
import {Animated, StyleSheet } from "react-native";
import View from "$ecomponents/View";
import {isNativeMobile} from "$cplatform";
import {defaultDecimal} from "$cutils";
import {LogoProgress} from "$ecomponents/Logo";
import { Portal } from "react-native-paper";
import {defaultStr} from "$cutils";
import styles, {
_solidBackground,
_staticBackground,
_dynamicLogoStyle,
_dynamicCustomComponentStyle,
_dynamicImageBackground,
_dynamicBackgroundOpacity,
} from "./styles"
import {useAppComponent} from "$econtext/hooks";
const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,logoHeight,backgroundColor,imageBackgroundSource,imageBackgroundResizeMode,
testID})=>{
const [state,setState] = React.useState({
animationDone: false,
loadingProgress: new Animated.Value(0),
});
const { loadingProgress, animationDone} = state;
const prevIsLoaded = React.usePrevious(isLoaded);
const timerRef = React.useRef(null);
React.useEffect(()=>{
if(isLoaded && !prevIsLoaded){
Animated.timing(loadingProgress, {
toValue: 100,
duration: duration || 100,
delay: delay || 0,
useNativeDriver: isNativeMobile(),
}).start(() => {
setState({
...state,
animationDone:true,
})
})
} else if(isLoaded){
clearTimeout(timerRef.current);
timerRef.current = setTimeout(()=>{
if(isLoaded && !animationDone){
setState({...state,animationDone:true});
}
clearTimeout(timerRef.current);
},delay|2000);
}
},[isLoaded,prevIsLoaded,animationDone]);
testID = defaultStr(testID,"RN_SplashscreenComponent")
logoWidth = defaultDecimal(logoWidth,150);
logoHeight = defaultDecimal(logoHeight,250);
const Component = useAppComponent("SplashScreen");
const logoScale = {
transform: [
{
scale: loadingProgress.interpolate({
inputRange: [0, 10, 100],
outputRange: [1, 0.8, 10],
}),
},
],
}
const logoOpacity = {
opacity: loadingProgress.interpolate({
inputRange: [0, 20, 100],
outputRange: [1, 0, 0],
extrapolate: "clamp",
}),
}
if(isLoaded && animationDone){
return React.isValidElement(children)?children:null;
}
return <>
{!animationDone || !isLoaded ? <Portal>
<View style={[styles.container,{backgroundColor}]} testID={testID} id={testID}>
{<View style={[StyleSheet.absoluteFill,{backgroundColor}]} testID={testID+"_Animation"}/>}
<View style={styles.containerGlue} testID={testID+"_ContainerGlue"}>
{(
<Animated.View
style={_staticBackground(logoOpacity, backgroundColor)}
testID={testID+"_AnimationDone"}
/>
)}
{(
React.isComponent(Component)? <Component testID={testID+"_CustomSplashComponent"}/> :
<View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill,{backgroundColor}, styles.logoStyle]}>
<Animated.View
testID={testID+"_Logo"}
style={_dynamicCustomComponentStyle(
logoScale,
logoOpacity,
logoWidth,
logoHeight
)}>
{<LogoProgress />}
</Animated.View>
</View>
)}
</View>
</View>
</Portal> : null}
</>
}
SplashScreenComponent.propTypes = {
preload: PropTypes.bool,
logoWidth: PropTypes.number,
children: PropTypes.element,
logoHeight: PropTypes.number,
backgroundColor: PropTypes.string,
isLoaded: PropTypes.bool.isRequired,
disableBackgroundImage: PropTypes.bool,
logoImage: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
disableAppScale: PropTypes.bool,
duration: PropTypes.number,
delay: PropTypes.number,
}
SplashScreenComponent.displayName = "SplashScreenComponent";
export default SplashScreenComponent;