Something went wrong. Try again.
An ATproto social media client -- with an independent Appview.
Something went wrong. Try again.
5.2 kB · 177 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178import React, {useState} from 'react'import {ActivityIndicator, Keyboard, View} from 'react-native'import {type ComAtprotoServerDescribeServer} from '@atproto/api'import {msg, Trans} from '@lingui/macro'import {useLingui} from '@lingui/react'import * as EmailValidator from 'email-validator'
import {isNetworkError} from '#/lib/strings/errors'import {cleanError} from '#/lib/strings/errors'import {logger} from '#/logger'import {Agent} from '#/state/session/agent'import {atoms as a, useTheme} from '#/alf'import {Button, ButtonText} from '#/components/Button'import {FormError} from '#/components/forms/FormError'import {HostingProvider} from '#/components/forms/HostingProvider'import * as TextField from '#/components/forms/TextField'import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'import {Text} from '#/components/Typography'import {FormContainer} from './FormContainer'
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
export const ForgotPasswordForm = ({ error, serviceUrl, serviceDescription, setError, setServiceUrl, onPressBack, onEmailSent,}: { error: string serviceUrl: string serviceDescription: ServiceDescription | undefined setError: (v: string) => void setServiceUrl: (v: string) => void onPressBack: () => void onEmailSent: () => void}) => { const t = useTheme() const [isProcessing, setIsProcessing] = useState<boolean>(false) const [email, setEmail] = useState<string>('') const {_} = useLingui()
const onPressSelectService = React.useCallback(() => { Keyboard.dismiss() }, [])
const onPressNext = async () => { if (!EmailValidator.validate(email)) { return setError(_(msg`Your email appears to be invalid.`)) }
setError('') setIsProcessing(true)
try { const agent = new Agent(null, {service: serviceUrl}) await agent.com.atproto.server.requestPasswordReset({email}) onEmailSent() } catch (e: any) { const errMsg = e.toString() logger.warn('Failed to request password reset', {error: e}) setIsProcessing(false) if (isNetworkError(e)) { setError( _( msg`Unable to contact your service. Please check your Internet connection.`, ), ) } else { setError(cleanError(errMsg)) } } }
return ( <FormContainer testID="forgotPasswordForm" titleText={<Trans>Reset password</Trans>}> <View> <TextField.LabelText> <Trans>Hosting provider</Trans> </TextField.LabelText> <HostingProvider serviceUrl={serviceUrl} onSelectServiceUrl={setServiceUrl} onOpenDialog={onPressSelectService} /> </View> <View> <TextField.LabelText> <Trans>Email address</Trans> </TextField.LabelText> <TextField.Root> <TextField.Icon icon={At} /> <TextField.Input testID="forgotPasswordEmail" label={_(msg`Enter your email address`)} autoCapitalize="none" autoFocus autoCorrect={false} autoComplete="email" value={email} onChangeText={setEmail} editable={!isProcessing} accessibilityHint={_(msg`Sets email for password reset`)} /> </TextField.Root> </View>
<Text style={[t.atoms.text_contrast_high, a.leading_snug]}> <Trans> Enter the email you used to create your account. We'll send you a "reset code" so you can set a new password. </Trans> </Text>
<FormError error={error} />
<View style={[a.flex_row, a.align_center, a.pt_md]}> <Button label={_(msg`Back`)} variant="solid" color="secondary" size="large" onPress={onPressBack}> <ButtonText> <Trans>Back</Trans> </ButtonText> </Button> <View style={a.flex_1} /> {!serviceDescription || isProcessing ? ( <ActivityIndicator /> ) : ( <Button label={_(msg`Next`)} variant="solid" color={'primary'} size="large" onPress={onPressNext}> <ButtonText> <Trans>Next</Trans> </ButtonText> </Button> )} {!serviceDescription || isProcessing ? ( <Text style={[t.atoms.text_contrast_high, a.pl_md]}> <Trans>Processing...</Trans> </Text> ) : undefined} </View> <View style={[ t.atoms.border_contrast_medium, a.border_t, a.pt_2xl, a.mt_md, a.flex_row, a.justify_center, ]}> <Button testID="skipSendEmailButton" onPress={onEmailSent} label={_(msg`Go to next`)} accessibilityHint={_(msg`Navigates to the next screen`)} size="large" variant="ghost" color="secondary"> <ButtonText> <Trans>Already have a code?</Trans> </ButtonText> </Button> </View> </FormContainer> )}