this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 276 lines 12 kB view raw
1import '#/logger/sentry/setup' 2import '#/view/icons' 3 4import {Fragment, useEffect, useState} from 'react' 5import {GestureHandlerRootView} from 'react-native-gesture-handler' 6import {KeyboardProvider as KeyboardControllerProvider} from 'react-native-keyboard-controller' 7import { 8 initialWindowMetrics, 9 SafeAreaProvider, 10} from 'react-native-safe-area-context' 11import * as ScreenOrientation from 'expo-screen-orientation' 12import * as SplashScreen from 'expo-splash-screen' 13import * as SystemUI from 'expo-system-ui' 14import {msg} from '@lingui/core/macro' 15import {useLingui} from '@lingui/react' 16import * as Sentry from '@sentry/react-native' 17 18import {Provider as HideBottomBarBorderProvider} from '#/lib/hooks/useHideBottomBarBorder' 19import {QueryProvider} from '#/lib/react-query' 20import {s} from '#/lib/styles' 21import {ThemeProvider} from '#/lib/ThemeContext' 22import {Provider as TranslateOnDeviceProvider} from '#/lib/translation' 23import I18nProvider from '#/locale/i18nProvider' 24import {logger} from '#/logger' 25import {Provider as A11yProvider} from '#/state/a11y' 26import { 27 prefetchAppConfig, 28 Provider as AppConfigProvider, 29} from '#/state/appConfig' 30import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes' 31import {Provider as DialogStateProvider} from '#/state/dialogs' 32import {Provider as EmailVerificationProvider} from '#/state/email-verification' 33import {listenSessionDropped} from '#/state/events' 34import {GlobalGestureEventsProvider} from '#/state/global-gesture-events' 35import {Provider as HomeBadgeProvider} from '#/state/home-badge' 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 {Provider as ServiceAccountManager} from '#/state/service-config' 45import { 46 Provider as SessionProvider, 47 type SessionAccount, 48 useSession, 49 useSessionApi, 50} from '#/state/session' 51import {readLastActiveAccount} from '#/state/session/util' 52import {Provider as ShellStateProvider} from '#/state/shell' 53import {Provider as ComposerProvider} from '#/state/shell/composer' 54import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out' 55import {Provider as OnboardingProvider} from '#/state/shell/onboarding' 56import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide' 57import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' 58import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' 59import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' 60import {TestCtrls} from '#/view/com/testing/TestCtrls' 61import {Shell} from '#/view/shell' 62import {ThemeProvider as Alf} from '#/alf' 63import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 64import {Provider as ContextMenuProvider} from '#/components/ContextMenu' 65import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 66import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' 67import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay' 68import {Provider as PortalProvider} from '#/components/Portal' 69import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' 70import * as Toast from '#/components/Toast' 71import {ToastOutlet} from '#/components/Toast' 72import { 73 prefetchAgeAssuranceConfig, 74 Provider as AgeAssuranceV2Provider, 75} from '#/ageAssurance' 76import { 77 AnalyticsContext, 78 AnalyticsFeaturesContext, 79 features, 80 setupDeviceId, 81} from '#/analytics' 82import {IS_ANDROID, IS_IOS} from '#/env' 83import { 84 prefetchLiveEvents, 85 Provider as LiveEventsProvider, 86} from '#/features/liveEvents/context' 87import * as Geo from '#/geolocation' 88import {Splash} from '#/Splash' 89import {BottomSheetProvider} from '../modules/bottom-sheet' 90import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' 91 92SplashScreen.preventAutoHideAsync() 93if (IS_IOS) { 94 SystemUI.setBackgroundColorAsync('black') 95} 96if (IS_ANDROID) { 97 // iOS is handled by the config plugin -sfn 98 ScreenOrientation.lockAsync( 99 ScreenOrientation.OrientationLock.PORTRAIT_UP, 100 ).catch(error => 101 logger.debug('Could not lock orientation', {safeMessage: error}), 102 ) 103} 104 105/** 106 * Begin geolocation ASAP 107 */ 108Geo.resolve() 109prefetchAgeAssuranceConfig() 110prefetchLiveEvents() 111prefetchAppConfig() 112 113function InnerApp() { 114 const [isReady, setIsReady] = useState(false) 115 const {currentAccount} = useSession() 116 const {resumeSession} = useSessionApi() 117 const theme = useColorModeTheme() 118 const {_} = useLingui() 119 const hasCheckedReferrer = useStarterPackEntry() 120 121 // init 122 useEffect(() => { 123 async function onLaunch(account?: SessionAccount) { 124 try { 125 if (account) { 126 await resumeSession(account) 127 } else { 128 await features.init 129 } 130 } catch (e) { 131 logger.error(`session: resume failed`, {message: e}) 132 } finally { 133 setIsReady(true) 134 } 135 } 136 const account = readLastActiveAccount() 137 onLaunch(account) 138 }, [resumeSession]) 139 140 useEffect(() => { 141 return listenSessionDropped(() => { 142 Toast.show(_(msg`Sorry! Your session expired. Please sign in again.`), { 143 type: 'info', 144 }) 145 }) 146 }, [_]) 147 148 return ( 149 <Alf theme={theme}> 150 <ThemeProvider theme={theme}> 151 <ContextMenuProvider> 152 <Splash isReady={isReady && hasCheckedReferrer}> 153 <VideoVolumeProvider> 154 <Fragment 155 // Resets the entire tree below when it changes: 156 key={currentAccount?.did}> 157 <AnalyticsFeaturesContext> 158 <QueryProvider currentDid={currentAccount?.did}> 159 <PolicyUpdateOverlayProvider> 160 <LiveEventsProvider> 161 <AgeAssuranceV2Provider> 162 <ComposerProvider> 163 <MessagesProvider> 164 {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 165 <LabelDefsProvider> 166 <ModerationOptsProvider> 167 <LoggedOutViewProvider> 168 <SelectedFeedProvider> 169 <HiddenRepliesProvider> 170 <HomeBadgeProvider> 171 <UnreadNotifsProvider> 172 <BackgroundNotificationPreferencesProvider> 173 <MutedThreadsProvider> 174 <ProgressGuideProvider> 175 <ServiceAccountManager> 176 <EmailVerificationProvider> 177 <HideBottomBarBorderProvider> 178 <GestureHandlerRootView 179 style={s.h100pct}> 180 <GlobalGestureEventsProvider> 181 <IntentDialogProvider> 182 <TranslateOnDeviceProvider> 183 <TestCtrls /> 184 <Shell /> 185 <ToastOutlet /> 186 </TranslateOnDeviceProvider> 187 </IntentDialogProvider> 188 </GlobalGestureEventsProvider> 189 </GestureHandlerRootView> 190 </HideBottomBarBorderProvider> 191 </EmailVerificationProvider> 192 </ServiceAccountManager> 193 </ProgressGuideProvider> 194 </MutedThreadsProvider> 195 </BackgroundNotificationPreferencesProvider> 196 </UnreadNotifsProvider> 197 </HomeBadgeProvider> 198 </HiddenRepliesProvider> 199 </SelectedFeedProvider> 200 </LoggedOutViewProvider> 201 </ModerationOptsProvider> 202 </LabelDefsProvider> 203 </MessagesProvider> 204 </ComposerProvider> 205 </AgeAssuranceV2Provider> 206 </LiveEventsProvider> 207 </PolicyUpdateOverlayProvider> 208 </QueryProvider> 209 </AnalyticsFeaturesContext> 210 </Fragment> 211 </VideoVolumeProvider> 212 </Splash> 213 </ContextMenuProvider> 214 </ThemeProvider> 215 </Alf> 216 ) 217} 218 219function App() { 220 const [isReady, setReady] = useState(false) 221 222 useEffect(() => { 223 Promise.all([initPersistedState(), Geo.resolve(), setupDeviceId]).then(() => 224 setReady(true), 225 ) 226 }, []) 227 228 if (!isReady) { 229 return null 230 } 231 232 /* 233 * NOTE: only nothing here can depend on other data or session state, since 234 * that is set up in the InnerApp component above. 235 */ 236 return ( 237 <Geo.Provider> 238 <AppConfigProvider> 239 <A11yProvider> 240 <KeyboardControllerProvider> 241 <OnboardingProvider> 242 <AnalyticsContext> 243 <SessionProvider> 244 <PrefsStateProvider> 245 <I18nProvider> 246 <ShellStateProvider> 247 <ModalStateProvider> 248 <DialogStateProvider> 249 <LightboxStateProvider> 250 <PortalProvider> 251 <BottomSheetProvider> 252 <StarterPackProvider> 253 <SafeAreaProvider 254 initialMetrics={initialWindowMetrics}> 255 <InnerApp /> 256 </SafeAreaProvider> 257 </StarterPackProvider> 258 </BottomSheetProvider> 259 </PortalProvider> 260 </LightboxStateProvider> 261 </DialogStateProvider> 262 </ModalStateProvider> 263 </ShellStateProvider> 264 </I18nProvider> 265 </PrefsStateProvider> 266 </SessionProvider> 267 </AnalyticsContext> 268 </OnboardingProvider> 269 </KeyboardControllerProvider> 270 </A11yProvider> 271 </AppConfigProvider> 272 </Geo.Provider> 273 ) 274} 275 276export default Sentry.wrap(App)