diff --git a/app.config.js b/app.config.js index f2403edd47..4f2780feb1 100644 --- a/app.config.js +++ b/app.config.js @@ -66,6 +66,12 @@ module.exports = function () { 'Used for profile pictures, posts, and other kinds of content', }, associatedDomains: ['applinks:bsky.app', 'applinks:staging.bsky.app'], + splash: { + dark: { + image: './assets/splash-dark.png', + backgroundColor: '#001429', + }, + }, }, androidStatusBar: { barStyle: 'dark-content', @@ -95,6 +101,12 @@ module.exports = function () { category: ['BROWSABLE', 'DEFAULT'], }, ], + splash: { + dark: { + image: './assets/splash-dark.png', + backgroundColor: '#001429', + }, + }, }, web: { favicon: './assets/favicon.png', diff --git a/assets/splash-dark.png b/assets/splash-dark.png new file mode 100644 index 0000000000..6425bf28a1 Binary files /dev/null and b/assets/splash-dark.png differ diff --git a/src/Splash.tsx b/src/Splash.tsx index d3b21dd630..bb2c7a1757 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} - + {isReady && + (isAndroid || reduceMotion === true ? ( + // Use a simple fade on older versions of android (work around a bug) + <> + + {props.children} + - {!isAnimationComplete && ( - - + {!isAnimationComplete && ( + + + + )} + + ) : ( + + + + }> + {!isAnimationComplete && ( + + )} + + {props.children} - )} - - ) : ( - - - - }> - {!isAnimationComplete && ( - - )} - - {props.children} - - - )} + + ))} ) }