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