Web login/signup and shell

This commit is contained in:
Eric Bailey 2023-11-09 20:35:17 -06:00
parent 487d871cfd
commit ab878ba9a6
21 changed files with 581 additions and 374 deletions

View file

@ -1,52 +1,93 @@
import React from 'react'
import {
ActivityIndicator,
ScrollView,
TouchableOpacity,
View,
} from 'react-native'
import {ScrollView, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useAnalytics} from 'lib/analytics/analytics'
import {Text} from '../../util/text/Text'
import {UserAvatar} from '../../util/UserAvatar'
import {s} from 'lib/styles'
import {RootStoreModel} from 'state/index'
import {AccountData} from 'state/models/session'
import {usePalette} from 'lib/hooks/usePalette'
import {Trans, msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {styles} from './styles'
import {useSession, useSessionApi, SessionAccount} from '#/state/session'
import {useGetProfile} from '#/data/useGetProfile'
function AccountItem({
account,
onSelect,
}: {
account: SessionAccount
onSelect: (account: SessionAccount) => void
}) {
const pal = usePalette('default')
const {_} = useLingui()
const {isError, data} = useGetProfile({did: account.did})
const onPress = React.useCallback(() => {
onSelect(account)
}, [account, onSelect])
if (isError) return null
return (
<TouchableOpacity
testID={`chooseAccountBtn-${account.handle}`}
key={account.did}
style={[pal.view, pal.border, styles.account]}
onPress={onPress}
accessibilityRole="button"
accessibilityLabel={_(msg`Sign in as ${account.handle}`)}
accessibilityHint="Double tap to sign in">
<View style={[pal.borderDark, styles.groupContent, styles.noTopBorder]}>
<View style={s.p10}>
<UserAvatar avatar={data?.avatar} size={30} />
</View>
<Text style={styles.accountText}>
<Text type="lg-bold" style={pal.text}>
{data?.displayName || account.handle}{' '}
</Text>
<Text type="lg" style={[pal.textLight]}>
{account.handle}
</Text>
</Text>
<FontAwesomeIcon
icon="angle-right"
size={16}
style={[pal.text, s.mr10]}
/>
</View>
</TouchableOpacity>
)
}
export const ChooseAccountForm = ({
store,
onSelectAccount,
onPressBack,
}: {
store: RootStoreModel
onSelectAccount: (account?: AccountData) => void
onPressBack: () => void
}) => {
const {track, screen} = useAnalytics()
const pal = usePalette('default')
const [isProcessing, setIsProcessing] = React.useState(false)
const {_} = useLingui()
const {accounts} = useSession()
const {initSession} = useSessionApi()
React.useEffect(() => {
screen('Choose Account')
}, [screen])
const onTryAccount = async (account: AccountData) => {
if (account.accessJwt && account.refreshJwt) {
setIsProcessing(true)
if (await store.session.resumeSession(account)) {
const onSelect = React.useCallback(
async (account: SessionAccount) => {
if (account.accessJwt) {
await initSession(account)
track('Sign In', {resumedSession: true})
setIsProcessing(false)
return
} else {
onSelectAccount(account)
}
setIsProcessing(false)
}
onSelectAccount(account)
}
},
[track, initSession, onSelectAccount],
)
return (
<ScrollView testID="chooseAccountForm" style={styles.maxHeight}>
@ -55,35 +96,8 @@ export const ChooseAccountForm = ({
style={[pal.text, styles.groupLabel, s.mt5, s.mb10]}>
<Trans>Sign in as...</Trans>
</Text>
{store.session.accounts.map(account => (
<TouchableOpacity
testID={`chooseAccountBtn-${account.handle}`}
key={account.did}
style={[pal.view, pal.border, styles.account]}
onPress={() => onTryAccount(account)}
accessibilityRole="button"
accessibilityLabel={_(msg`Sign in as ${account.handle}`)}
accessibilityHint="Double tap to sign in">
<View
style={[pal.borderDark, styles.groupContent, styles.noTopBorder]}>
<View style={s.p10}>
<UserAvatar avatar={account.aviUrl} size={30} />
</View>
<Text style={styles.accountText}>
<Text type="lg-bold" style={pal.text}>
{account.displayName || account.handle}{' '}
</Text>
<Text type="lg" style={[pal.textLight]}>
{account.handle}
</Text>
</Text>
<FontAwesomeIcon
icon="angle-right"
size={16}
style={[pal.text, s.mr10]}
/>
</View>
</TouchableOpacity>
{accounts.map(account => (
<AccountItem key={account.did} account={account} onSelect={onSelect} />
))}
<TouchableOpacity
testID="chooseNewAccountBtn"
@ -112,7 +126,6 @@ export const ChooseAccountForm = ({
</Text>
</TouchableOpacity>
<View style={s.flex1} />
{isProcessing && <ActivityIndicator />}
</View>
</ScrollView>
)