mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at samuel/exp-cli 242 lines 10 kB view raw
1import '#/logger/sentry/setup' 2import '#/logger/bitdrift/setup' 3import '#/view/icons' 4 5import React, {useEffect, useState} from 'react' 6import {GestureHandlerRootView} from 'react-native-gesture-handler' 7import {RootSiblingParent} from 'react-native-root-siblings' 8import { 9 initialWindowMetrics, 10 SafeAreaProvider, 11} from 'react-native-safe-area-context' 12import * as ScreenOrientation from 'expo-screen-orientation' 13import * as SplashScreen from 'expo-splash-screen' 14import * as SystemUI from 'expo-system-ui' 15import {msg} from '@lingui/macro' 16import {useLingui} from '@lingui/react' 17import * as Sentry from '@sentry/react-native' 18 19import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController' 20import {QueryProvider} from '#/lib/react-query' 21import {Provider as StatsigProvider, tryFetchGates} from '#/lib/statsig/statsig' 22import {s} from '#/lib/styles' 23import {ThemeProvider} from '#/lib/ThemeContext' 24import I18nProvider from '#/locale/i18nProvider' 25import {logger} from '#/logger' 26import {isAndroid, isIOS} from '#/platform/detection' 27import {Provider as A11yProvider} from '#/state/a11y' 28import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes' 29import {Provider as DialogStateProvider} from '#/state/dialogs' 30import {listenSessionDropped} from '#/state/events' 31import { 32 beginResolveGeolocation, 33 ensureGeolocationResolved, 34 Provider as GeolocationProvider, 35} from '#/state/geolocation' 36import {Provider as HomeBadgeProvider} from '#/state/home-badge' 37import {Provider as InvitesStateProvider} from '#/state/invites' 38import {Provider as LightboxStateProvider} from '#/state/lightbox' 39import {MessagesProvider} from '#/state/messages' 40import {Provider as ModalStateProvider} from '#/state/modals' 41import {init as initPersistedState} from '#/state/persisted' 42import {Provider as PrefsStateProvider} from '#/state/preferences' 43import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' 44import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts' 45import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread' 46import {Provider as ServiceAccountManager} from '#/state/service-config' 47import { 48 Provider as SessionProvider, 49 type SessionAccount, 50 useSession, 51 useSessionApi, 52} from '#/state/session' 53import {readLastActiveAccount} from '#/state/session/util' 54import {Provider as ShellStateProvider} from '#/state/shell' 55import {Provider as ComposerProvider} from '#/state/shell/composer' 56import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out' 57import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide' 58import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' 59import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' 60import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' 61import {TestCtrls} from '#/view/com/testing/TestCtrls' 62import * as Toast from '#/view/com/util/Toast' 63import {Shell} from '#/view/shell' 64import {ThemeProvider as Alf} from '#/alf' 65import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 66import {Provider as ContextMenuProvider} from '#/components/ContextMenu' 67import {NuxDialogs} from '#/components/dialogs/nuxs' 68import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 69import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' 70import {Provider as PortalProvider} from '#/components/Portal' 71import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' 72import {Splash} from '#/Splash' 73import {BottomSheetProvider} from '../modules/bottom-sheet' 74import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' 75import {Provider as HideBottomBarBorderProvider} from './lib/hooks/useHideBottomBarBorder' 76 77SplashScreen.preventAutoHideAsync() 78if (isIOS) { 79 SystemUI.setBackgroundColorAsync('black') 80} 81if (isAndroid) { 82 // iOS is handled by the config plugin -sfn 83 ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP) 84} 85 86/** 87 * Begin geolocation ASAP 88 */ 89beginResolveGeolocation() 90 91function InnerApp() { 92 const [isReady, setIsReady] = React.useState(false) 93 const {currentAccount} = useSession() 94 const {resumeSession} = useSessionApi() 95 const theme = useColorModeTheme() 96 const {_} = useLingui() 97 98 const hasCheckedReferrer = useStarterPackEntry() 99 100 // init 101 useEffect(() => { 102 async function onLaunch(account?: SessionAccount) { 103 try { 104 if (account) { 105 await resumeSession(account) 106 } else { 107 await tryFetchGates(undefined, 'prefer-fresh-gates') 108 } 109 } catch (e) { 110 logger.error(`session: resume failed`, {message: e}) 111 } finally { 112 setIsReady(true) 113 } 114 } 115 const account = readLastActiveAccount() 116 onLaunch(account) 117 }, [resumeSession]) 118 119 useEffect(() => { 120 return listenSessionDropped(() => { 121 Toast.show( 122 _(msg`Sorry! Your session expired. Please sign in again.`), 123 'info', 124 ) 125 }) 126 }, [_]) 127 128 return ( 129 <Alf theme={theme}> 130 <ThemeProvider theme={theme}> 131 <ContextMenuProvider> 132 <Splash isReady={isReady && hasCheckedReferrer}> 133 <RootSiblingParent> 134 <VideoVolumeProvider> 135 <React.Fragment 136 // Resets the entire tree below when it changes: 137 key={currentAccount?.did}> 138 <QueryProvider currentDid={currentAccount?.did}> 139 <ComposerProvider> 140 <StatsigProvider> 141 <MessagesProvider> 142 {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 143 <LabelDefsProvider> 144 <ModerationOptsProvider> 145 <LoggedOutViewProvider> 146 <SelectedFeedProvider> 147 <HiddenRepliesProvider> 148 <HomeBadgeProvider> 149 <UnreadNotifsProvider> 150 <BackgroundNotificationPreferencesProvider> 151 <MutedThreadsProvider> 152 <ProgressGuideProvider> 153 <ServiceAccountManager> 154 <HideBottomBarBorderProvider> 155 <GestureHandlerRootView 156 style={s.h100pct}> 157 <IntentDialogProvider> 158 <TestCtrls /> 159 <Shell /> 160 <NuxDialogs /> 161 </IntentDialogProvider> 162 </GestureHandlerRootView> 163 </HideBottomBarBorderProvider> 164 </ServiceAccountManager> 165 </ProgressGuideProvider> 166 </MutedThreadsProvider> 167 </BackgroundNotificationPreferencesProvider> 168 </UnreadNotifsProvider> 169 </HomeBadgeProvider> 170 </HiddenRepliesProvider> 171 </SelectedFeedProvider> 172 </LoggedOutViewProvider> 173 </ModerationOptsProvider> 174 </LabelDefsProvider> 175 </MessagesProvider> 176 </StatsigProvider> 177 </ComposerProvider> 178 </QueryProvider> 179 </React.Fragment> 180 </VideoVolumeProvider> 181 </RootSiblingParent> 182 </Splash> 183 </ContextMenuProvider> 184 </ThemeProvider> 185 </Alf> 186 ) 187} 188 189function App() { 190 const [isReady, setReady] = useState(false) 191 192 React.useEffect(() => { 193 Promise.all([initPersistedState(), ensureGeolocationResolved()]).then(() => 194 setReady(true), 195 ) 196 }, []) 197 198 if (!isReady) { 199 return null 200 } 201 202 /* 203 * NOTE: only nothing here can depend on other data or session state, since 204 * that is set up in the InnerApp component above. 205 */ 206 return ( 207 <GeolocationProvider> 208 <A11yProvider> 209 <KeyboardControllerProvider> 210 <SessionProvider> 211 <PrefsStateProvider> 212 <I18nProvider> 213 <ShellStateProvider> 214 <InvitesStateProvider> 215 <ModalStateProvider> 216 <DialogStateProvider> 217 <LightboxStateProvider> 218 <PortalProvider> 219 <BottomSheetProvider> 220 <StarterPackProvider> 221 <SafeAreaProvider 222 initialMetrics={initialWindowMetrics}> 223 <InnerApp /> 224 </SafeAreaProvider> 225 </StarterPackProvider> 226 </BottomSheetProvider> 227 </PortalProvider> 228 </LightboxStateProvider> 229 </DialogStateProvider> 230 </ModalStateProvider> 231 </InvitesStateProvider> 232 </ShellStateProvider> 233 </I18nProvider> 234 </PrefsStateProvider> 235 </SessionProvider> 236 </KeyboardControllerProvider> 237 </A11yProvider> 238 </GeolocationProvider> 239 ) 240} 241 242export default Sentry.wrap(App)