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