From 9eeff2cc5ca6c05dee8c191f33dbbb4b7a4bd482 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 8 Jan 2024 15:47:25 -0600 Subject: Splash: reduce motion + dark mode (#2448) * Don't use mask for android at all * Handle reduced motion * Add dark splash * Add dark config * Fix android version code --------- Co-authored-by: Paul Frazee --- src/Splash.tsx | 164 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 57 deletions(-) (limited to 'src/Splash.tsx') diff --git a/src/Splash.tsx b/src/Splash.tsx index d3b21dd63..bb2c7a175 100644 --- a/src/Splash.tsx +++ b/src/Splash.tsx @@ -1,5 +1,11 @@ import React, {useCallback, useEffect} from 'react' -import {View, StyleSheet, Image as RNImage} from 'react-native' +import { + View, + StyleSheet, + Image as RNImage, + AccessibilityInfo, + useColorScheme, +} from 'react-native' import * as SplashScreen from 'expo-splash-screen' import {Image} from 'expo-image' import Animated, { @@ -15,10 +21,17 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context' import Svg, {Path, SvgProps} from 'react-native-svg' import {isAndroid} from '#/platform/detection' +import {useColorMode} from 'state/shell' +import {colors} from '#/lib/styles' // @ts-ignore import splashImagePointer from '../assets/splash.png' +// @ts-ignore +import darkSplashImagePointer from '../assets/splash-dark.png' const splashImageUri = RNImage.resolveAssetSource(splashImagePointer).uri +const darkSplashImageUri = RNImage.resolveAssetSource( + darkSplashImagePointer, +).uri export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { const width = 1000 @@ -29,9 +42,9 @@ export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { // @ts-ignore it's fiiiiine ref={ref} viewBox="0 0 64 66" - style={{width, height}}> + style={[{width, height}, props.style]}> @@ -53,7 +66,19 @@ export function Splash(props: React.PropsWithChildren) { const [isAnimationComplete, setIsAnimationComplete] = React.useState(false) const [isImageLoaded, setIsImageLoaded] = React.useState(false) const [isLayoutReady, setIsLayoutReady] = React.useState(false) - const isReady = props.isReady && isImageLoaded && isLayoutReady + const [reduceMotion, setReduceMotion] = React.useState( + false, + ) + const isReady = + props.isReady && + isImageLoaded && + isLayoutReady && + reduceMotion !== undefined + + const colorMode = useColorMode() + const colorScheme = useColorScheme() + const themeName = colorMode === 'system' ? colorScheme : colorMode + const isDarkMode = themeName === 'dark' const logoAnimation = useAnimatedStyle(() => { return { @@ -73,6 +98,17 @@ export function Splash(props: React.PropsWithChildren) { opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'), } }) + const reducedLogoAnimation = useAnimatedStyle(() => { + return { + transform: [ + { + scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'), + }, + ], + opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'), + } + }) + const logoWrapperAnimation = useAnimatedStyle(() => { return { opacity: interpolate( @@ -137,71 +173,85 @@ export function Splash(props: React.PropsWithChildren) { } }, [onFinish, intro, outroLogo, outroApp, outroAppOpacity, isReady]) + useEffect(() => { + AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion) + }, []) + + const logoAnimations = + reduceMotion === true ? reducedLogoAnimation : logoAnimation + return ( {!isAnimationComplete && ( )} - {isAndroid ? ( - // Use a simple fade on older versions of android (work around a bug) - <> - - {props.children} - - - {!isAnimationComplete && ( - - + {isReady && + (isAndroid || reduceMotion === true ? ( + // Use a simple fade on older versions of android (work around a bug) + <> + + {props.children} - )} - - ) : ( - - + + {!isAnimationComplete && ( + + + + )} + + ) : ( + + + + }> + {!isAnimationComplete && ( + + )} + + {props.children} - }> - {!isAnimationComplete && ( - - )} - - {props.children} - - - )} + + ))} ) } -- cgit 1.4.1