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