Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

at main 248 lines 11 kB view raw
1import '#/logger/sentry/setup' // must be near top 2import '#/view/icons' 3import './style.css' 4 5import {Fragment, useEffect, useState} from 'react' 6import {KeyboardProvider as KeyboardControllerProvider} from 'react-native-keyboard-controller' 7import {SafeAreaProvider} from 'react-native-safe-area-context' 8import {useLingui} from '@lingui/react/macro' 9import * as Sentry from '@sentry/react-native' 10 11import {Provider as HotkeysProvider} from '#/lib/hotkeys' 12import {QueryProvider} from '#/lib/react-query' 13import {ThemeProvider} from '#/lib/ThemeContext' 14import {Provider as TranslateOnDeviceProvider} from '#/lib/translation' 15import I18nProvider from '#/locale/i18nProvider' 16import {logger} from '#/logger' 17import {Provider as A11yProvider} from '#/state/a11y' 18import { 19 prefetchAppConfig, 20 Provider as AppConfigProvider, 21} from '#/state/appConfig' 22import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes' 23import {Provider as DialogStateProvider} from '#/state/dialogs' 24import {Provider as EmailVerificationProvider} from '#/state/email-verification' 25import {listenSessionDropped} from '#/state/events' 26import {Provider as HomeBadgeProvider} from '#/state/home-badge' 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 {Provider as ServiceConfigProvider} from '#/state/service-config' 36import { 37 Provider as SessionProvider, 38 type SessionAccount, 39 useSession, 40 useSessionApi, 41} from '#/state/session' 42import {readLastActiveAccount} from '#/state/session/util' 43import {Provider as ShellStateProvider} from '#/state/shell' 44import {Provider as ComposerProvider} from '#/state/shell/composer' 45import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out' 46import {Provider as OnboardingProvider} from '#/state/shell/onboarding' 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 {Shell} from '#/view/shell/index' 52import {ThemeProvider as Alf} from '#/alf' 53import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 54import {Provider as ContextMenuProvider} from '#/components/ContextMenu' 55import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry' 56import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs' 57import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay' 58import {Provider as PortalProvider} from '#/components/Portal' 59import {Provider as ActiveVideoProvider} from '#/components/Post/Embed/VideoEmbed/ActiveVideoWebContext' 60import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' 61import * as Toast from '#/components/Toast' 62import {ToastOutlet} from '#/components/Toast' 63import { 64 prefetchAgeAssuranceConfig, 65 Provider as AgeAssuranceV2Provider, 66} from '#/ageAssurance' 67import { 68 AnalyticsContext, 69 AnalyticsFeaturesContext, 70 features, 71 setupDeviceId, 72} from '#/analytics' 73import { 74 prefetchLiveEvents, 75 Provider as LiveEventsProvider, 76} from '#/features/liveEvents/context' 77import * as Geo from '#/geolocation' 78import {Splash} from '#/Splash' 79import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' 80import {Provider as HideBottomBarBorderProvider} from './lib/hooks/useHideBottomBarBorder' 81 82/** 83 * Begin geolocation ASAP 84 */ 85void Geo.resolve() 86void prefetchAgeAssuranceConfig() 87void prefetchLiveEvents() 88void prefetchAppConfig() 89 90function InnerApp() { 91 const [isReady, setIsReady] = useState(false) 92 const {currentAccount} = useSession() 93 const {resumeSession} = useSessionApi() 94 const theme = useColorModeTheme() 95 const {t: l} = useLingui() 96 const hasCheckedReferrer = useStarterPackEntry() 97 98 // init 99 useEffect(() => { 100 async function onLaunch(account?: SessionAccount) { 101 try { 102 if (account) { 103 await resumeSession(account) 104 } else { 105 await features.init 106 } 107 } catch (e) { 108 logger.error('session: resumeSession failed', {message: e}) 109 } finally { 110 setIsReady(true) 111 } 112 } 113 const account = readLastActiveAccount() 114 void onLaunch(account) 115 }, [resumeSession]) 116 117 useEffect(() => { 118 return listenSessionDropped(() => { 119 Toast.show(l`Sorry! Your session expired. Please sign in again.`, { 120 type: 'info', 121 }) 122 }) 123 }, [l]) 124 125 return ( 126 <Alf theme={theme}> 127 <ThemeProvider theme={theme}> 128 <ContextMenuProvider> 129 <Splash isReady={isReady && hasCheckedReferrer}> 130 <VideoVolumeProvider> 131 <ActiveVideoProvider> 132 <Fragment 133 // Resets the entire tree below when it changes: 134 key={currentAccount?.did}> 135 <AnalyticsFeaturesContext> 136 <QueryProvider currentDid={currentAccount?.did}> 137 <PolicyUpdateOverlayProvider> 138 <LiveEventsProvider> 139 <AgeAssuranceV2Provider> 140 <ComposerProvider> 141 <MessagesProvider> 142 {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 143 <LabelDefsProvider> 144 <ModerationOptsProvider> 145 <LoggedOutViewProvider> 146 <SelectedFeedProvider> 147 <HiddenRepliesProvider> 148 <HomeBadgeProvider> 149 <UnreadNotifsProvider> 150 <BackgroundNotificationPreferencesProvider> 151 <MutedThreadsProvider> 152 <SafeAreaProvider> 153 <ProgressGuideProvider> 154 <ServiceConfigProvider> 155 <EmailVerificationProvider> 156 <HideBottomBarBorderProvider> 157 <IntentDialogProvider> 158 <TranslateOnDeviceProvider> 159 <HotkeysProvider> 160 <Shell /> 161 <ToastOutlet /> 162 </HotkeysProvider> 163 </TranslateOnDeviceProvider> 164 </IntentDialogProvider> 165 </HideBottomBarBorderProvider> 166 </EmailVerificationProvider> 167 </ServiceConfigProvider> 168 </ProgressGuideProvider> 169 </SafeAreaProvider> 170 </MutedThreadsProvider> 171 </BackgroundNotificationPreferencesProvider> 172 </UnreadNotifsProvider> 173 </HomeBadgeProvider> 174 </HiddenRepliesProvider> 175 </SelectedFeedProvider> 176 </LoggedOutViewProvider> 177 </ModerationOptsProvider> 178 </LabelDefsProvider> 179 </MessagesProvider> 180 </ComposerProvider> 181 </AgeAssuranceV2Provider> 182 </LiveEventsProvider> 183 </PolicyUpdateOverlayProvider> 184 </QueryProvider> 185 </AnalyticsFeaturesContext> 186 </Fragment> 187 </ActiveVideoProvider> 188 </VideoVolumeProvider> 189 </Splash> 190 </ContextMenuProvider> 191 </ThemeProvider> 192 </Alf> 193 ) 194} 195 196function App() { 197 const [isReady, setIsReady] = useState(false) 198 199 useEffect(() => { 200 void Promise.all([initPersistedState(), Geo.resolve(), setupDeviceId]).then( 201 () => setIsReady(true), 202 ) 203 }, []) 204 205 if (!isReady) { 206 return null 207 } 208 209 /* 210 * NOTE: only nothing here can depend on other data or session state, since 211 * that is set up in the InnerApp component above. 212 */ 213 return ( 214 <Geo.Provider> 215 <AppConfigProvider> 216 <A11yProvider> 217 <KeyboardControllerProvider> 218 <OnboardingProvider> 219 <AnalyticsContext> 220 <SessionProvider> 221 <PrefsStateProvider> 222 <I18nProvider> 223 <ShellStateProvider> 224 <ModalStateProvider> 225 <DialogStateProvider> 226 <LightboxStateProvider> 227 <PortalProvider> 228 <StarterPackProvider> 229 <InnerApp /> 230 </StarterPackProvider> 231 </PortalProvider> 232 </LightboxStateProvider> 233 </DialogStateProvider> 234 </ModalStateProvider> 235 </ShellStateProvider> 236 </I18nProvider> 237 </PrefsStateProvider> 238 </SessionProvider> 239 </AnalyticsContext> 240 </OnboardingProvider> 241 </KeyboardControllerProvider> 242 </A11yProvider> 243 </AppConfigProvider> 244 </Geo.Provider> 245 ) 246} 247 248export default Sentry.wrap(App)