remove some more unnecessary stuff

This commit is contained in:
Hailey
2024-04-02 15:49:39 -07:00
parent 9128cb1690
commit 103d441f08
5 changed files with 15 additions and 512 deletions
-184
View File
@@ -1,184 +0,0 @@
import React, {useEffect, useState} from 'react'
import {ActivityIndicator, Keyboard, View} from 'react-native'
import {ComAtprotoServerDescribeServer} from '@atproto/api'
import {BskyAgent} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import * as EmailValidator from 'email-validator'
import {useAnalytics} from '#/lib/analytics/analytics'
import {isNetworkError} from '#/lib/strings/errors'
import {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger'
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 {screen} = useAnalytics()
const {_} = useLingui()
useEffect(() => {
screen('Signin:ForgotPassword')
}, [screen])
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 BskyAgent({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"
title={<Trans>Reset password</Trans>}>
<View>
<TextField.Label>
<Trans>Hosting provider</Trans>
</TextField.Label>
<HostingProvider
serviceUrl={serviceUrl}
onSelectServiceUrl={setServiceUrl}
onOpenDialog={onPressSelectService}
/>
</View>
<View>
<TextField.Label>
<Trans>Email address</Trans>
</TextField.Label>
<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="medium"
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="medium"
onPress={onPressNext}
disabled={!email}>
<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="medium"
variant="ghost"
color="secondary">
<ButtonText>
<Trans>Already have a code?</Trans>
</ButtonText>
</Button>
</View>
</FormContainer>
)
}
+14 -32
View File
@@ -1,31 +1,17 @@
import React, {useRef, useState} from 'react' import React from 'react'
import { import {Keyboard, View} from 'react-native'
ActivityIndicator,
Keyboard,
LayoutAnimation,
TextInput,
View,
} from 'react-native'
import * as Browser from 'expo-web-browser' import * as Browser from 'expo-web-browser'
import {ComAtprotoServerDescribeServer} from '@atproto/api' import {ComAtprotoServerDescribeServer} from '@atproto/api'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics' import {useAnalytics} from '#/lib/analytics/analytics'
import {isNetworkError} from '#/lib/strings/errors' import {isAndroid} from 'platform/detection'
import {cleanError} from '#/lib/strings/errors' import {atoms as a} from '#/alf'
import {createFullHandle} from '#/lib/strings/handles' import {Button, ButtonText} from '#/components/Button'
import {logger} from '#/logger'
import {useSessionApi} from '#/state/session'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {FormError} from '#/components/forms/FormError' import {FormError} from '#/components/forms/FormError'
import {HostingProvider} from '#/components/forms/HostingProvider' import {HostingProvider} from '#/components/forms/HostingProvider'
import * as TextField from '#/components/forms/TextField' import * as TextField from '#/components/forms/TextField'
import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
import {Lock_Stroke2_Corner0_Rounded as Lock} from '#/components/icons/Lock'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
import {FormContainer} from './FormContainer' import {FormContainer} from './FormContainer'
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
@@ -34,17 +20,14 @@ export const LoginForm = ({
error, error,
serviceUrl, serviceUrl,
serviceDescription, serviceDescription,
initialHandle,
setError, setError,
setServiceUrl, setServiceUrl,
onPressRetryConnect, onPressRetryConnect,
onPressBack, onPressBack,
onPressForgotPassword,
}: { }: {
error: string error: string
serviceUrl: string serviceUrl: string
serviceDescription: ServiceDescription | undefined serviceDescription: ServiceDescription | undefined
initialHandle: string
setError: (v: string) => void setError: (v: string) => void
setServiceUrl: (v: string) => void setServiceUrl: (v: string) => void
onPressRetryConnect: () => void onPressRetryConnect: () => void
@@ -52,15 +35,13 @@ export const LoginForm = ({
onPressForgotPassword: () => void onPressForgotPassword: () => void
}) => { }) => {
const {track} = useAnalytics() const {track} = useAnalytics()
const t = useTheme()
const [isProcessing, setIsProcessing] = useState<boolean>(false)
const passwordInputRef = useRef<TextInput>(null)
const {_} = useLingui() const {_} = useLingui()
const {login} = useSessionApi()
// This improves speed at which the browser presents itself on Android // This improves speed at which the browser presents itself on Android
React.useEffect(() => { React.useEffect(() => {
Browser.warmUpAsync() if (isAndroid) {
Browser.warmUpAsync()
}
}, []) }, [])
const onPressSelectService = React.useCallback(() => { const onPressSelectService = React.useCallback(() => {
@@ -73,9 +54,7 @@ export const LoginForm = ({
'https://bsky.app/login', // Replace this with the PDS auth url 'https://bsky.app/login', // Replace this with the PDS auth url
'bsky://login', // Replace this as well with the appropriate link 'bsky://login', // Replace this as well with the appropriate link
{ {
// Similar to how Google auth works. Sessions will be remembered so that we can windowFeatures: {},
// usually proceed without needing credentials
preferEphemeralSession: true,
}, },
) )
@@ -86,6 +65,8 @@ export const LoginForm = ({
// Handle session storage here // Handle session storage here
} }
console.log(serviceDescription)
return ( return (
<FormContainer testID="loginForm" title={<Trans>Sign in</Trans>}> <FormContainer testID="loginForm" title={<Trans>Sign in</Trans>}>
<View> <View>
@@ -115,9 +96,10 @@ export const LoginForm = ({
variant="solid" variant="solid"
color="primary" color="primary"
size="medium" size="medium"
onPress={onPressBack}> onPress={onPressNext}
disabled={!serviceDescription}>
<ButtonText> <ButtonText>
<Trans>Login</Trans> <Trans>Sign In</Trans>
</ButtonText> </ButtonText>
</Button> </Button>
</View> </View>
-50
View File
@@ -1,50 +0,0 @@
import React, {useEffect} from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {atoms as a, useBreakpoints} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import {Text} from '#/components/Typography'
import {FormContainer} from './FormContainer'
export const PasswordUpdatedForm = ({
onPressNext,
}: {
onPressNext: () => void
}) => {
const {screen} = useAnalytics()
const {_} = useLingui()
const {gtMobile} = useBreakpoints()
useEffect(() => {
screen('Signin:PasswordUpdatedForm')
}, [screen])
return (
<FormContainer
testID="passwordUpdatedForm"
style={[a.gap_2xl, !gtMobile && a.mt_5xl]}>
<Text style={[a.text_3xl, a.font_bold, a.text_center]}>
<Trans>Password updated!</Trans>
</Text>
<Text style={[a.text_center, a.mx_auto, {maxWidth: '80%'}]}>
<Trans>You can now sign in with your new password.</Trans>
</Text>
<View style={[a.flex_row, a.justify_center]}>
<Button
onPress={onPressNext}
label={_(msg`Close alert`)}
accessibilityHint={_(msg`Closes password update alert`)}
variant="solid"
color="primary"
size="medium">
<ButtonText>
<Trans>Okay</Trans>
</ButtonText>
</Button>
</View>
</FormContainer>
)
}
-192
View File
@@ -1,192 +0,0 @@
import React, {useEffect, useState} from 'react'
import {ActivityIndicator, View} from 'react-native'
import {BskyAgent} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {isNetworkError} from '#/lib/strings/errors'
import {cleanError} from '#/lib/strings/errors'
import {checkAndFormatResetCode} from '#/lib/strings/password'
import {logger} from '#/logger'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import {FormError} from '#/components/forms/FormError'
import * as TextField from '#/components/forms/TextField'
import {Lock_Stroke2_Corner0_Rounded as Lock} from '#/components/icons/Lock'
import {Ticket_Stroke2_Corner0_Rounded as Ticket} from '#/components/icons/Ticket'
import {Text} from '#/components/Typography'
import {FormContainer} from './FormContainer'
export const SetNewPasswordForm = ({
error,
serviceUrl,
setError,
onPressBack,
onPasswordSet,
}: {
error: string
serviceUrl: string
setError: (v: string) => void
onPressBack: () => void
onPasswordSet: () => void
}) => {
const {screen} = useAnalytics()
const {_} = useLingui()
const t = useTheme()
useEffect(() => {
screen('Signin:SetNewPasswordForm')
}, [screen])
const [isProcessing, setIsProcessing] = useState<boolean>(false)
const [resetCode, setResetCode] = useState<string>('')
const [password, setPassword] = useState<string>('')
const onPressNext = async () => {
// Check that the code is correct. We do this again just incase the user enters the code after their pw and we
// don't get to call onBlur first
const formattedCode = checkAndFormatResetCode(resetCode)
// TODO Better password strength check
if (!formattedCode || !password) {
setError(
_(
msg`You have entered an invalid code. It should look like XXXXX-XXXXX.`,
),
)
return
}
setError('')
setIsProcessing(true)
try {
const agent = new BskyAgent({service: serviceUrl})
await agent.com.atproto.server.resetPassword({
token: formattedCode,
password,
})
onPasswordSet()
} catch (e: any) {
const errMsg = e.toString()
logger.warn('Failed to set new password', {error: e})
setIsProcessing(false)
if (isNetworkError(e)) {
setError(
_(
msg`Unable to contact your service. Please check your Internet connection.`,
),
)
} else {
setError(cleanError(errMsg))
}
}
}
const onBlur = () => {
const formattedCode = checkAndFormatResetCode(resetCode)
if (!formattedCode) {
setError(
_(
msg`You have entered an invalid code. It should look like XXXXX-XXXXX.`,
),
)
return
}
setResetCode(formattedCode)
}
return (
<FormContainer
testID="setNewPasswordForm"
title={<Trans>Set new password</Trans>}>
<Text style={[a.leading_snug, a.mb_sm]}>
<Trans>
You will receive an email with a "reset code." Enter that code here,
then enter your new password.
</Trans>
</Text>
<View>
<TextField.Label>Reset code</TextField.Label>
<TextField.Root>
<TextField.Icon icon={Ticket} />
<TextField.Input
testID="resetCodeInput"
label={_(msg`Looks like XXXXX-XXXXX`)}
autoCapitalize="none"
autoFocus={true}
autoCorrect={false}
autoComplete="off"
value={resetCode}
onChangeText={setResetCode}
onFocus={() => setError('')}
onBlur={onBlur}
editable={!isProcessing}
accessibilityHint={_(
msg`Input code sent to your email for password reset`,
)}
/>
</TextField.Root>
</View>
<View>
<TextField.Label>New password</TextField.Label>
<TextField.Root>
<TextField.Icon icon={Lock} />
<TextField.Input
testID="newPasswordInput"
label={_(msg`Enter a password`)}
autoCapitalize="none"
autoCorrect={false}
autoComplete="password"
returnKeyType="done"
secureTextEntry={true}
textContentType="password"
clearButtonMode="while-editing"
value={password}
onChangeText={setPassword}
onSubmitEditing={onPressNext}
editable={!isProcessing}
accessibilityHint={_(msg`Input new password`)}
/>
</TextField.Root>
</View>
<FormError error={error} />
<View style={[a.flex_row, a.align_center, a.pt_lg]}>
<Button
label={_(msg`Back`)}
variant="solid"
color="secondary"
size="medium"
onPress={onPressBack}>
<ButtonText>
<Trans>Back</Trans>
</ButtonText>
</Button>
<View style={a.flex_1} />
{isProcessing ? (
<ActivityIndicator />
) : (
<Button
label={_(msg`Next`)}
variant="solid"
color="primary"
size="medium"
onPress={onPressNext}>
<ButtonText>
<Trans>Next</Trans>
</ButtonText>
</Button>
)}
{isProcessing ? (
<Text style={[t.atoms.text_contrast_high, a.pl_md]}>
<Trans>Updating...</Trans>
</Text>
) : undefined}
</View>
</FormContainer>
)
}
+1 -54
View File
@@ -4,17 +4,13 @@ import {LayoutAnimationConfig} from 'react-native-reanimated'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {DEFAULT_SERVICE} from '#/lib/constants' import {DEFAULT_SERVICE} from '#/lib/constants'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useServiceQuery} from '#/state/queries/service' import {useServiceQuery} from '#/state/queries/service'
import {SessionAccount, useSession} from '#/state/session' import {SessionAccount, useSession} from '#/state/session'
import {useLoggedOutView} from '#/state/shell/logged-out' import {useLoggedOutView} from '#/state/shell/logged-out'
import {LoggedOutLayout} from '#/view/com/util/layouts/LoggedOutLayout' import {LoggedOutLayout} from '#/view/com/util/layouts/LoggedOutLayout'
import {ForgotPasswordForm} from '#/screens/Login/ForgotPasswordForm'
import {LoginForm} from '#/screens/Login/LoginForm' import {LoginForm} from '#/screens/Login/LoginForm'
import {PasswordUpdatedForm} from '#/screens/Login/PasswordUpdatedForm'
import {SetNewPasswordForm} from '#/screens/Login/SetNewPasswordForm'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {ChooseAccountForm} from './ChooseAccountForm' import {ChooseAccountForm} from './ChooseAccountForm'
import {ScreenTransition} from './ScreenTransition' import {ScreenTransition} from './ScreenTransition'
@@ -22,16 +18,12 @@ import {ScreenTransition} from './ScreenTransition'
enum Forms { enum Forms {
Login, Login,
ChooseAccount, ChooseAccount,
ForgotPassword,
SetNewPassword,
PasswordUpdated,
} }
export const Login = ({onPressBack}: {onPressBack: () => void}) => { export const Login = ({onPressBack}: {onPressBack: () => void}) => {
const {_} = useLingui() const {_} = useLingui()
const {accounts} = useSession() const {accounts} = useSession()
const {track} = useAnalytics()
const {requestedAccountSwitchTo} = useLoggedOutView() const {requestedAccountSwitchTo} = useLoggedOutView()
const requestedAccount = accounts.find( const requestedAccount = accounts.find(
acc => acc.did === requestedAccountSwitchTo, acc => acc.did === requestedAccountSwitchTo,
@@ -41,9 +33,6 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
const [serviceUrl, setServiceUrl] = React.useState<string>( const [serviceUrl, setServiceUrl] = React.useState<string>(
requestedAccount?.service || DEFAULT_SERVICE, requestedAccount?.service || DEFAULT_SERVICE,
) )
const [initialHandle, setInitialHandle] = React.useState<string>(
requestedAccount?.handle || '',
)
const [currentForm, setCurrentForm] = React.useState<Forms>( const [currentForm, setCurrentForm] = React.useState<Forms>(
requestedAccount requestedAccount
? Forms.Login ? Forms.Login
@@ -62,7 +51,7 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
if (account?.service) { if (account?.service) {
setServiceUrl(account.service) setServiceUrl(account.service)
} }
setInitialHandle(account?.handle || '') // TODO set the service URL. We really need to fix this though in general
setCurrentForm(Forms.Login) setCurrentForm(Forms.Login)
} }
@@ -86,11 +75,6 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
} }
}, [serviceError, serviceUrl, _]) }, [serviceError, serviceUrl, _])
const onPressForgotPassword = () => {
track('Signin:PressedForgotPassword')
setCurrentForm(Forms.ForgotPassword)
}
let content = null let content = null
let title = '' let title = ''
let description = '' let description = ''
@@ -104,13 +88,11 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
error={error} error={error}
serviceUrl={serviceUrl} serviceUrl={serviceUrl}
serviceDescription={serviceDescription} serviceDescription={serviceDescription}
initialHandle={initialHandle}
setError={setError} setError={setError}
setServiceUrl={setServiceUrl} setServiceUrl={setServiceUrl}
onPressBack={() => onPressBack={() =>
accounts.length ? gotoForm(Forms.ChooseAccount) : onPressBack() accounts.length ? gotoForm(Forms.ChooseAccount) : onPressBack()
} }
onPressForgotPassword={onPressForgotPassword}
onPressRetryConnect={refetchService} onPressRetryConnect={refetchService}
/> />
) )
@@ -125,41 +107,6 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
/> />
) )
break break
case Forms.ForgotPassword:
title = _(msg`Forgot Password`)
description = _(msg`Let's get your password reset!`)
content = (
<ForgotPasswordForm
error={error}
serviceUrl={serviceUrl}
serviceDescription={serviceDescription}
setError={setError}
setServiceUrl={setServiceUrl}
onPressBack={() => gotoForm(Forms.Login)}
onEmailSent={() => gotoForm(Forms.SetNewPassword)}
/>
)
break
case Forms.SetNewPassword:
title = _(msg`Forgot Password`)
description = _(msg`Let's get your password reset!`)
content = (
<SetNewPasswordForm
error={error}
serviceUrl={serviceUrl}
setError={setError}
onPressBack={() => gotoForm(Forms.ForgotPassword)}
onPasswordSet={() => gotoForm(Forms.PasswordUpdated)}
/>
)
break
case Forms.PasswordUpdated:
title = _(msg`Password updated`)
description = _(msg`You can now sign in with your new password.`)
content = (
<PasswordUpdatedForm onPressNext={() => gotoForm(Forms.Login)} />
)
break
} }
return ( return (