An ATproto social media client -- with an independent Appview.

🤫 (#2211)

* Add new assets

* Add splashiness

* Add butter icon, spread it

* Cream together eggs, sugar, and vanilla

* Hi, I'd like to place and order. Yeah, none pizza with left beef, plz.

* test

* Refine animation

* tweak

* tweak

* tweak

* Tweak

* Simplify

* Cleanup

* Fix android logo

---------

Co-authored-by: Ansh Nanda <anshnanda10@gmail.com>

authored by Eric Bailey Ansh Nanda and committed by GitHub 7897dd24 075ffdf5

+6 -3
app.config.js
··· 43 43 icon: './assets/icon.png', 44 44 userInterfaceStyle: 'automatic', 45 45 splash: { 46 - image: './assets/cloud-splash.png', 46 + image: './assets/splash.png', 47 47 resizeMode: 'cover', 48 48 backgroundColor: '#ffffff', 49 49 }, ··· 73 73 }, 74 74 android: { 75 75 versionCode: ANDROID_VERSION_CODE, 76 + icon: './assets/icon.png', 76 77 adaptiveIcon: { 77 - foregroundImage: './assets/adaptive-icon.png', 78 - backgroundColor: '#ffffff', 78 + foregroundImage: './assets/icon-android-foreground.png', 79 + monochromeImage: './assets/icon-android-foreground.png', 80 + backgroundImage: './assets/icon-android-background.png', 81 + backgroundColor: '#1185FE', 79 82 }, 80 83 googleServicesFile: './google-services.json', 81 84 package: 'xyz.blueskyweb.app',
assets/adaptive-icon.png

This is a binary file and will not be displayed.

assets/cloud-splash.png

This is a binary file and will not be displayed.

assets/default-avatar.jpg

This is a binary file and will not be displayed.

assets/default-avatar.png

This is a binary file and will not be displayed.

assets/favicon.png

This is a binary file and will not be displayed.

assets/icon-android-background.png

This is a binary file and will not be displayed.

assets/icon-android-foreground.png

This is a binary file and will not be displayed.

assets/icon.png

This is a binary file and will not be displayed.

assets/splash-with-logo.png

This is a binary file and will not be displayed.

assets/splash.png

This is a binary file and will not be displayed.

assets/tabs-explainer.jpg

This is a binary file and will not be displayed.

+1
package.json
··· 54 54 "@react-native-clipboard/clipboard": "^1.10.0", 55 55 "@react-native-community/blur": "^4.3.0", 56 56 "@react-native-community/datetimepicker": "7.2.0", 57 + "@react-native-masked-view/masked-view": "^0.3.1", 57 58 "@react-native-menu/menu": "^0.8.0", 58 59 "@react-native-picker/picker": "2.4.10", 59 60 "@react-navigation/bottom-tabs": "^6.5.7",
+26 -20
src/App.native.tsx
··· 6 6 import * as SplashScreen from 'expo-splash-screen' 7 7 import {GestureHandlerRootView} from 'react-native-gesture-handler' 8 8 import {QueryClientProvider} from '@tanstack/react-query' 9 + import { 10 + SafeAreaProvider, 11 + initialWindowMetrics, 12 + } from 'react-native-safe-area-context' 9 13 10 14 import 'view/icons' 11 15 ··· 34 38 } from 'state/session' 35 39 import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread' 36 40 import * as persisted from '#/state/persisted' 41 + import {Splash} from '#/Splash' 37 42 38 43 SplashScreen.preventAutoHideAsync() 39 44 ··· 53 58 resumeSession(account) 54 59 }, [resumeSession]) 55 60 56 - // wait for session to resume 57 - if (isInitialLoad) return null 58 - 59 61 return ( 60 - <React.Fragment 61 - // Resets the entire tree below when it changes: 62 - key={currentAccount?.did}> 63 - <LoggedOutViewProvider> 64 - <UnreadNotifsProvider> 65 - <ThemeProvider theme={colorMode}> 66 - {/* All components should be within this provider */} 67 - <RootSiblingParent> 68 - <GestureHandlerRootView style={s.h100pct}> 69 - <TestCtrls /> 70 - <Shell /> 71 - </GestureHandlerRootView> 72 - </RootSiblingParent> 73 - </ThemeProvider> 74 - </UnreadNotifsProvider> 75 - </LoggedOutViewProvider> 76 - </React.Fragment> 62 + <SafeAreaProvider initialMetrics={initialWindowMetrics}> 63 + <Splash isReady={!isInitialLoad}> 64 + <React.Fragment 65 + // Resets the entire tree below when it changes: 66 + key={currentAccount?.did}> 67 + <LoggedOutViewProvider> 68 + <UnreadNotifsProvider> 69 + <ThemeProvider theme={colorMode}> 70 + {/* All components should be within this provider */} 71 + <RootSiblingParent> 72 + <GestureHandlerRootView style={s.h100pct}> 73 + <TestCtrls /> 74 + <Shell /> 75 + </GestureHandlerRootView> 76 + </RootSiblingParent> 77 + </ThemeProvider> 78 + </UnreadNotifsProvider> 79 + </LoggedOutViewProvider> 80 + </React.Fragment> 81 + </Splash> 82 + </SafeAreaProvider> 77 83 ) 78 84 } 79 85
-2
src/Navigation.tsx
··· 1 1 import * as React from 'react' 2 2 import {StyleSheet} from 'react-native' 3 - import * as SplashScreen from 'expo-splash-screen' 4 3 import { 5 4 NavigationContainer, 6 5 createNavigationContainerRef, ··· 493 492 linking={LINKING} 494 493 theme={theme} 495 494 onReady={() => { 496 - SplashScreen.hideAsync() 497 495 logModuleInitTime() 498 496 onReady() 499 497 }}>
+154
src/Splash.tsx
··· 1 + import React, {useCallback, useEffect} from 'react' 2 + import {View, StyleSheet} from 'react-native' 3 + import * as SplashScreen from 'expo-splash-screen' 4 + import LinearGradient from 'react-native-linear-gradient' 5 + import Animated, { 6 + interpolate, 7 + runOnJS, 8 + useAnimatedStyle, 9 + useSharedValue, 10 + withTiming, 11 + Easing, 12 + } from 'react-native-reanimated' 13 + import MaskedView from '@react-native-masked-view/masked-view' 14 + import {useSafeAreaInsets} from 'react-native-safe-area-context' 15 + import Svg, {Path, SvgProps} from 'react-native-svg' 16 + 17 + export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { 18 + const width = 1000 19 + const height = width * (67 / 64) 20 + return ( 21 + <Svg 22 + fill="none" 23 + // @ts-ignore it's fiiiiine 24 + ref={ref} 25 + viewBox="0 0 64 66" 26 + style={{width, height}}> 27 + <Path 28 + fill="#fff" 29 + d="M13.873 3.77C21.21 9.243 29.103 20.342 32 26.3v15.732c0-.335-.13.043-.41.858-1.512 4.414-7.418 21.642-20.923 7.87-7.111-7.252-3.819-14.503 9.125-16.692-7.405 1.252-15.73-.817-18.014-8.93C1.12 22.804 0 8.431 0 6.488 0-3.237 8.579-.18 13.873 3.77ZM50.127 3.77C42.79 9.243 34.897 20.342 32 26.3v15.732c0-.335.13.043.41.858 1.512 4.414 7.418 21.642 20.923 7.87 7.111-7.252 3.819-14.503-9.125-16.692 7.405 1.252 15.73-.817 18.014-8.93C62.88 22.804 64 8.431 64 6.488 64-3.237 55.422-.18 50.127 3.77Z" 30 + /> 31 + </Svg> 32 + ) 33 + }) 34 + 35 + type Props = { 36 + isReady: boolean 37 + } 38 + 39 + SplashScreen.preventAutoHideAsync().catch(() => {}) 40 + 41 + const AnimatedLogo = Animated.createAnimatedComponent(Logo) 42 + 43 + export function Splash(props: React.PropsWithChildren<Props>) { 44 + const insets = useSafeAreaInsets() 45 + const intro = useSharedValue(0) 46 + const outroLogo = useSharedValue(0) 47 + const outroApp = useSharedValue(0) 48 + const [isAnimationComplete, setIsAnimationComplete] = React.useState(false) 49 + 50 + const logoAnimations = useAnimatedStyle(() => { 51 + return { 52 + transform: [ 53 + { 54 + scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'), 55 + }, 56 + { 57 + scale: interpolate( 58 + outroLogo.value, 59 + [0, 0.06, 0.08, 1], 60 + [1, 0.8, 0.8, 800], 61 + 'clamp', 62 + ), 63 + }, 64 + ], 65 + opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'), 66 + } 67 + }) 68 + 69 + const appAnimation = useAnimatedStyle(() => { 70 + return { 71 + transform: [ 72 + { 73 + scale: interpolate( 74 + outroApp.value, 75 + [0, 0.7, 1], 76 + [1.1, 1.1, 1], 77 + 'clamp', 78 + ), 79 + }, 80 + ], 81 + opacity: interpolate(outroApp.value, [0, 0.7, 1], [0, 0, 1], 'clamp'), 82 + } 83 + }) 84 + 85 + const onFinish = useCallback(() => setIsAnimationComplete(true), []) 86 + 87 + useEffect(() => { 88 + if (props.isReady) { 89 + // hide on mount 90 + SplashScreen.hideAsync().catch(() => {}) 91 + 92 + intro.value = withTiming( 93 + 1, 94 + {duration: 200, easing: Easing.out(Easing.cubic)}, 95 + async () => { 96 + outroLogo.value = withTiming( 97 + 1, 98 + {duration: 1200, easing: Easing.in(Easing.cubic)}, 99 + () => { 100 + runOnJS(onFinish)() 101 + }, 102 + ) 103 + outroApp.value = withTiming( 104 + 1, 105 + {duration: 1200, easing: Easing.inOut(Easing.cubic)}, 106 + () => { 107 + runOnJS(onFinish)() 108 + }, 109 + ) 110 + }, 111 + ) 112 + } 113 + }, [onFinish, intro, outroLogo, outroApp, props.isReady]) 114 + 115 + return ( 116 + <View style={{flex: 1}}> 117 + {!isAnimationComplete && ( 118 + <LinearGradient 119 + colors={['#0A7AFF', '#59B9FF']} 120 + style={[StyleSheet.absoluteFillObject]} 121 + /> 122 + )} 123 + 124 + <MaskedView 125 + style={[StyleSheet.absoluteFillObject]} 126 + maskElement={ 127 + <Animated.View 128 + style={[ 129 + StyleSheet.absoluteFillObject, 130 + { 131 + // Transparent background because mask is based off alpha channel. 132 + backgroundColor: 'transparent', 133 + flex: 1, 134 + justifyContent: 'center', 135 + alignItems: 'center', 136 + transform: [{translateY: -(insets.top / 2)}, {scale: 0.1}], // scale from 1000px to 100px 137 + }, 138 + ]}> 139 + <AnimatedLogo style={[logoAnimations]} /> 140 + </Animated.View> 141 + }> 142 + {!isAnimationComplete && ( 143 + <View 144 + style={[StyleSheet.absoluteFillObject, {backgroundColor: 'white'}]} 145 + /> 146 + )} 147 + 148 + <Animated.View style={[{flex: 1}, appAnimation]}> 149 + {props.children} 150 + </Animated.View> 151 + </MaskedView> 152 + </View> 153 + ) 154 + }
+2 -3
src/lib/assets.native.ts
··· 1 1 import {ImageRequireSource} from 'react-native' 2 2 3 - export const DEF_AVATAR: ImageRequireSource = require('../../assets/default-avatar.jpg') 4 - export const TABS_EXPLAINER: ImageRequireSource = require('../../assets/tabs-explainer.jpg') 5 - export const CLOUD_SPLASH: ImageRequireSource = require('../../assets/cloud-splash.png') 3 + export const DEF_AVATAR: ImageRequireSource = require('../../assets/default-avatar.png') 4 + export const CLOUD_SPLASH: ImageRequireSource = require('../../assets/splash.png')
+2 -6
src/lib/assets.ts
··· 1 1 import {ImageRequireSource} from 'react-native' 2 2 3 3 // @ts-ignore we need to pretend -prf 4 - export const DEF_AVATAR: ImageRequireSource = {uri: '/img/default-avatar.jpg'} 5 - // @ts-ignore we need to pretend -prf 6 - export const TABS_EXPLAINER: ImageRequireSource = { 7 - uri: '/img/tabs-explainer.jpg', 8 - } 4 + export const DEF_AVATAR: ImageRequireSource = {uri: '/img/default-avatar.png'} 9 5 // @ts-ignore we need to pretend -prf 10 - export const CLOUD_SPLASH: ImageRequireSource = {uri: '/img/cloud-splash.png'} 6 + export const CLOUD_SPLASH: ImageRequireSource = {uri: '/img/splash.png'}
+11 -5
src/view/com/auth/SplashScreen.tsx
··· 7 7 import {CenteredView} from '../util/Views' 8 8 import {Trans, msg} from '@lingui/macro' 9 9 import {useLingui} from '@lingui/react' 10 + import {Logo} from '#/view/icons/Logo' 11 + import {Logotype} from '#/view/icons/Logotype' 10 12 11 13 export const SplashScreen = ({ 12 14 onPressSignin, ··· 22 24 <CenteredView style={[styles.container, pal.view]}> 23 25 <ErrorBoundary> 24 26 <View style={styles.hero}> 25 - <Text style={[styles.title, pal.link]}> 26 - <Trans>Bluesky</Trans> 27 - </Text> 28 - <Text style={[styles.subtitle, pal.textLight]}> 29 - <Trans>See what's next</Trans> 27 + <Logo width={92} fill="sky" /> 28 + 29 + <View style={{paddingTop: 40, paddingBottom: 6}}> 30 + <Logotype width={161} /> 31 + </View> 32 + 33 + <Text type="lg-medium" style={[pal.textLight]}> 34 + <Trans>What's next?</Trans> 30 35 </Text> 31 36 </View> 32 37 <View testID="signinOrCreateAccount" style={styles.btns}> ··· 65 70 hero: { 66 71 flex: 2, 67 72 justifyContent: 'center', 73 + alignItems: 'center', 68 74 }, 69 75 btns: { 70 76 paddingBottom: 40,
+10 -10
src/view/com/auth/SplashScreen.web.tsx
··· 10 10 import {isWeb} from 'platform/detection' 11 11 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 12 12 import {Trans} from '@lingui/macro' 13 + import {Logo} from '#/view/icons/Logo' 14 + import {Logotype} from '#/view/icons/Logotype' 13 15 14 16 export const SplashScreen = ({ 15 17 onDismiss, ··· 55 57 styles.containerInner, 56 58 isMobileWeb && styles.containerInnerMobile, 57 59 pal.border, 60 + {alignItems: 'center'}, 58 61 ]}> 59 62 <ErrorBoundary> 60 - <Text style={isMobileWeb ? styles.titleMobile : styles.title}> 61 - Bluesky 62 - </Text> 63 - <Text style={isMobileWeb ? styles.subtitleMobile : styles.subtitle}> 64 - See what's next 65 - </Text> 63 + <Logo width={92} fill="sky" /> 64 + 65 + <View style={{paddingTop: 40, paddingBottom: 20}}> 66 + <Logotype width={161} /> 67 + </View> 68 + 66 69 <View testID="signinOrCreateAccount" style={styles.btns}> 67 70 <TouchableOpacity 68 71 testID="createAccountButton" ··· 117 120 ) 118 121 } 119 122 const useStyles = () => { 120 - const {isTabletOrMobile} = useWebMediaQueries() 121 - const isMobileWeb = isWeb && isTabletOrMobile 122 123 return StyleSheet.create({ 123 124 container: { 124 125 height: '100%', ··· 161 162 paddingBottom: 30, 162 163 }, 163 164 btns: { 164 - flexDirection: isMobileWeb ? 'column' : 'row', 165 - gap: 20, 165 + gap: 10, 166 166 justifyContent: 'center', 167 167 paddingBottom: 40, 168 168 },
+5 -8
src/view/com/pager/FeedsTabBarMobile.tsx
··· 3 3 import {TabBar} from 'view/com/pager/TabBar' 4 4 import {RenderTabBarFnProps} from 'view/com/pager/Pager' 5 5 import {usePalette} from 'lib/hooks/usePalette' 6 - import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' 7 6 import {Link} from '../util/Link' 8 - import {Text} from '../util/text/Text' 9 7 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 10 8 import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome' 11 - import {s} from 'lib/styles' 12 9 import {HITSLOP_10} from 'lib/constants' 13 10 import Animated from 'react-native-reanimated' 14 11 import {msg} from '@lingui/macro' ··· 21 18 import {isWeb} from 'platform/detection' 22 19 import {useNavigation} from '@react-navigation/native' 23 20 import {NavigationProp} from 'lib/routes/types' 21 + import {Logo} from '#/view/icons/Logo' 24 22 25 23 export function FeedsTabBar( 26 24 props: RenderTabBarFnProps & {testID?: string; onPressSelected: () => void}, 27 25 ) { 28 26 const pal = usePalette('default') 29 - const {isSandbox, hasSession} = useSession() 27 + const {hasSession} = useSession() 30 28 const {_} = useLingui() 31 29 const setDrawerOpen = useSetDrawerOpen() 32 30 const navigation = useNavigation<NavigationProp>() 33 31 const {feeds, hasPinnedCustom} = usePinnedFeedsInfos() 34 - const brandBlue = useColorSchemeStyle(s.brandBlue, s.blue3) 35 32 const {headerHeight} = useShellLayout() 36 33 const {headerMinimalShellTransform} = useMinimalShellMode() 37 34 const pinnedDisplayNames = hasSession ? feeds.map(f => f.displayName) : [] ··· 86 83 /> 87 84 </TouchableOpacity> 88 85 </View> 89 - <Text style={[brandBlue, s.bold, styles.title]}> 90 - {isSandbox ? 'SANDBOX' : 'Bluesky'} 91 - </Text> 86 + <View> 87 + <Logo width={30} /> 88 + </View> 92 89 <View style={[pal.view, {width: 18}]}> 93 90 {hasSession && ( 94 91 <Link
src/view/icons.ts src/view/icons/index.tsx
+48
src/view/icons/Logo.tsx
··· 1 + import React from 'react' 2 + import Svg, { 3 + Path, 4 + Defs, 5 + LinearGradient, 6 + Stop, 7 + SvgProps, 8 + PathProps, 9 + } from 'react-native-svg' 10 + 11 + import {colors} from '#/lib/styles' 12 + 13 + const ratio = 57 / 64 14 + 15 + type Props = { 16 + fill?: PathProps['fill'] 17 + } & SvgProps 18 + 19 + export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { 20 + const {fill, ...rest} = props 21 + const gradient = fill === 'sky' 22 + const _fill = gradient ? 'url(#sky)' : fill || colors.blue3 23 + // @ts-ignore it's fiiiiine 24 + const size = parseInt(rest.width || 32) 25 + return ( 26 + <Svg 27 + fill="none" 28 + // @ts-ignore it's fiiiiine 29 + ref={ref} 30 + viewBox="0 0 64 57" 31 + {...rest} 32 + style={{width: size, height: size * ratio}}> 33 + {gradient && ( 34 + <Defs> 35 + <LinearGradient id="sky" x1="0" y1="0" x2="0" y2="1"> 36 + <Stop offset="0" stopColor="#0A7AFF" stopOpacity="1" /> 37 + <Stop offset="1" stopColor="#59B9FF" stopOpacity="1" /> 38 + </LinearGradient> 39 + </Defs> 40 + )} 41 + 42 + <Path 43 + fill={_fill} 44 + d="M13.873 3.805C21.21 9.332 29.103 20.537 32 26.55v15.882c0-.338-.13.044-.41.867-1.512 4.456-7.418 21.847-20.923 7.944-7.111-7.32-3.819-14.64 9.125-16.85-7.405 1.264-15.73-.825-18.014-9.015C1.12 23.022 0 8.51 0 6.55 0-3.268 8.579-.182 13.873 3.805ZM50.127 3.805C42.79 9.332 34.897 20.537 32 26.55v15.882c0-.338.13.044.41.867 1.512 4.456 7.418 21.847 20.923 7.944 7.111-7.32 3.819-14.64-9.125-16.85 7.405 1.264 15.73-.825 18.014-9.015C62.88 23.022 64 8.51 64 6.55c0-9.818-8.578-6.732-13.873-2.745Z" 45 + /> 46 + </Svg> 47 + ) 48 + })
+28
src/view/icons/Logotype.tsx
··· 1 + import React from 'react' 2 + import Svg, {Path, SvgProps, PathProps} from 'react-native-svg' 3 + 4 + import {colors} from '#/lib/styles' 5 + 6 + const ratio = 17 / 64 7 + 8 + export function Logotype({ 9 + fill, 10 + ...rest 11 + }: {fill?: PathProps['fill']} & SvgProps) { 12 + // @ts-ignore it's fiiiiine 13 + const size = parseInt(rest.width || 32) 14 + 15 + return ( 16 + <Svg 17 + fill="none" 18 + viewBox="0 0 64 17" 19 + {...rest} 20 + width={size} 21 + height={Number(size) * ratio}> 22 + <Path 23 + fill={fill || colors.black} 24 + d="M8.478 6.252c1.503.538 2.3 1.78 2.3 3.172 0 2.356-1.576 3.785-4.6 3.785H0V0h5.974c2.875 0 4.267 1.466 4.267 3.413 0 1.3-.594 2.245-1.763 2.839Zm-2.69-4.193H2.504v3.45h3.284c1.28 0 1.967-.667 1.967-1.78 0-1.02-.705-1.67-1.967-1.67Zm-3.284 9.072h3.544c1.41 0 2.17-.65 2.17-1.818 0-1.224-.723-1.837-2.17-1.837H2.504v3.655ZM14.251 13.209h-2.337V0h2.337v13.209ZM22.001 8.998V3.636h2.338v9.573h-2.263v-1.392c-.724 1.076-1.726 1.614-3.006 1.614-2.022 0-3.34-1.224-3.34-3.45V3.636h2.338v5.955c0 1.206.594 1.818 1.8 1.818 1.132 0 2.133-.835 2.133-2.411ZM34.979 8.59v.556h-7.161c.167 1.651 1.076 2.467 2.486 2.467 1.076 0 1.8-.463 2.189-1.372h2.244c-.5 1.947-2.17 3.19-4.452 3.19-1.428 0-2.579-.463-3.45-1.372-.872-.91-1.318-2.115-1.318-3.637 0-1.502.427-2.708 1.299-3.636.872-.909 2.004-1.372 3.432-1.372 1.447 0 2.597.482 3.45 1.428.854.946 1.28 2.208 1.28 3.747Zm-4.75-3.358c-1.28 0-2.17.742-2.393 2.281h4.805c-.204-1.391-1.057-2.281-2.411-2.281ZM40.16 13.469c-2.783 0-4.249-1.095-4.379-3.303h2.282c.13 1.188.724 1.633 2.134 1.633 1.261 0 1.892-.39 1.892-1.15 0-.687-.445-1.02-1.874-1.262l-1.094-.185c-2.097-.353-3.136-1.318-3.136-2.894 0-1.8 1.429-2.894 3.97-2.894 2.728 0 4.138 1.075 4.23 3.246h-2.207c-.056-1.169-.742-1.577-2.023-1.577-1.113 0-1.67.371-1.67 1.113 0 .668.483.965 1.596 1.169l1.206.186c2.32.426 3.32 1.28 3.32 2.912 0 1.93-1.557 3.006-4.247 3.006ZM54.667 13.209h-2.671l-2.783-4.453-1.447 1.447v3.006h-2.3V0h2.3v7.606l3.896-3.97h2.783l-3.618 3.618 3.84 5.955ZM60.772 6.048l.78-2.412H64l-3.692 10.352c-.39 1.057-.872 1.818-1.484 2.245-.612.426-1.484.63-2.634.63-.39 0-.724-.018-1.02-.055V14.97h.89c1.057 0 1.577-.65 1.577-1.54 0-.445-.149-1.094-.446-1.929l-2.746-7.866h2.487l.779 2.393c.575 1.8 1.076 3.58 1.521 5.343.408-1.521.928-3.302 1.54-5.324Z" 25 + /> 26 + </Svg> 27 + ) 28 + }
+6 -12
src/view/shell/index.tsx
··· 20 20 import {RoutesContainer, TabsNavigator} from '../../Navigation' 21 21 import {isStateAtTabRoot} from 'lib/routes/helpers' 22 22 import { 23 - SafeAreaProvider, 24 - initialWindowMetrics, 25 - } from 'react-native-safe-area-context' 26 - import { 27 23 useIsDrawerOpen, 28 24 useSetDrawerOpen, 29 25 useIsDrawerSwipeDisabled, ··· 107 103 const pal = usePalette('default') 108 104 const theme = useTheme() 109 105 return ( 110 - <SafeAreaProvider initialMetrics={initialWindowMetrics} style={pal.view}> 111 - <View testID="mobileShellView" style={[styles.outerContainer, pal.view]}> 112 - <StatusBar style={theme.colorScheme === 'dark' ? 'light' : 'dark'} /> 113 - <RoutesContainer> 114 - <ShellInner /> 115 - </RoutesContainer> 116 - </View> 117 - </SafeAreaProvider> 106 + <View testID="mobileShellView" style={[styles.outerContainer, pal.view]}> 107 + <StatusBar style={theme.colorScheme === 'dark' ? 'light' : 'dark'} /> 108 + <RoutesContainer> 109 + <ShellInner /> 110 + </RoutesContainer> 111 + </View> 118 112 ) 119 113 } 120 114
+5
yarn.lock
··· 4448 4448 resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.3.0.tgz#9e558170c106bbafaa1ef502bd8e6d4651012bf9" 4449 4449 integrity sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg== 4450 4450 4451 + "@react-native-masked-view/masked-view@^0.3.1": 4452 + version "0.3.1" 4453 + resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.3.1.tgz#5bd76f17004a6ccbcec03856893777ee91f23d29" 4454 + integrity sha512-uVm8U6nwFIlUd1iDIB5cS+lDadApKR+l8k4k84d9hn+GN4lzAIJhUZ9syYX7c022MxNgAlbxoFLt0pqKoyaAGg== 4455 + 4451 4456 "@react-native-menu/menu@^0.8.0": 4452 4457 version "0.8.0" 4453 4458 resolved "https://registry.yarnpkg.com/@react-native-menu/menu/-/menu-0.8.0.tgz#dbf227c2081e5ffd3d2073ee68ecc84cf8639727"