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