mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at verify-code 7.9 kB view raw
1import 'react-native-url-polyfill/auto' 2import 'lib/sentry' // must be near top 3import 'view/icons' 4 5import React, {useEffect, useState} from 'react' 6import {GestureHandlerRootView} from 'react-native-gesture-handler' 7import {KeyboardProvider} from 'react-native-keyboard-controller' 8import {RootSiblingParent} from 'react-native-root-siblings' 9import { 10 initialWindowMetrics, 11 SafeAreaProvider, 12} from 'react-native-safe-area-context' 13import * as SplashScreen from 'expo-splash-screen' 14import {msg} from '@lingui/macro' 15import {useLingui} from '@lingui/react' 16 17import {useIntentHandler} from '#/lib/hooks/useIntentHandler' 18import {QueryProvider} from '#/lib/react-query' 19import { 20 initialize, 21 Provider as StatsigProvider, 22 tryFetchGates, 23} from '#/lib/statsig/statsig' 24import {s} from '#/lib/styles' 25import {ThemeProvider} from '#/lib/ThemeContext' 26import I18nProvider from '#/locale/i18nProvider' 27import {logger} from '#/logger' 28import {Provider as A11yProvider} from '#/state/a11y' 29import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes' 30import {Provider as DialogStateProvider} from '#/state/dialogs' 31import {listenSessionDropped} from '#/state/events' 32import {Provider as InvitesStateProvider} from '#/state/invites' 33import {Provider as LightboxStateProvider} from '#/state/lightbox' 34import {MessagesProvider} from '#/state/messages' 35import {Provider as ModalStateProvider} from '#/state/modals' 36import {init as initPersistedState} from '#/state/persisted' 37import {Provider as PrefsStateProvider} from '#/state/preferences' 38import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' 39import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts' 40import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread' 41import { 42 Provider as SessionProvider, 43 SessionAccount, 44 useSession, 45 useSessionApi, 46} from '#/state/session' 47import {readLastActiveAccount} from '#/state/session/util' 48import {Provider as ShellStateProvider} from '#/state/shell' 49import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out' 50import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide' 51import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' 52import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' 53import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' 54import {TestCtrls} from '#/view/com/testing/TestCtrls' 55import {Provider as ActiveVideoProvider} from '#/view/com/util/post-embeds/ActiveVideoNativeContext' 56import * as Toast from '#/view/com/util/Toast' 57import {Shell} from '#/view/shell' 58import {ThemeProvider as Alf} from '#/alf' 59import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 60import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 61import {Provider as PortalProvider} from '#/components/Portal' 62import {Splash} from '#/Splash' 63import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' 64import {AudioCategory, PlatformInfo} from '../modules/expo-bluesky-swiss-army' 65 66SplashScreen.preventAutoHideAsync() 67 68function InnerApp() { 69 const [isReady, setIsReady] = React.useState(false) 70 const {currentAccount} = useSession() 71 const {resumeSession} = useSessionApi() 72 const theme = useColorModeTheme() 73 const {_} = useLingui() 74 75 useIntentHandler() 76 const hasCheckedReferrer = useStarterPackEntry() 77 78 // init 79 useEffect(() => { 80 async function onLaunch(account?: SessionAccount) { 81 try { 82 if (account) { 83 await resumeSession(account) 84 } else { 85 await initialize() 86 await tryFetchGates(undefined, 'prefer-fresh-gates') 87 } 88 } catch (e) { 89 logger.error(`session: resume failed`, {message: e}) 90 } finally { 91 setIsReady(true) 92 } 93 } 94 const account = readLastActiveAccount() 95 onLaunch(account) 96 }, [resumeSession]) 97 98 useEffect(() => { 99 return listenSessionDropped(() => { 100 Toast.show( 101 _(msg`Sorry! Your session expired. Please log in again.`), 102 'info', 103 ) 104 }) 105 }, [_]) 106 107 return ( 108 <SafeAreaProvider initialMetrics={initialWindowMetrics}> 109 <Alf theme={theme}> 110 <ThemeProvider theme={theme}> 111 <Splash isReady={isReady && hasCheckedReferrer}> 112 <ActiveVideoProvider> 113 <RootSiblingParent> 114 <React.Fragment 115 // Resets the entire tree below when it changes: 116 key={currentAccount?.did}> 117 <QueryProvider currentDid={currentAccount?.did}> 118 <StatsigProvider> 119 <MessagesProvider> 120 {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 121 <LabelDefsProvider> 122 <ModerationOptsProvider> 123 <LoggedOutViewProvider> 124 <SelectedFeedProvider> 125 <HiddenRepliesProvider> 126 <UnreadNotifsProvider> 127 <BackgroundNotificationPreferencesProvider> 128 <MutedThreadsProvider> 129 <ProgressGuideProvider> 130 <GestureHandlerRootView 131 style={s.h100pct}> 132 <TestCtrls /> 133 <Shell /> 134 </GestureHandlerRootView> 135 </ProgressGuideProvider> 136 </MutedThreadsProvider> 137 </BackgroundNotificationPreferencesProvider> 138 </UnreadNotifsProvider> 139 </HiddenRepliesProvider> 140 </SelectedFeedProvider> 141 </LoggedOutViewProvider> 142 </ModerationOptsProvider> 143 </LabelDefsProvider> 144 </MessagesProvider> 145 </StatsigProvider> 146 </QueryProvider> 147 </React.Fragment> 148 </RootSiblingParent> 149 </ActiveVideoProvider> 150 </Splash> 151 </ThemeProvider> 152 </Alf> 153 </SafeAreaProvider> 154 ) 155} 156 157function App() { 158 const [isReady, setReady] = useState(false) 159 160 React.useEffect(() => { 161 PlatformInfo.setAudioCategory(AudioCategory.Ambient) 162 PlatformInfo.setAudioActive(false) 163 initPersistedState().then(() => setReady(true)) 164 }, []) 165 166 if (!isReady) { 167 return null 168 } 169 170 /* 171 * NOTE: only nothing here can depend on other data or session state, since 172 * that is set up in the InnerApp component above. 173 */ 174 return ( 175 <A11yProvider> 176 <KeyboardProvider enabled={false} statusBarTranslucent={true}> 177 <SessionProvider> 178 <PrefsStateProvider> 179 <I18nProvider> 180 <ShellStateProvider> 181 <InvitesStateProvider> 182 <ModalStateProvider> 183 <DialogStateProvider> 184 <LightboxStateProvider> 185 <PortalProvider> 186 <StarterPackProvider> 187 <InnerApp /> 188 </StarterPackProvider> 189 </PortalProvider> 190 </LightboxStateProvider> 191 </DialogStateProvider> 192 </ModalStateProvider> 193 </InvitesStateProvider> 194 </ShellStateProvider> 195 </I18nProvider> 196 </PrefsStateProvider> 197 </SessionProvider> 198 </KeyboardProvider> 199 </A11yProvider> 200 ) 201} 202 203export default App