diff --git a/app.config.js b/app.config.js index 7528e9010c..6e43ab83f8 100644 --- a/app.config.js +++ b/app.config.js @@ -310,26 +310,24 @@ module.exports = function (_config) { [ 'expo-splash-screen', { - ios: { - enableFullScreenImage_legacy: true, - backgroundColor: '#ffffff', - image: './assets/splash.png', + enableFullScreenImage_legacy: true, // iOS only + backgroundColor: '#EEF5FF', // based on illustration + image: './assets/splash/splash-mobile.png', + resizeMode: 'cover', + dark: { + enableFullScreenImage_legacy: true, // iOS only + backgroundColor: '#446DA9', // based on illustration + image: './assets/splash/splash-mobile-dark.png', resizeMode: 'cover', - dark: { - enableFullScreenImage_legacy: true, - backgroundColor: '#001429', - image: './assets/splash-dark.png', - resizeMode: 'cover', - }, }, android: { - backgroundColor: '#0c7cff', - image: './assets/splash-android-icon.png', - imageWidth: 150, + backgroundColor: '#A8CCFF', // primary_200 + image: './assets/splash/android-splash-logo-white.png', + imageWidth: 105, dark: { - backgroundColor: '#0c2a49', - image: './assets/splash-android-icon-dark.png', - imageWidth: 150, + backgroundColor: '#00398A', // primary_800 + image: './assets/splash/android-splash-logo-white.png', + imageWidth: 105, }, }, }, diff --git a/assets/splash-android-icon-dark.png b/assets/splash-android-icon-dark.png deleted file mode 100644 index c19a01dc6d..0000000000 Binary files a/assets/splash-android-icon-dark.png and /dev/null differ diff --git a/assets/splash-android-icon.png b/assets/splash-android-icon.png deleted file mode 100644 index 280386c900..0000000000 Binary files a/assets/splash-android-icon.png and /dev/null differ diff --git a/assets/splash-dark.png b/assets/splash-dark.png deleted file mode 100644 index 95176b3ff4..0000000000 Binary files a/assets/splash-dark.png and /dev/null differ diff --git a/assets/splash.png b/assets/splash.png deleted file mode 100644 index 05a7392b37..0000000000 Binary files a/assets/splash.png and /dev/null differ diff --git a/assets/splash/android-splash-logo-white.png b/assets/splash/android-splash-logo-white.png new file mode 100644 index 0000000000..b2b570b933 Binary files /dev/null and b/assets/splash/android-splash-logo-white.png differ diff --git a/assets/splash/splash-mobile-dark.png b/assets/splash/splash-mobile-dark.png new file mode 100644 index 0000000000..948a33c11c Binary files /dev/null and b/assets/splash/splash-mobile-dark.png differ diff --git a/assets/splash/splash-mobile.png b/assets/splash/splash-mobile.png new file mode 100644 index 0000000000..4a56835fda Binary files /dev/null and b/assets/splash/splash-mobile.png differ diff --git a/src/Splash.tsx b/src/Splash.tsx index 47e70b375f..7fc09d7ab9 100644 --- a/src/Splash.tsx +++ b/src/Splash.tsx @@ -9,55 +9,30 @@ import { import Animated, { Easing, interpolate, - runOnJS, useAnimatedStyle, useSharedValue, withTiming, } from 'react-native-reanimated' -import {useSafeAreaInsets} from 'react-native-safe-area-context' -import Svg, {Path, type SvgProps} from 'react-native-svg' import {Image} from 'expo-image' import * as SplashScreen from 'expo-splash-screen' -import {Logotype} from '#/view/icons/Logotype' // @ts-ignore -import splashImagePointer from '../assets/splash.png' +import splashImagePointer from '../assets/splash/splash-mobile.png' // @ts-ignore -import darkSplashImagePointer from '../assets/splash-dark.png' +import darkSplashImagePointer from '../assets/splash/splash-mobile-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 - const height = width * (67 / 64) - return ( - - - - ) -}) - type Props = { isReady: boolean } export function Splash(props: React.PropsWithChildren) { 'use no memo' - const insets = useSafeAreaInsets() - const intro = useSharedValue(0) - const outroLogo = useSharedValue(0) - const outroApp = useSharedValue(0) const outroAppOpacity = useSharedValue(0) + const colorScheme = useColorScheme() const [isAnimationComplete, setIsAnimationComplete] = React.useState(false) const [isImageLoaded, setIsImageLoaded] = React.useState(false) const [isLayoutReady, setIsLayoutReady] = React.useState(false) @@ -69,62 +44,10 @@ export function Splash(props: React.PropsWithChildren) { isImageLoaded && isLayoutReady && reduceMotion !== undefined - - const colorScheme = useColorScheme() const isDarkMode = colorScheme === 'dark' - const logoAnimation = useAnimatedStyle(() => { - return { - transform: [ - { - scale: interpolate(intro.get(), [0, 1], [0.8, 1], 'clamp'), - }, - { - scale: interpolate( - outroLogo.get(), - [0, 0.08, 1], - [1, 0.8, 500], - 'clamp', - ), - }, - ], - opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'), - } - }) - const bottomLogoAnimation = useAnimatedStyle(() => { - return { - opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'), - } - }) - const reducedLogoAnimation = useAnimatedStyle(() => { - return { - transform: [ - { - scale: interpolate(intro.get(), [0, 1], [0.8, 1], 'clamp'), - }, - ], - opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'), - } - }) - - const logoWrapperAnimation = useAnimatedStyle(() => { - return { - opacity: interpolate( - outroAppOpacity.get(), - [0, 0.1, 0.2, 1], - [1, 1, 0, 0], - 'clamp', - ), - } - }) - const appAnimation = useAnimatedStyle(() => { return { - transform: [ - { - scale: interpolate(outroApp.get(), [0, 1], [1.1, 1], 'clamp'), - }, - ], opacity: interpolate( outroAppOpacity.get(), [0, 0.1, 0.2, 1], @@ -142,50 +65,21 @@ export function Splash(props: React.PropsWithChildren) { if (isReady) { SplashScreen.hideAsync() .then(() => { - intro.set(() => - withTiming( - 1, - {duration: 400, easing: Easing.out(Easing.cubic)}, - async () => { - // set these values to check animation at specific point - outroLogo.set(() => - withTiming( - 1, - {duration: 1200, easing: Easing.in(Easing.cubic)}, - () => { - runOnJS(onFinish)() - }, - ), - ) - outroApp.set(() => - withTiming(1, { - duration: 1200, - easing: Easing.inOut(Easing.cubic), - }), - ) - outroAppOpacity.set(() => - withTiming(1, { - duration: 1200, - easing: Easing.in(Easing.cubic), - }), - ) - }, - ), + outroAppOpacity.set(() => + withTiming(1, { + duration: 1200, + easing: Easing.in(Easing.cubic), + }), ) }) .catch(() => {}) } - }, [onFinish, intro, outroLogo, outroApp, outroAppOpacity, isReady]) + }, [onFinish, outroAppOpacity, isReady]) useEffect(() => { AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion) }, []) - const logoAnimations = - reduceMotion === true ? reducedLogoAnimation : logoAnimation - // special off-spec color for dark mode - const logoBg = isDarkMode ? '#0F1824' : '#fff' - return ( {!isAnimationComplete && ( @@ -196,22 +90,6 @@ export function Splash(props: React.PropsWithChildren) { source={{uri: isDarkMode ? darkSplashImageUri : splashImageUri}} style={StyleSheet.absoluteFillObject} /> - - - - )} @@ -220,24 +98,6 @@ export function Splash(props: React.PropsWithChildren) { {props.children} - - {!isAnimationComplete && ( - - - - - - )} )} diff --git a/src/view/com/auth/SplashScreen.tsx b/src/view/com/auth/SplashScreen.tsx index 3442d1bdf9..77973ed3d7 100644 --- a/src/view/com/auth/SplashScreen.tsx +++ b/src/view/com/auth/SplashScreen.tsx @@ -1,18 +1,23 @@ -import {View} from 'react-native' +import {useMemo} from 'react' +import {Image as RNImage, View} from 'react-native' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' -import {useSafeAreaInsets} from 'react-native-safe-area-context' +import {Image} from 'expo-image' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useHaptics} from '#/lib/haptics' -import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' -import {CenteredView} from '#/view/com/util/Views' import {Logo} from '#/view/icons/Logo' import {Logotype} from '#/view/icons/Logotype' import {atoms as a, useTheme} from '#/alf' -import {AppLanguageDropdown} from '#/components/AppLanguageDropdown' import {Button, ButtonText} from '#/components/Button' -import {Text} from '#/components/Typography' +// @ts-ignore +import splashImagePointer from '../../../../assets/splash/splash-mobile.png' +// @ts-ignore +import darkSplashImagePointer from '../../../../assets/splash/splash-mobile-dark.png' +const splashImageUri = RNImage.resolveAssetSource(splashImagePointer).uri +const darkSplashImageUri = RNImage.resolveAssetSource( + darkSplashImagePointer, +).uri export const SplashScreen = ({ onPressSignin, @@ -23,38 +28,68 @@ export const SplashScreen = ({ }) => { const t = useTheme() const {_} = useLingui() + const isDarkMode = t.name !== 'light' const playHaptic = useHaptics() - const insets = useSafeAreaInsets() + + const styles = useMemo(() => { + const logoFill = isDarkMode ? 'white' : t.palette.primary_500 + return { + logoFill, + logoShadow: isDarkMode + ? [ + t.atoms.shadow_md, + { + shadowColor: logoFill, + shadowOpacity: 0.5, + shadowOffset: { + width: 0, + height: 0, + }, + }, + ] + : [], + } + }, [t, isDarkMode]) return ( - + <> + + - - - + + + + - - - - - - What's up? - - + + + style={[ + t.atoms.shadow_md, + { + shadowOpacity: 0.1, + shadowOffset: { + width: 0, + height: 5, + }, + }, + ]}> - - - - - - - - + + + - + ) }