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 121 lines 3.6 kB view raw
1import {useCallback, useState} from 'react' 2import {View} from 'react-native' 3import {msg} from '@lingui/core/macro' 4import {useLingui} from '@lingui/react' 5import {Trans} from '@lingui/react/macro' 6 7import {logger} from '#/logger' 8import {type SessionAccount, useSession, useSessionApi} from '#/state/session' 9import {canAttemptSessionResume} from '#/state/session/util' 10import {useLoggedOutViewControls} from '#/state/shell/logged-out' 11import {atoms as a, web} from '#/alf' 12import {AccountList} from '#/components/AccountList' 13import {Button, ButtonText} from '#/components/Button' 14import * as TextField from '#/components/forms/TextField' 15import * as Toast from '#/components/Toast' 16import {useAnalytics} from '#/analytics' 17import {IS_WEB} from '#/env' 18import {FormContainer} from './FormContainer' 19 20export const ChooseAccountForm = ({ 21 onSelectAccount, 22 onPressBack, 23}: { 24 onSelectAccount: (account?: SessionAccount) => void 25 onPressBack: () => void 26}) => { 27 const [pendingDid, setPendingDid] = useState<string | null>(null) 28 const {_} = useLingui() 29 const ax = useAnalytics() 30 const {currentAccount} = useSession() 31 const {resumeSession} = useSessionApi() 32 const {setShowLoggedOut} = useLoggedOutViewControls() 33 34 const onSelect = useCallback( 35 async (account: SessionAccount) => { 36 if (pendingDid) { 37 // The session API isn't resilient to race conditions so let's just ignore this. 38 return 39 } 40 if (!canAttemptSessionResume(account)) { 41 // Move to login form. 42 onSelectAccount(account) 43 return 44 } 45 if (account.did === currentAccount?.did) { 46 setShowLoggedOut(false) 47 Toast.show(_(msg`Already signed in as @${account.handle}`)) 48 return 49 } 50 try { 51 setPendingDid(account.did) 52 await Promise.race([ 53 resumeSession(account, true), 54 new Promise<never>((_, reject) => 55 setTimeout( 56 () => reject(new Error('Session resume timed out')), 57 15_000, 58 ), 59 ), 60 ]) 61 ax.metric('account:loggedIn', { 62 logContext: 'ChooseAccountForm', 63 withPassword: false, 64 }) 65 Toast.show(_(msg`Signed in as @${account.handle}`)) 66 } catch (e: any) { 67 logger.error('choose account: initSession failed', { 68 message: e instanceof Error ? e.message : 'Unknown error', 69 }) 70 Toast.show(_(msg`Sign in failed. Please try again.`)) 71 // Move to login form. 72 onSelectAccount(account) 73 } finally { 74 setPendingDid(null) 75 } 76 }, 77 [ 78 currentAccount, 79 resumeSession, 80 pendingDid, 81 onSelectAccount, 82 setShowLoggedOut, 83 _, 84 ax, 85 ], 86 ) 87 88 return ( 89 <FormContainer 90 testID="chooseAccountForm" 91 titleText={<Trans>Select account</Trans>} 92 style={web([a.py_2xl])}> 93 <View> 94 {IS_WEB && ( 95 <TextField.LabelText> 96 <Trans>Sign in as...</Trans> 97 </TextField.LabelText> 98 )} 99 <AccountList 100 onSelectAccount={account => { 101 void onSelect(account) 102 }} 103 onSelectOther={() => onSelectAccount()} 104 pendingDid={pendingDid} 105 /> 106 </View> 107 {IS_WEB && ( 108 <View style={[a.flex_row]}> 109 <Button 110 label={_(msg`Back`)} 111 color="secondary" 112 size="large" 113 onPress={onPressBack}> 114 <ButtonText>{_(msg`Back`)}</ButtonText> 115 </Button> 116 <View style={[a.flex_1]} /> 117 </View> 118 )} 119 </FormContainer> 120 ) 121}