From 70dbc94766b8f3c9d2c1b815fad66232523d28ab Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 23 Apr 2025 19:22:08 +0300 Subject: Modernise change email flow (#8106) * use new verify email dialog in 2fa flow * alf change email flow * Fallback change email dialog * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update ChangeEmailDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update Email2FAToggle.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * don't use existing email as default value * increase max width of email dialogs * Use ALF verify email dialog for reminder (#5924) * use new verify email dialog for reminder * style tweaks, improve web * add a lil toast * Apply suggestions from code review Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Ditch close and push up image --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey * delete old change/verify email modals (#8122) (cherry picked from commit fceb655b3bacad1bce210810234137b7233d263d) * Translate email placeholder Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Align copy * Clean up error handling --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey --- src/components/dialogs/ChangeEmailDialog.tsx | 259 +++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/components/dialogs/ChangeEmailDialog.tsx (limited to 'src/components/dialogs/ChangeEmailDialog.tsx') diff --git a/src/components/dialogs/ChangeEmailDialog.tsx b/src/components/dialogs/ChangeEmailDialog.tsx new file mode 100644 index 000000000..93397bae9 --- /dev/null +++ b/src/components/dialogs/ChangeEmailDialog.tsx @@ -0,0 +1,259 @@ +import {useState} from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {cleanError} from '#/lib/strings/errors' +import {useAgent, useSession} from '#/state/session' +import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' +import {atoms as a, useBreakpoints, web} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import * as TextField from '#/components/forms/TextField' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' + +export function ChangeEmailDialog({ + control, + verifyEmailControl, +}: { + control: Dialog.DialogControlProps + verifyEmailControl: Dialog.DialogControlProps +}) { + return ( + + + + + ) +} + +export function Inner({ + verifyEmailControl, +}: { + verifyEmailControl: Dialog.DialogControlProps +}) { + const {_} = useLingui() + const {currentAccount} = useSession() + const agent = useAgent() + const control = Dialog.useDialogContext() + const {gtMobile} = useBreakpoints() + + const [currentStep, setCurrentStep] = useState< + 'StepOne' | 'StepTwo' | 'StepThree' + >('StepOne') + const [email, setEmail] = useState('') + const [confirmationCode, setConfirmationCode] = useState('') + const [isProcessing, setIsProcessing] = useState(false) + const [error, setError] = useState('') + + const currentEmail = currentAccount?.email || '(no email)' + const uiStrings = { + StepOne: { + title: _(msg`Change Your Email`), + message: '', + }, + StepTwo: { + title: _(msg`Security Step Required`), + message: _( + msg`An email has been sent to your previous address, ${currentEmail}. It includes a confirmation code which you can enter below.`, + ), + }, + StepThree: { + title: _(msg`Email Updated!`), + message: _( + msg`Your email address has been updated but it is not yet verified. As a next step, please verify your new email.`, + ), + }, + } + + const onRequestChange = async () => { + if (email === currentAccount?.email) { + setError( + _( + msg`The email address you entered is the same as your current email address.`, + ), + ) + return + } + setError('') + setIsProcessing(true) + try { + const res = await agent.com.atproto.server.requestEmailUpdate() + if (res.data.tokenRequired) { + setCurrentStep('StepTwo') + } else { + await agent.com.atproto.server.updateEmail({email: email.trim()}) + await agent.resumeSession(agent.session!) + setCurrentStep('StepThree') + } + } catch (e) { + setError(cleanError(String(e))) + } finally { + setIsProcessing(false) + } + } + + const onConfirm = async () => { + setError('') + setIsProcessing(true) + try { + await agent.com.atproto.server.updateEmail({ + email: email.trim(), + token: confirmationCode.trim(), + }) + await agent.resumeSession(agent.session!) + setCurrentStep('StepThree') + } catch (e) { + setError(cleanError(String(e))) + } finally { + setIsProcessing(false) + } + } + + const onVerify = async () => { + control.close(() => { + verifyEmailControl.open() + }) + } + + return ( + + + + + + {uiStrings[currentStep].title} + + {error ? ( + + + + ) : null} + {currentStep === 'StepOne' ? ( + + + Enter your new email address below. + + + + + + ) : ( + + {uiStrings[currentStep].message} + + )} + + {currentStep === 'StepTwo' ? ( + + + Confirmation code + + + + + + ) : null} + + {currentStep === 'StepOne' ? ( + <> + + + + ) : currentStep === 'StepTwo' ? ( + <> + + + + ) : currentStep === 'StepThree' ? ( + <> + + + + ) : null} + + + + ) +} -- cgit 1.4.1