diff options
Diffstat (limited to 'src/view/com/modals')
-rw-r--r-- | src/view/com/modals/ChangeEmail.tsx | 244 | ||||
-rw-r--r-- | src/view/com/modals/CreateOrEditMuteList.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/EditProfile.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.tsx | 20 | ||||
-rw-r--r-- | src/view/com/modals/ProfilePreview.tsx | 11 | ||||
-rw-r--r-- | src/view/com/modals/SwitchAccount.tsx | 113 | ||||
-rw-r--r-- | src/view/com/modals/VerifyEmail.tsx | 281 | ||||
-rw-r--r-- | src/view/com/modals/Waitlist.tsx | 2 | ||||
-rw-r--r-- | src/view/com/modals/crop-image/CropImage.web.tsx | 6 |
9 files changed, 330 insertions, 355 deletions
diff --git a/src/view/com/modals/ChangeEmail.tsx b/src/view/com/modals/ChangeEmail.tsx index c92dabdca..012570556 100644 --- a/src/view/com/modals/ChangeEmail.tsx +++ b/src/view/com/modals/ChangeEmail.tsx @@ -1,11 +1,5 @@ import React, {useState} from 'react' -import { - ActivityIndicator, - KeyboardAvoidingView, - SafeAreaView, - StyleSheet, - View, -} from 'react-native' +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' @@ -101,142 +95,134 @@ export const Component = observer(function Component({}: {}) { } return ( - <KeyboardAvoidingView - behavior="padding" - style={[pal.view, styles.container]}> - <SafeAreaView style={s.flex1}> - <ScrollView - testID="changeEmailModal" - style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> - <View style={styles.titleSection}> - <Text type="title-lg" style={[pal.text, styles.title]}> - {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. - </> - )} + <SafeAreaView style={[pal.view, s.flex1]}> + <ScrollView + testID="changeEmailModal" + style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> + <View style={styles.titleSection}> + <Text type="title-lg" style={[pal.text, styles.title]}> + {stage === Stages.InputEmail ? 'Change Your Email' : ''} + {stage === Stages.ConfirmCode ? 'Security Step Required' : ''} + {stage === Stages.Done ? 'Email Updated' : ''} </Text> + </View> - {stage === Stages.InputEmail && ( - <TextInput - 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} - /> + <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> - {error ? ( - <ErrorMessage message={error} style={styles.error} /> - ) : undefined} + {stage === Stages.InputEmail && ( + <TextInput + 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]}> - {isProcessing ? ( - <View style={styles.btn}> - <ActivityIndicator color="#fff" /> - </View> - ) : ( - <View style={{gap: 6}}> - {stage === Stages.InputEmail && ( - <Button - testID="requestChangeBtn" - type="primary" - onPress={onRequestChange} - 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]} - /> - )} + {error ? ( + <ErrorMessage message={error} style={styles.error} /> + ) : undefined} + + <View style={[styles.btnContainer]}> + {isProcessing ? ( + <View style={styles.btn}> + <ActivityIndicator color="#fff" /> + </View> + ) : ( + <View style={{gap: 6}}> + {stage === Stages.InputEmail && ( + <Button + testID="requestChangeBtn" + type="primary" + onPress={onRequestChange} + accessibilityLabel="Request Change" + accessibilityHint="" + label="Request Change" + labelContainerStyle={{justifyContent: 'center', padding: 4}} + labelStyle={[s.f18]} + /> + )} + {stage === Stages.ConfirmCode && ( <Button - testID="cancelBtn" - type="default" - onPress={() => store.shell.closeModal()} - accessibilityLabel="Cancel" + testID="confirmBtn" + type="primary" + onPress={onConfirm} + accessibilityLabel="Confirm Change" accessibilityHint="" - label="Cancel" + label="Confirm Change" labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} /> - </View> - )} - </View> - </ScrollView> - </SafeAreaView> - </KeyboardAvoidingView> + )} + {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({ - container: { - flex: 1, - paddingBottom: isWeb ? 0 : 40, - }, titleSection: { paddingTop: isWeb ? 0 : 4, paddingBottom: isWeb ? 14 : 10, diff --git a/src/view/com/modals/CreateOrEditMuteList.tsx b/src/view/com/modals/CreateOrEditMuteList.tsx index 3f3cfc5f0..4a440afeb 100644 --- a/src/view/com/modals/CreateOrEditMuteList.tsx +++ b/src/view/com/modals/CreateOrEditMuteList.tsx @@ -18,7 +18,7 @@ import {ListModel} from 'state/models/content/list' import {s, colors, gradients} from 'lib/styles' import {enforceLen} from 'lib/strings/helpers' import {compressIfNeeded} from 'lib/media/manip' -import {UserAvatar} from '../util/UserAvatar' +import {EditableUserAvatar} from '../util/UserAvatar' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' import {useAnalytics} from 'lib/analytics/analytics' @@ -148,7 +148,7 @@ export function Component({ )} <Text style={[styles.label, pal.text]}>List Avatar</Text> <View style={[styles.avi, {borderColor: pal.colors.background}]}> - <UserAvatar + <EditableUserAvatar type="list" size={80} avatar={avatar} diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index 620aad9fc..58d0857ad 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -20,7 +20,7 @@ import {enforceLen} from 'lib/strings/helpers' import {MAX_DISPLAY_NAME, MAX_DESCRIPTION} from 'lib/constants' import {compressIfNeeded} from 'lib/media/manip' import {UserBanner} from '../util/UserBanner' -import {UserAvatar} from '../util/UserAvatar' +import {EditableUserAvatar} from '../util/UserAvatar' import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' import {useAnalytics} from 'lib/analytics/analytics' @@ -153,7 +153,7 @@ export function Component({ onSelectNewBanner={onSelectNewBanner} /> <View style={[styles.avi, {borderColor: pal.colors.background}]}> - <UserAvatar + <EditableUserAvatar size={80} avatar={userAvatar} onSelectNewAvatar={onSelectNewAvatar} diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 4f3f424a3..1fe1299d7 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -1,11 +1,12 @@ import React, {useRef, useEffect} from 'react' import {StyleSheet} from 'react-native' -import {SafeAreaView} from 'react-native-safe-area-context' +import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context' import {observer} from 'mobx-react-lite' import BottomSheet from '@gorhom/bottom-sheet' import {useStores} from 'state/index' import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' import {usePalette} from 'lib/hooks/usePalette' +import {timeout} from 'lib/async/timeout' import {navigate} from '../../../Navigation' import once from 'lodash.once' @@ -36,11 +37,13 @@ import * as SwitchAccountModal from './SwitchAccount' import * as LinkWarningModal from './LinkWarning' const DEFAULT_SNAPPOINTS = ['90%'] +const HANDLE_HEIGHT = 24 export const ModalsContainer = observer(function ModalsContainer() { const store = useStores() const bottomSheetRef = useRef<BottomSheet>(null) const pal = usePalette('default') + const safeAreaInsets = useSafeAreaInsets() const activeModal = store.shell.activeModals[store.shell.activeModals.length - 1] @@ -53,12 +56,16 @@ export const ModalsContainer = observer(function ModalsContainer() { navigateOnce('Profile', {name: activeModal.did}) } } - const onBottomSheetChange = (snapPoint: number) => { + const onBottomSheetChange = async (snapPoint: number) => { if (snapPoint === -1) { store.shell.closeModal() } else if (activeModal?.name === 'profile-preview' && snapPoint === 1) { - // ensure we navigate to Profile and close the modal - navigateOnce('Profile', {name: activeModal.did}) + await navigateOnce('Profile', {name: activeModal.did}) + // There is no particular callback for when the view has actually been presented. + // This delay gives us a decent chance the navigation has flushed *and* images have loaded. + // It's acceptable because the data is already being fetched + it usually takes longer anyway. + // TODO: Figure out why avatar/cover don't always show instantly from cache. + await timeout(200) store.shell.closeModal() } } @@ -75,6 +82,7 @@ export const ModalsContainer = observer(function ModalsContainer() { } }, [store.shell.isModalActive, bottomSheetRef, activeModal?.name]) + let needsSafeTopInset = false let snapPoints: (string | number)[] = DEFAULT_SNAPPOINTS let element if (activeModal?.name === 'confirm') { @@ -86,6 +94,7 @@ export const ModalsContainer = observer(function ModalsContainer() { } else if (activeModal?.name === 'profile-preview') { snapPoints = ProfilePreviewModal.snapPoints element = <ProfilePreviewModal.Component {...activeModal} /> + needsSafeTopInset = true // Need to align with the target profile screen. } else if (activeModal?.name === 'server-input') { snapPoints = ServerInputModal.snapPoints element = <ServerInputModal.Component {...activeModal} /> @@ -164,10 +173,13 @@ export const ModalsContainer = observer(function ModalsContainer() { ) } + const topInset = needsSafeTopInset ? safeAreaInsets.top - HANDLE_HEIGHT : 0 return ( <BottomSheet ref={bottomSheetRef} snapPoints={snapPoints} + topInset={topInset} + handleHeight={HANDLE_HEIGHT} index={store.shell.isModalActive ? 0 : -1} enablePanDownToClose android_keyboardInputMode="adjustResize" diff --git a/src/view/com/modals/ProfilePreview.tsx b/src/view/com/modals/ProfilePreview.tsx index 225a3972b..dad02aa5e 100644 --- a/src/view/com/modals/ProfilePreview.tsx +++ b/src/view/com/modals/ProfilePreview.tsx @@ -9,7 +9,6 @@ import {useAnalytics} from 'lib/analytics/analytics' import {ProfileHeader} from '../profile/ProfileHeader' import {InfoCircleIcon} from 'lib/icons' import {useNavigationState} from '@react-navigation/native' -import {isIOS} from 'platform/detection' import {s} from 'lib/styles' export const snapPoints = [520, '100%'] @@ -36,11 +35,7 @@ export const Component = observer(function ProfilePreviewImpl({ return ( <View testID="profilePreview" style={[pal.view, s.flex1]}> - <View - style={[ - styles.headerWrapper, - isLoading && isIOS && styles.headerPositionAdjust, - ]}> + <View style={[styles.headerWrapper]}> <ProfileHeader view={model} hideBackButton @@ -70,10 +65,6 @@ const styles = StyleSheet.create({ headerWrapper: { height: 440, }, - headerPositionAdjust: { - // HACK align the header for the profilescreen transition -prf - paddingTop: 23, - }, hintWrapper: { height: 80, }, diff --git a/src/view/com/modals/SwitchAccount.tsx b/src/view/com/modals/SwitchAccount.tsx index 51d75e3ef..d5fa32692 100644 --- a/src/view/com/modals/SwitchAccount.tsx +++ b/src/view/com/modals/SwitchAccount.tsx @@ -37,74 +37,69 @@ export function Component({}: {}) { }, [track, store]) return ( - <View style={[styles.container, pal.view]}> + <BottomSheetScrollView + style={[styles.container, pal.view]} + contentContainerStyle={[styles.innerContainer, pal.view]}> <Text type="title-xl" style={[styles.title, pal.text]}> Switch Account </Text> - <BottomSheetScrollView - style={styles.container} - contentContainerStyle={[styles.innerContainer, pal.view]}> - {isSwitching ? ( + {isSwitching ? ( + <View style={[pal.view, styles.linkCard]}> + <ActivityIndicator /> + </View> + ) : ( + <Link href={makeProfileLink(store.me)} title="Your profile" noFeedback> <View style={[pal.view, styles.linkCard]}> - <ActivityIndicator /> - </View> - ) : ( - <Link - href={makeProfileLink(store.me)} - title="Your profile" - noFeedback> - <View style={[pal.view, styles.linkCard]}> - <View style={styles.avi}> - <UserAvatar size={40} avatar={store.me.avatar} /> - </View> - <View style={[s.flex1]}> - <Text type="md-bold" style={pal.text} numberOfLines={1}> - {store.me.displayName || store.me.handle} - </Text> - <Text type="sm" style={pal.textLight} numberOfLines={1}> - {store.me.handle} - </Text> - </View> - <TouchableOpacity - testID="signOutBtn" - onPress={isSwitching ? undefined : onPressSignout} - accessibilityRole="button" - accessibilityLabel="Sign out" - accessibilityHint={`Signs ${store.me.displayName} out of Bluesky`}> - <Text type="lg" style={pal.link}> - Sign out - </Text> - </TouchableOpacity> - </View> - </Link> - )} - {store.session.switchableAccounts.map(account => ( - <TouchableOpacity - testID={`switchToAccountBtn-${account.handle}`} - key={account.did} - style={[pal.view, styles.linkCard, isSwitching && styles.dimmed]} - onPress={ - isSwitching ? undefined : () => onPressSwitchAccount(account) - } - accessibilityRole="button" - accessibilityLabel={`Switch to ${account.handle}`} - accessibilityHint="Switches the account you are logged in to"> <View style={styles.avi}> - <UserAvatar size={40} avatar={account.aviUrl} /> + <UserAvatar size={40} avatar={store.me.avatar} /> </View> <View style={[s.flex1]}> - <Text type="md-bold" style={pal.text}> - {account.displayName || account.handle} + <Text type="md-bold" style={pal.text} numberOfLines={1}> + {store.me.displayName || store.me.handle} </Text> - <Text type="sm" style={pal.textLight}> - {account.handle} + <Text type="sm" style={pal.textLight} numberOfLines={1}> + {store.me.handle} </Text> </View> - <AccountDropdownBtn handle={account.handle} /> - </TouchableOpacity> - ))} - </BottomSheetScrollView> - </View> + <TouchableOpacity + testID="signOutBtn" + onPress={isSwitching ? undefined : onPressSignout} + accessibilityRole="button" + accessibilityLabel="Sign out" + accessibilityHint={`Signs ${store.me.displayName} out of Bluesky`}> + <Text type="lg" style={pal.link}> + Sign out + </Text> + </TouchableOpacity> + </View> + </Link> + )} + {store.session.switchableAccounts.map(account => ( + <TouchableOpacity + testID={`switchToAccountBtn-${account.handle}`} + key={account.did} + style={[pal.view, styles.linkCard, isSwitching && styles.dimmed]} + onPress={ + isSwitching ? undefined : () => onPressSwitchAccount(account) + } + accessibilityRole="button" + accessibilityLabel={`Switch to ${account.handle}`} + accessibilityHint="Switches the account you are logged in to"> + <View style={styles.avi}> + <UserAvatar size={40} avatar={account.aviUrl} /> + </View> + <View style={[s.flex1]}> + <Text type="md-bold" style={pal.text}> + {account.displayName || account.handle} + </Text> + <Text type="sm" style={pal.textLight}> + {account.handle} + </Text> + </View> + <AccountDropdownBtn handle={account.handle} /> + </TouchableOpacity> + ))} + </BottomSheetScrollView> ) } @@ -113,7 +108,7 @@ const styles = StyleSheet.create({ flex: 1, }, innerContainer: { - paddingBottom: 20, + paddingBottom: 40, }, title: { textAlign: 'center', diff --git a/src/view/com/modals/VerifyEmail.tsx b/src/view/com/modals/VerifyEmail.tsx index 0a626a4ef..9fe8811b0 100644 --- a/src/view/com/modals/VerifyEmail.tsx +++ b/src/view/com/modals/VerifyEmail.tsx @@ -1,7 +1,6 @@ import React, {useState} from 'react' import { ActivityIndicator, - KeyboardAvoidingView, Pressable, SafeAreaView, StyleSheet, @@ -82,169 +81,163 @@ export const Component = observer(function Component({ } return ( - <KeyboardAvoidingView - behavior="padding" - style={[pal.view, styles.container]}> - <SafeAreaView style={s.flex1}> - <ScrollView - testID="verifyEmailModal" - style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> - {stage === Stages.Reminder && <ReminderIllustration />} - <View style={styles.titleSection}> - <Text type="title-lg" style={[pal.text, styles.title]}> - {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. - </> - ) : ( - '' - )} + <SafeAreaView style={[pal.view, s.flex1]}> + <ScrollView + testID="verifyEmailModal" + style={[s.flex1, isMobile && {paddingHorizontal: 18}]}> + {stage === Stages.Reminder && <ReminderIllustration />} + <View style={styles.titleSection}> + <Text type="title-lg" style={[pal.text, styles.title]}> + {stage === Stages.Reminder ? 'Please Verify Your Email' : ''} + {stage === Stages.ConfirmCode ? 'Enter Confirmation Code' : ''} + {stage === Stages.Email ? 'Verify Your Email' : ''} </Text> + </View> - {stage === Stages.Email ? ( + <Text type="lg" style={[pal.textLight, {marginBottom: 10}]}> + {stage === Stages.Reminder ? ( <> - <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="" - onPress={onEmailIncorrect} - style={styles.changeEmailLink}> - <Text type="lg" style={pal.link}> - Change - </Text> - </Pressable> + 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 ? ( - <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" + <> + An email has been sent to{' '} + {store.session.currentSession?.email || ''}. It includes a + confirmation code which you can enter below. + </> + ) : ( + '' + )} + </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="" - autoCapitalize="none" - autoComplete="off" - autoCorrect={false} - /> - ) : undefined} + onPress={onEmailIncorrect} + style={styles.changeEmailLink}> + <Text type="lg" style={pal.link}> + Change + </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 ? ( - <ErrorMessage message={error} style={styles.error} /> - ) : undefined} + {error ? ( + <ErrorMessage message={error} style={styles.error} /> + ) : undefined} - <View style={[styles.btnContainer]}> - {isProcessing ? ( - <View style={styles.btn}> - <ActivityIndicator color="#fff" /> - </View> - ) : ( - <View style={{gap: 6}}> - {stage === Stages.Reminder && ( + <View style={[styles.btnContainer]}> + {isProcessing ? ( + <View style={styles.btn}> + <ActivityIndicator color="#fff" /> + </View> + ) : ( + <View style={{gap: 6}}> + {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="getStartedBtn" + testID="sendEmailBtn" type="primary" - onPress={() => setStage(Stages.Email)} - accessibilityLabel="Get Started" + onPress={onSendEmail} + accessibilityLabel="Send Confirmation Email" accessibilityHint="" - label="Get Started" - labelContainerStyle={{justifyContent: 'center', padding: 4}} + label="Send Confirmation Email" + 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" + testID="haveCodeBtn" + type="default" + accessibilityLabel="I have a code" accessibilityHint="" - label="Confirm" - labelContainerStyle={{justifyContent: 'center', padding: 4}} + label="I have a confirmation code" + labelContainerStyle={{ + justifyContent: 'center', + padding: 4, + }} labelStyle={[s.f18]} + onPress={() => setStage(Stages.ConfirmCode)} /> - )} + </> + )} + {stage === Stages.ConfirmCode && ( <Button - testID="cancelBtn" - type="default" - onPress={() => store.shell.closeModal()} - accessibilityLabel={ - stage === Stages.Reminder ? 'Not right now' : 'Cancel' - } + testID="confirmBtn" + type="primary" + onPress={onConfirm} + accessibilityLabel="Confirm" accessibilityHint="" - label={stage === Stages.Reminder ? 'Not right now' : 'Cancel'} + label="Confirm" labelContainerStyle={{justifyContent: 'center', padding: 4}} labelStyle={[s.f18]} /> - </View> - )} - </View> - </ScrollView> - </SafeAreaView> - </KeyboardAvoidingView> + )} + <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({ - container: { - flex: 1, - paddingBottom: isWeb ? 0 : 40, - }, titleSection: { paddingTop: isWeb ? 0 : 4, paddingBottom: isWeb ? 14 : 10, diff --git a/src/view/com/modals/Waitlist.tsx b/src/view/com/modals/Waitlist.tsx index 1104c0a39..0fb371fe4 100644 --- a/src/view/com/modals/Waitlist.tsx +++ b/src/view/com/modals/Waitlist.tsx @@ -77,6 +77,8 @@ export function Component({}: {}) { keyboardAppearance={theme.colorScheme} value={email} onChangeText={setEmail} + onSubmitEditing={onPressSignup} + enterKeyHint="done" accessible={true} accessibilityLabel="Email" accessibilityHint="Input your email to get on the Bluesky waitlist" diff --git a/src/view/com/modals/crop-image/CropImage.web.tsx b/src/view/com/modals/crop-image/CropImage.web.tsx index c5959cf4c..8e35201d1 100644 --- a/src/view/com/modals/crop-image/CropImage.web.tsx +++ b/src/view/com/modals/crop-image/CropImage.web.tsx @@ -100,7 +100,7 @@ export function Component({ accessibilityHint="Sets image aspect ratio to wide"> <RectWideIcon size={24} - style={as === AspectRatio.Wide ? s.blue3 : undefined} + style={as === AspectRatio.Wide ? s.blue3 : pal.text} /> </TouchableOpacity> <TouchableOpacity @@ -110,7 +110,7 @@ export function Component({ accessibilityHint="Sets image aspect ratio to tall"> <RectTallIcon size={24} - style={as === AspectRatio.Tall ? s.blue3 : undefined} + style={as === AspectRatio.Tall ? s.blue3 : pal.text} /> </TouchableOpacity> <TouchableOpacity @@ -120,7 +120,7 @@ export function Component({ accessibilityHint="Sets image aspect ratio to square"> <SquareIcon size={24} - style={as === AspectRatio.Square ? s.blue3 : undefined} + style={as === AspectRatio.Square ? s.blue3 : pal.text} /> </TouchableOpacity> </View> |