import React, {useState} from 'react' import {ActivityIndicator, SafeAreaView, StyleSheet, View} from 'react-native' import {ScrollView, TextInput} from './util' import {observer} from 'mobx-react-lite' import {Text} from '../util/text/Text' import {Button} from '../util/forms/Button' import {ErrorMessage} from '../util/error/ErrorMessage' import * as Toast from '../util/Toast' import {useStores} from 'state/index' import {s, colors} from 'lib/styles' import {usePalette} from 'lib/hooks/usePalette' import {isWeb} from 'platform/detection' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {cleanError} from 'lib/strings/errors' import {useModalControls} from '#/state/modals' enum Stages { InputEmail, ConfirmCode, Done, } export const snapPoints = ['90%'] export const Component = observer(function Component({}: {}) { const pal = usePalette('default') const store = useStores() const [stage, setStage] = useState(Stages.InputEmail) const [email, setEmail] = useState( store.session.currentSession?.email || '', ) const [confirmationCode, setConfirmationCode] = useState('') const [isProcessing, setIsProcessing] = useState(false) const [error, setError] = useState('') const {isMobile} = useWebMediaQueries() const {openModal, closeModal} = useModalControls() const onRequestChange = async () => { if (email === store.session.currentSession?.email) { setError('Enter your new email above') return } setError('') setIsProcessing(true) try { const res = await store.agent.com.atproto.server.requestEmailUpdate() if (res.data.tokenRequired) { setStage(Stages.ConfirmCode) } else { await store.agent.com.atproto.server.updateEmail({email: email.trim()}) store.session.updateLocalAccountData({ email: email.trim(), emailConfirmed: false, }) Toast.show('Email updated') setStage(Stages.Done) } } catch (e) { let err = cleanError(String(e)) // TEMP // while rollout is occuring, we're giving a temporary error message // you can remove this any time after Oct2023 // -prf if (err === 'email must be confirmed (temporary)') { err = `Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed.` } setError(err) } finally { setIsProcessing(false) } } const onConfirm = async () => { setError('') setIsProcessing(true) try { await store.agent.com.atproto.server.updateEmail({ email: email.trim(), token: confirmationCode.trim(), }) store.session.updateLocalAccountData({ email: email.trim(), emailConfirmed: false, }) Toast.show('Email updated') setStage(Stages.Done) } catch (e) { setError(cleanError(String(e))) } finally { setIsProcessing(false) } } const onVerify = async () => { closeModal() openModal({name: 'verify-email'}) } return ( {stage === Stages.InputEmail ? 'Change Your Email' : ''} {stage === Stages.ConfirmCode ? 'Security Step Required' : ''} {stage === Stages.Done ? 'Email Updated' : ''} {stage === Stages.InputEmail ? ( <>Enter your new email address below. ) : stage === Stages.ConfirmCode ? ( <> An email has been sent to your previous address,{' '} {store.session.currentSession?.email || ''}. It includes a confirmation code which you can enter below. ) : ( <> Your email has been updated but not verified. As a next step, please verify your new email. )} {stage === Stages.InputEmail && ( )} {stage === Stages.ConfirmCode && ( )} {error ? ( ) : undefined} {isProcessing ? ( ) : ( {stage === Stages.InputEmail && (