Bluesky app fork with some witchin' additions 💫

Don't clear toasts when changing users (#3843)

* Move ThemeProvider to the top

* Move RootSiblingParent above the remounted part

* Move ToastContainer outside the remounted part

* Remove setTimeout around toasts

* Consistently handle dropped session

authored by danabra.mov and committed by

GitHub 85b34418 aeed4786

+64 -62
+27 -28
src/App.native.tsx
··· 89 89 return ( 90 90 <SafeAreaProvider initialMetrics={initialWindowMetrics}> 91 91 <Alf theme={theme}> 92 - <Splash isReady={isReady}> 93 - <React.Fragment 94 - // Resets the entire tree below when it changes: 95 - key={currentAccount?.did}> 96 - <QueryProvider currentDid={currentAccount?.did}> 97 - <PushNotificationsListener> 98 - <StatsigProvider> 99 - {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 100 - <LabelDefsProvider> 101 - <ModerationOptsProvider> 102 - <LoggedOutViewProvider> 103 - <SelectedFeedProvider> 104 - <UnreadNotifsProvider> 105 - <ThemeProvider theme={theme}> 106 - {/* All components should be within this provider */} 107 - <RootSiblingParent> 92 + <ThemeProvider theme={theme}> 93 + <Splash isReady={isReady}> 94 + <RootSiblingParent> 95 + <React.Fragment 96 + // Resets the entire tree below when it changes: 97 + key={currentAccount?.did}> 98 + <QueryProvider currentDid={currentAccount?.did}> 99 + <PushNotificationsListener> 100 + <StatsigProvider> 101 + {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 102 + <LabelDefsProvider> 103 + <ModerationOptsProvider> 104 + <LoggedOutViewProvider> 105 + <SelectedFeedProvider> 106 + <UnreadNotifsProvider> 108 107 <GestureHandlerRootView style={s.h100pct}> 109 108 <TestCtrls /> 110 109 <Shell /> 111 110 </GestureHandlerRootView> 112 - </RootSiblingParent> 113 - </ThemeProvider> 114 - </UnreadNotifsProvider> 115 - </SelectedFeedProvider> 116 - </LoggedOutViewProvider> 117 - </ModerationOptsProvider> 118 - </LabelDefsProvider> 119 - </StatsigProvider> 120 - </PushNotificationsListener> 121 - </QueryProvider> 122 - </React.Fragment> 123 - </Splash> 111 + </UnreadNotifsProvider> 112 + </SelectedFeedProvider> 113 + </LoggedOutViewProvider> 114 + </ModerationOptsProvider> 115 + </LabelDefsProvider> 116 + </StatsigProvider> 117 + </PushNotificationsListener> 118 + </QueryProvider> 119 + </React.Fragment> 120 + </RootSiblingParent> 121 + </Splash> 122 + </ThemeProvider> 124 123 </Alf> 125 124 </SafeAreaProvider> 126 125 )
+35 -25
src/App.web.tsx
··· 4 4 import React, {useEffect, useState} from 'react' 5 5 import {RootSiblingParent} from 'react-native-root-siblings' 6 6 import {SafeAreaProvider} from 'react-native-safe-area-context' 7 + import {msg} from '@lingui/macro' 8 + import {useLingui} from '@lingui/react' 7 9 8 10 import {Provider as StatsigProvider} from '#/lib/statsig/statsig' 9 11 import {logger} from '#/logger' ··· 30 32 import {Provider as ShellStateProvider} from 'state/shell' 31 33 import {Provider as LoggedOutViewProvider} from 'state/shell/logged-out' 32 34 import {Provider as SelectedFeedProvider} from 'state/shell/selected-feed' 35 + import * as Toast from 'view/com/util/Toast' 33 36 import {ToastContainer} from 'view/com/util/Toast.web' 34 37 import {Shell} from 'view/shell/index' 35 38 import {ThemeProvider as Alf} from '#/alf' 36 39 import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 37 40 import {Provider as PortalProvider} from '#/components/Portal' 38 41 import I18nProvider from './locale/i18nProvider' 42 + import {listenSessionDropped} from './state/events' 39 43 40 44 function InnerApp() { 41 45 const [isReady, setIsReady] = React.useState(false) 42 46 const {currentAccount} = useSession() 43 47 const {initSession} = useSessionApi() 44 48 const theme = useColorModeTheme() 49 + const {_} = useLingui() 45 50 useIntentHandler() 46 51 47 52 // init ··· 61 66 resumeSession(account) 62 67 }, [initSession]) 63 68 69 + useEffect(() => { 70 + return listenSessionDropped(() => { 71 + Toast.show(_(msg`Sorry! Your session expired. Please log in again.`)) 72 + }) 73 + }, [_]) 74 + 64 75 // wait for session to resume 65 76 if (!isReady) return null 66 77 67 78 return ( 68 79 <Alf theme={theme}> 69 - <React.Fragment 70 - // Resets the entire tree below when it changes: 71 - key={currentAccount?.did}> 72 - <QueryProvider currentDid={currentAccount?.did}> 73 - <StatsigProvider> 74 - {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 75 - <LabelDefsProvider> 76 - <ModerationOptsProvider> 77 - <LoggedOutViewProvider> 78 - <SelectedFeedProvider> 79 - <UnreadNotifsProvider> 80 - <ThemeProvider theme={theme}> 81 - {/* All components should be within this provider */} 82 - <RootSiblingParent> 80 + <ThemeProvider theme={theme}> 81 + <RootSiblingParent> 82 + <React.Fragment 83 + // Resets the entire tree below when it changes: 84 + key={currentAccount?.did}> 85 + <QueryProvider currentDid={currentAccount?.did}> 86 + <StatsigProvider> 87 + {/* LabelDefsProvider MUST come before ModerationOptsProvider */} 88 + <LabelDefsProvider> 89 + <ModerationOptsProvider> 90 + <LoggedOutViewProvider> 91 + <SelectedFeedProvider> 92 + <UnreadNotifsProvider> 83 93 <SafeAreaProvider> 84 94 <Shell /> 85 95 </SafeAreaProvider> 86 - </RootSiblingParent> 87 - <ToastContainer /> 88 - </ThemeProvider> 89 - </UnreadNotifsProvider> 90 - </SelectedFeedProvider> 91 - </LoggedOutViewProvider> 92 - </ModerationOptsProvider> 93 - </LabelDefsProvider> 94 - </StatsigProvider> 95 - </QueryProvider> 96 - </React.Fragment> 96 + </UnreadNotifsProvider> 97 + </SelectedFeedProvider> 98 + </LoggedOutViewProvider> 99 + </ModerationOptsProvider> 100 + </LabelDefsProvider> 101 + </StatsigProvider> 102 + </QueryProvider> 103 + </React.Fragment> 104 + <ToastContainer /> 105 + </RootSiblingParent> 106 + </ThemeProvider> 97 107 </Alf> 98 108 ) 99 109 }
+1 -6
src/lib/hooks/useAccountSwitcher.ts
··· 41 41 } 42 42 await initSession(account) 43 43 logEvent('account:loggedIn', {logContext, withPassword: false}) 44 - setTimeout(() => { 45 - Toast.show(_(msg`Signed in as @${account.handle}`)) 46 - }, 100) 44 + Toast.show(_(msg`Signed in as @${account.handle}`)) 47 45 } else { 48 46 requestSwitchToAccount({requestedAccount: account.did}) 49 47 Toast.show( ··· 56 54 message: e.message, 57 55 }) 58 56 clearCurrentAccount() // back user out to login 59 - setTimeout(() => { 60 - Toast.show(_(msg`Sorry! We need you to enter your password.`)) 61 - }, 100) 62 57 } finally { 63 58 setPendingDid(null) 64 59 }
+1 -3
src/screens/Login/ChooseAccountForm.tsx
··· 52 52 withPassword: false, 53 53 }) 54 54 track('Sign In', {resumedSession: true}) 55 - setTimeout(() => { 56 - Toast.show(_(msg`Signed in as @${account.handle}`)) 57 - }, 100) 55 + Toast.show(_(msg`Signed in as @${account.handle}`)) 58 56 } catch (e: any) { 59 57 logger.error('choose account: initSession failed', { 60 58 message: e.message,