import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; import { Animated, Easing, LayoutAnimation, Platform, StyleSheet, UIManager, View, } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; import { SkeletonTypes } from './types'; import { Colors, Styles } from '../Consts'; import styles from './styles'; import { ScreenContext, SkeletonContext } from '../Context'; const Skeleton: React.FC = ({ style }) => { const screen = useContext(ScreenContext); const [width, setWidth] = useState(0); const PRIMARY_COLOR = Colors.black_05; const HIGHLIGHT_COLOR1 = Colors.black_05; const HIGHLIGHT_COLOR2 = Colors.black_03; const beginShimmerPosition = useRef(new Animated.Value(0)).current; const shimmerColors = [HIGHLIGHT_COLOR1, HIGHLIGHT_COLOR2, HIGHLIGHT_COLOR1]; const linearTranslate = beginShimmerPosition.interpolate({ inputRange: [0, 1], outputRange: [-width, width], }); const animatedValue = useMemo(() => { return Animated.loop( Animated.timing(beginShimmerPosition, { toValue: 1, duration: 1000, easing: Easing.linear, useNativeDriver: Platform.OS !== 'web', }), ); }, [beginShimmerPosition]); useEffect(() => { animatedValue.start(); screen?.onLoading?.(true); return () => { animatedValue.stop(); screen?.onLoading?.(false); }; }, [animatedValue, screen]); const onLayout = (newWidth: number) => { if (newWidth !== width) { setWidth(newWidth); } }; return ( onLayout(e.nativeEvent.layout.width)} style={[Styles.flex, { backgroundColor: PRIMARY_COLOR }]} > ); }; const SkeletonProvider: React.FC<{ loading: boolean; children: any }> = ({ loading = true, children, }) => { const [previous, setPrevious] = useState(loading); useEffect(() => { if (previous !== loading) { if (Platform.OS === 'android') { if (UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } } LayoutAnimation.configureNext({ duration: 500, create: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.opacity, }, }); setPrevious(loading); } }, [loading, previous]); return ( {children} ); }; export { Skeleton, SkeletonProvider };