Fix keyboard double pad issue in email change & verify modals (#1664)

zio/stable
Paul Frazee 2023-10-10 14:02:31 -07:00 committed by GitHub
parent fc28fc639f
commit e878da04a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 259 additions and 284 deletions

View File

@ -1,11 +1,5 @@
import React, {useState} from 'react' import React, {useState} from 'react'
import { import {ActivityIndicator, SafeAreaView, StyleSheet, View} from 'react-native'
ActivityIndicator,
KeyboardAvoidingView,
SafeAreaView,
StyleSheet,
View,
} from 'react-native'
import {ScrollView, TextInput} from './util' import {ScrollView, TextInput} from './util'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
@ -101,142 +95,134 @@ export const Component = observer(function Component({}: {}) {
} }
return ( return (
<KeyboardAvoidingView <SafeAreaView style={[pal.view, s.flex1]}>
behavior="padding" <ScrollView
style={[pal.view, styles.container]}> testID="changeEmailModal"
<SafeAreaView style={s.flex1}> style={[s.flex1, isMobile && {paddingHorizontal: 18}]}>
<ScrollView <View style={styles.titleSection}>
testID="changeEmailModal" <Text type="title-lg" style={[pal.text, styles.title]}>
style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> {stage === Stages.InputEmail ? 'Change Your Email' : ''}
<View style={styles.titleSection}> {stage === Stages.ConfirmCode ? 'Security Step Required' : ''}
<Text type="title-lg" style={[pal.text, styles.title]}> {stage === Stages.Done ? 'Email Updated' : ''}
{stage === Stages.InputEmail ? 'Change Your Email' : ''}
{stage === Stages.ConfirmCode ? 'Security Step Required' : ''}
{stage === Stages.Done ? 'Email Updated' : ''}
</Text>
</View>
<Text type="lg" style={[pal.textLight, {marginBottom: 10}]}>
{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.
</>
)}
</Text> </Text>
</View>
{stage === Stages.InputEmail && ( <Text type="lg" style={[pal.textLight, {marginBottom: 10}]}>
<TextInput {stage === Stages.InputEmail ? (
testID="emailInput" <>Enter your new email address below.</>
style={[styles.textInput, pal.border, pal.text]} ) : stage === Stages.ConfirmCode ? (
placeholder="alice@mail.com" <>
placeholderTextColor={pal.colors.textLight} An email has been sent to your previous address,{' '}
value={email} {store.session.currentSession?.email || ''}. It includes a
onChangeText={setEmail} confirmation code which you can enter below.
accessible={true} </>
accessibilityLabel="Email" ) : (
accessibilityHint="" <>
autoCapitalize="none" Your email has been updated but not verified. As a next step,
autoComplete="email" please verify your new email.
autoCorrect={false} </>
/>
)}
{stage === Stages.ConfirmCode && (
<TextInput
testID="confirmCodeInput"
style={[styles.textInput, pal.border, pal.text]}
placeholder="XXXXX-XXXXX"
placeholderTextColor={pal.colors.textLight}
value={confirmationCode}
onChangeText={setConfirmationCode}
accessible={true}
accessibilityLabel="Confirmation code"
accessibilityHint=""
autoCapitalize="none"
autoComplete="off"
autoCorrect={false}
/>
)} )}
</Text>
{error ? ( {stage === Stages.InputEmail && (
<ErrorMessage message={error} style={styles.error} /> <TextInput
) : undefined} testID="emailInput"
style={[styles.textInput, pal.border, pal.text]}
placeholder="alice@mail.com"
placeholderTextColor={pal.colors.textLight}
value={email}
onChangeText={setEmail}
accessible={true}
accessibilityLabel="Email"
accessibilityHint=""
autoCapitalize="none"
autoComplete="email"
autoCorrect={false}
/>
)}
{stage === Stages.ConfirmCode && (
<TextInput
testID="confirmCodeInput"
style={[styles.textInput, pal.border, pal.text]}
placeholder="XXXXX-XXXXX"
placeholderTextColor={pal.colors.textLight}
value={confirmationCode}
onChangeText={setConfirmationCode}
accessible={true}
accessibilityLabel="Confirmation code"
accessibilityHint=""
autoCapitalize="none"
autoComplete="off"
autoCorrect={false}
/>
)}
<View style={[styles.btnContainer]}> {error ? (
{isProcessing ? ( <ErrorMessage message={error} style={styles.error} />
<View style={styles.btn}> ) : undefined}
<ActivityIndicator color="#fff" />
</View> <View style={[styles.btnContainer]}>
) : ( {isProcessing ? (
<View style={{gap: 6}}> <View style={styles.btn}>
{stage === Stages.InputEmail && ( <ActivityIndicator color="#fff" />
<Button </View>
testID="requestChangeBtn" ) : (
type="primary" <View style={{gap: 6}}>
onPress={onRequestChange} {stage === Stages.InputEmail && (
accessibilityLabel="Request Change"
accessibilityHint=""
label="Request Change"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
{stage === Stages.ConfirmCode && (
<Button
testID="confirmBtn"
type="primary"
onPress={onConfirm}
accessibilityLabel="Confirm Change"
accessibilityHint=""
label="Confirm Change"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
{stage === Stages.Done && (
<Button
testID="verifyBtn"
type="primary"
onPress={onVerify}
accessibilityLabel="Verify New Email"
accessibilityHint=""
label="Verify New Email"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
<Button <Button
testID="cancelBtn" testID="requestChangeBtn"
type="default" type="primary"
onPress={() => store.shell.closeModal()} onPress={onRequestChange}
accessibilityLabel="Cancel" accessibilityLabel="Request Change"
accessibilityHint="" accessibilityHint=""
label="Cancel" label="Request Change"
labelContainerStyle={{justifyContent: 'center', padding: 4}} labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]} labelStyle={[s.f18]}
/> />
</View> )}
)} {stage === Stages.ConfirmCode && (
</View> <Button
</ScrollView> testID="confirmBtn"
</SafeAreaView> type="primary"
</KeyboardAvoidingView> onPress={onConfirm}
accessibilityLabel="Confirm Change"
accessibilityHint=""
label="Confirm Change"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
{stage === Stages.Done && (
<Button
testID="verifyBtn"
type="primary"
onPress={onVerify}
accessibilityLabel="Verify New Email"
accessibilityHint=""
label="Verify New Email"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
<Button
testID="cancelBtn"
type="default"
onPress={() => store.shell.closeModal()}
accessibilityLabel="Cancel"
accessibilityHint=""
label="Cancel"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
</View>
)}
</View>
</ScrollView>
</SafeAreaView>
) )
}) })
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isWeb ? 0 : 40,
},
titleSection: { titleSection: {
paddingTop: isWeb ? 0 : 4, paddingTop: isWeb ? 0 : 4,
paddingBottom: isWeb ? 14 : 10, paddingBottom: isWeb ? 14 : 10,

View File

@ -1,7 +1,6 @@
import React, {useState} from 'react' import React, {useState} from 'react'
import { import {
ActivityIndicator, ActivityIndicator,
KeyboardAvoidingView,
Pressable, Pressable,
SafeAreaView, SafeAreaView,
StyleSheet, StyleSheet,
@ -82,169 +81,163 @@ export const Component = observer(function Component({
} }
return ( return (
<KeyboardAvoidingView <SafeAreaView style={[pal.view, s.flex1]}>
behavior="padding" <ScrollView
style={[pal.view, styles.container]}> testID="verifyEmailModal"
<SafeAreaView style={s.flex1}> style={[s.flex1, isMobile && {paddingHorizontal: 18}]}>
<ScrollView {stage === Stages.Reminder && <ReminderIllustration />}
testID="verifyEmailModal" <View style={styles.titleSection}>
style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> <Text type="title-lg" style={[pal.text, styles.title]}>
{stage === Stages.Reminder && <ReminderIllustration />} {stage === Stages.Reminder ? 'Please Verify Your Email' : ''}
<View style={styles.titleSection}> {stage === Stages.ConfirmCode ? 'Enter Confirmation Code' : ''}
<Text type="title-lg" style={[pal.text, styles.title]}> {stage === Stages.Email ? 'Verify Your Email' : ''}
{stage === Stages.Reminder ? 'Please Verify Your Email' : ''}
{stage === Stages.ConfirmCode ? 'Enter Confirmation Code' : ''}
{stage === Stages.Email ? 'Verify Your Email' : ''}
</Text>
</View>
<Text type="lg" style={[pal.textLight, {marginBottom: 10}]}>
{stage === Stages.Reminder ? (
<>
Your email has not yet been verified. This is an important
security step which we recommend.
</>
) : stage === Stages.Email ? (
<>
This is important in case you ever need to change your email or
reset your password.
</>
) : stage === Stages.ConfirmCode ? (
<>
An email has been sent to{' '}
{store.session.currentSession?.email || ''}. It includes a
confirmation code which you can enter below.
</>
) : (
''
)}
</Text> </Text>
</View>
{stage === Stages.Email ? ( <Text type="lg" style={[pal.textLight, {marginBottom: 10}]}>
{stage === Stages.Reminder ? (
<> <>
<View style={styles.emailContainer}> Your email has not yet been verified. This is an important
<FontAwesomeIcon security step which we recommend.
icon="envelope" </>
color={pal.colors.text} ) : stage === Stages.Email ? (
size={16} <>
/> This is important in case you ever need to change your email or
<Text reset your password.
type="xl-medium"
style={[pal.text, s.flex1, {minWidth: 0}]}>
{store.session.currentSession?.email || ''}
</Text>
</View>
<Pressable
accessibilityRole="link"
accessibilityLabel="Change my email"
accessibilityHint=""
onPress={onEmailIncorrect}
style={styles.changeEmailLink}>
<Text type="lg" style={pal.link}>
Change
</Text>
</Pressable>
</> </>
) : stage === Stages.ConfirmCode ? ( ) : stage === Stages.ConfirmCode ? (
<TextInput <>
testID="confirmCodeInput" An email has been sent to{' '}
style={[styles.textInput, pal.border, pal.text]} {store.session.currentSession?.email || ''}. It includes a
placeholder="XXXXX-XXXXX" confirmation code which you can enter below.
placeholderTextColor={pal.colors.textLight} </>
value={confirmationCode} ) : (
onChangeText={setConfirmationCode} ''
accessible={true} )}
accessibilityLabel="Confirmation code" </Text>
{stage === Stages.Email ? (
<>
<View style={styles.emailContainer}>
<FontAwesomeIcon
icon="envelope"
color={pal.colors.text}
size={16}
/>
<Text type="xl-medium" style={[pal.text, s.flex1, {minWidth: 0}]}>
{store.session.currentSession?.email || ''}
</Text>
</View>
<Pressable
accessibilityRole="link"
accessibilityLabel="Change my email"
accessibilityHint="" accessibilityHint=""
autoCapitalize="none" onPress={onEmailIncorrect}
autoComplete="off" style={styles.changeEmailLink}>
autoCorrect={false} <Text type="lg" style={pal.link}>
/> Change
) : undefined} </Text>
</Pressable>
</>
) : stage === Stages.ConfirmCode ? (
<TextInput
testID="confirmCodeInput"
style={[styles.textInput, pal.border, pal.text]}
placeholder="XXXXX-XXXXX"
placeholderTextColor={pal.colors.textLight}
value={confirmationCode}
onChangeText={setConfirmationCode}
accessible={true}
accessibilityLabel="Confirmation code"
accessibilityHint=""
autoCapitalize="none"
autoComplete="off"
autoCorrect={false}
/>
) : undefined}
{error ? ( {error ? (
<ErrorMessage message={error} style={styles.error} /> <ErrorMessage message={error} style={styles.error} />
) : undefined} ) : undefined}
<View style={[styles.btnContainer]}> <View style={[styles.btnContainer]}>
{isProcessing ? ( {isProcessing ? (
<View style={styles.btn}> <View style={styles.btn}>
<ActivityIndicator color="#fff" /> <ActivityIndicator color="#fff" />
</View> </View>
) : ( ) : (
<View style={{gap: 6}}> <View style={{gap: 6}}>
{stage === Stages.Reminder && ( {stage === Stages.Reminder && (
<Button
testID="getStartedBtn"
type="primary"
onPress={() => setStage(Stages.Email)}
accessibilityLabel="Get Started"
accessibilityHint=""
label="Get Started"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
{stage === Stages.Email && (
<>
<Button
testID="sendEmailBtn"
type="primary"
onPress={onSendEmail}
accessibilityLabel="Send Confirmation Email"
accessibilityHint=""
label="Send Confirmation Email"
labelContainerStyle={{
justifyContent: 'center',
padding: 4,
}}
labelStyle={[s.f18]}
/>
<Button
testID="haveCodeBtn"
type="default"
accessibilityLabel="I have a code"
accessibilityHint=""
label="I have a confirmation code"
labelContainerStyle={{
justifyContent: 'center',
padding: 4,
}}
labelStyle={[s.f18]}
onPress={() => setStage(Stages.ConfirmCode)}
/>
</>
)}
{stage === Stages.ConfirmCode && (
<Button
testID="confirmBtn"
type="primary"
onPress={onConfirm}
accessibilityLabel="Confirm"
accessibilityHint=""
label="Confirm"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
<Button <Button
testID="cancelBtn" testID="getStartedBtn"
type="default" type="primary"
onPress={() => store.shell.closeModal()} onPress={() => setStage(Stages.Email)}
accessibilityLabel={ accessibilityLabel="Get Started"
stage === Stages.Reminder ? 'Not right now' : 'Cancel'
}
accessibilityHint="" accessibilityHint=""
label={stage === Stages.Reminder ? 'Not right now' : 'Cancel'} label="Get Started"
labelContainerStyle={{justifyContent: 'center', padding: 4}} labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]} labelStyle={[s.f18]}
/> />
</View> )}
)} {stage === Stages.Email && (
</View> <>
</ScrollView> <Button
</SafeAreaView> testID="sendEmailBtn"
</KeyboardAvoidingView> type="primary"
onPress={onSendEmail}
accessibilityLabel="Send Confirmation Email"
accessibilityHint=""
label="Send Confirmation Email"
labelContainerStyle={{
justifyContent: 'center',
padding: 4,
}}
labelStyle={[s.f18]}
/>
<Button
testID="haveCodeBtn"
type="default"
accessibilityLabel="I have a code"
accessibilityHint=""
label="I have a confirmation code"
labelContainerStyle={{
justifyContent: 'center',
padding: 4,
}}
labelStyle={[s.f18]}
onPress={() => setStage(Stages.ConfirmCode)}
/>
</>
)}
{stage === Stages.ConfirmCode && (
<Button
testID="confirmBtn"
type="primary"
onPress={onConfirm}
accessibilityLabel="Confirm"
accessibilityHint=""
label="Confirm"
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
)}
<Button
testID="cancelBtn"
type="default"
onPress={() => store.shell.closeModal()}
accessibilityLabel={
stage === Stages.Reminder ? 'Not right now' : 'Cancel'
}
accessibilityHint=""
label={stage === Stages.Reminder ? 'Not right now' : 'Cancel'}
labelContainerStyle={{justifyContent: 'center', padding: 4}}
labelStyle={[s.f18]}
/>
</View>
)}
</View>
</ScrollView>
</SafeAreaView>
) )
}) })
@ -274,10 +267,6 @@ function ReminderIllustration() {
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: {
flex: 1,
paddingBottom: isWeb ? 0 : 40,
},
titleSection: { titleSection: {
paddingTop: isWeb ? 0 : 4, paddingTop: isWeb ? 0 : 4,
paddingBottom: isWeb ? 14 : 10, paddingBottom: isWeb ? 14 : 10,