From 381291ed6c337edac672a3ec3e9a402f0f2543c1 Mon Sep 17 00:00:00 2001 From: Tom McGuire Date: Fri, 28 Jun 2024 13:43:40 -0700 Subject: [PATCH 01/50] feat: add cab in onboarding --- branding/celo/src/images/email.png | Bin 0 -> 1680 bytes locales/base/translation.json | 12 +- src/account/AccountKeyEducation.tsx | 9 +- src/analytics/Events.tsx | 2 + src/analytics/Properties.tsx | 2 + src/analytics/docs.ts | 2 + src/components/header/CustomHeader.tsx | 14 +- src/images/Images.ts | 1 + src/keylessBackup/SignInWithEmail.tsx | 210 +++++++++++++++--- src/keylessBackup/types.ts | 1 + src/navigator/Navigator.tsx | 2 +- src/navigator/types.tsx | 3 +- .../registration/ImportSelect.test.tsx | 2 +- src/onboarding/registration/ImportSelect.tsx | 2 +- .../registration/OnboardingRecoveryPhrase.tsx | 5 +- src/onboarding/steps.ts | 33 +++ 16 files changed, 252 insertions(+), 48 deletions(-) create mode 100644 branding/celo/src/images/email.png diff --git a/branding/celo/src/images/email.png b/branding/celo/src/images/email.png new file mode 100644 index 0000000000000000000000000000000000000000..3b2c913702784e226a85cd7dd56130211fd5fb09 GIT binary patch literal 1680 zcmeAS@N?(olHy`uVBq!ia0vp^AAooZ2OE%FHD}=q1_q{2RUr{2L5bxG1x5L3nK`Kn zC6xuK3aJ&DX$%Y%x86>V-gH}mr|o{E>+}YdmLo+wX3TuI;PiX`vZ6_sFIUU|5-^s~ zaX9f`eX^&;zM6Rth4nVQP+VE5XXzfZa>*f4+5YFD-{vOW`d)iBo8!Fyw+oj{4;XMp zS<0`C`>g%u*R}`S*te!vf5>k6TU5e(N9NS6nHMGd9S@ybK6jmiljS)-y}bT~W_Gvh zx^LWHb)&4deAB$cixnk9q`D#x)o^&;`Cj6tkiK@sw)Y%aXC3W3*-cItxiLA;i+g|V z*bj{hlTU1qt5{#xFW-Is>nz3hTh2^(dr@QI@N46b=tu3nPvr#d`Df&p_xaQq8gL$Ak!vP=PDDn;)}g z=Pd7D_GMc1CQI*_nqZs#TwG>)>=QVuwVM*~dQ+n}&AwW>`KF?0smE@z2xv*(pVl0}x@L;V&*YO6okLwGuSzrhy1+Gi+MG?# z=IE|>UNfz_}-o@<^(`zyg@YW04GbKp7y{lKNCiKku4JLV)f-X;+ zZJNLIYTuWaE3?nv-Sz#_>j#R=$B&#i+}3aO%JJa=&%!0n{WUipx?8?-S?4=5^VONl z%g!6Uo_ovn>+Da`S6(bSHv7t~^zy6?Y@26uM;-6fOH(-3>2ODkQN=_*?V_e?+!L|Q z5fbvPMom|as_{e}X)usIV)gReyWTtch1{?9AL*@k)6*&W-xR~JD}QILL++JYzSGaP z?K`wIQ>3Q$u68x=owTeb*FxJz*WdEr7WjYZ;OUDnSpUG|!|BF)gNNE;`xKXHJaMdJ zU|?*?baoE#basZNeqfrPQ#;YtV$bZlO$q1U}8!9LW zoi{kVrSp2{a;qS%i=dW$cnHm19s^{MK!@X`^x9g&$F zW@P%v^U;h|FQ@3I*oIl=7hXFRdToz-eWJyBef`3@&lDy_98gl}2naaJc4~v*@=*1o zPP4uV+x=s_u0PRR@j9D?<+H#>wwqs@{~vsxxAxGH9n(ep80PBteKzE2DQk2)Tez=Z zc6lKa%lt;|y-(L)X?*E_DO*>!jO9xnv-ovg-ygL8?yv%RknR(KR>YmB`)C3kvY)Rhk zE(~%YcuGaF6)3`4;1OBOz`!jG!i)^F=12eq*-JcqUD=~pPZ!4! zV1ad+k(YsiQ1rL1gPlQUr4}#7!`h;68&`N0K6#_aSb=VG<5SxB~KUK6_<7 WOR9%=t{E`47(8A5T-G@yGywo7cdMfS literal 0 HcmV?d00001 diff --git a/locales/base/translation.json b/locales/base/translation.json index 76588fb359b..fc1f3b28c02 100644 --- a/locales/base/translation.json +++ b/locales/base/translation.json @@ -29,6 +29,7 @@ "dataSaver": "Data Saver", "enableDataSaver": "Enable Data Saver", "dataSaverDetail": "Data Saver mode allows you to communicate with the the network through a trusted node. You can always change this mode in app settings.", + "keylessBackupOnboardingTitle": "Create Login", "keylessBackupSettingsTitle": "Email & Phone Backup", "keylessBackupSettingsDeleteError": "Your backup was not able to be deleted, please wait & try again later.", "setup": "Set Up", @@ -102,9 +103,16 @@ }, "signInWithEmail": { "title": "Sign in with email", - "subtitle": "Sign in with your email to set it up as a backup.\n\nYou will be prompted to sign in again if you ever lose your wallet.", + "subtitle": "Sign in with your email to set it up as a backup. You will be prompted to sign in again if you ever lose your wallet.", "subtitleRestore": "Sign in with the email you used to set up your wallet backup.", - "google": "Sign in with Google" + "google": "Sign in with Google", + "signInAnotherWay": "Sign in another way", + "bottomSheet": { + "title": "Save your recovery phrase to create a wallet", + "description": "We’re going to be supporting other email providers soon, but in the meanwhile you’ll have to save your recovery phrase to finish creating a wallet.", + "continue": "Continue", + "skip": "Skip (not recommended)" + } }, "keylessBackupPhoneInput": { "setup": { diff --git a/src/account/AccountKeyEducation.tsx b/src/account/AccountKeyEducation.tsx index 69938653b83..66d92f7d6db 100644 --- a/src/account/AccountKeyEducation.tsx +++ b/src/account/AccountKeyEducation.tsx @@ -11,13 +11,19 @@ import { noHeader } from 'src/navigator/Headers' import { navigate } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { StackParamList } from 'src/navigator/types' +import Colors from 'src/styles/colors' type Props = NativeStackScreenProps export default function AccountKeyEducation(props: Props) { + const isFromCabOnboarding = + props.route.params?.nextScreen === Screens.OnboardingRecoveryPhrase && + props.route.params?.origin === 'CabOnboarding' function onComplete() { ValoraAnalytics.track(OnboardingEvents.backup_education_complete) - if (props.route.params?.nextScreen) { + if (isFromCabOnboarding) { + navigate(Screens.OnboardingRecoveryPhrase, { origin: 'CabOnboarding' }) + } else if (props.route.params?.nextScreen) { navigate(props.route.params?.nextScreen) } else { navigate(Screens.BackupPhrase) @@ -39,6 +45,7 @@ export default function AccountKeyEducation(props: Props) { finalButtonText={t('completeEducation')} buttonText={t('next')} finalButtonType={BtnTypes.PRIMARY} + style={{ backgroundColor: Colors.onboardingBackground }} /> ) } diff --git a/src/analytics/Events.tsx b/src/analytics/Events.tsx index d8df38fb00b..1cafacd4bb5 100644 --- a/src/analytics/Events.tsx +++ b/src/analytics/Events.tsx @@ -95,9 +95,11 @@ export enum SettingsEvents { export enum KeylessBackupEvents { wallet_security_primer_get_started = 'wallet_security_primer_get_started', cab_setup_recovery_phrase = 'cab_setup_recovery_phrase', + cab_sign_in_another_way = 'cab_sign_in_another_way', cab_sign_in_with_google = 'cab_sign_in_with_google', cab_sign_in_with_google_success = 'cab_sign_in_with_google_success', cab_sign_in_with_email_screen_cancel = 'cab_sign_in_with_email_screen_cancel', + cab_sign_in_with_email_screen_skip = 'cab_sign_in_with_email_screen_skip', cab_get_torus_keyshare_failed = 'cab_get_torus_keyshare_failed', cab_enter_phone_number_continue = 'cab_enter_phone_number_continue', cab_enter_phone_number_cancel = 'cab_enter_phone_number_cancel', diff --git a/src/analytics/Properties.tsx b/src/analytics/Properties.tsx index f099b78febe..078b6426e9c 100644 --- a/src/analytics/Properties.tsx +++ b/src/analytics/Properties.tsx @@ -254,9 +254,11 @@ interface CommonKeylessBackupProps { interface KeylessBackupEventsProperties { [KeylessBackupEvents.wallet_security_primer_get_started]: undefined [KeylessBackupEvents.cab_setup_recovery_phrase]: undefined + [KeylessBackupEvents.cab_sign_in_another_way]: CommonKeylessBackupProps [KeylessBackupEvents.cab_sign_in_with_google]: CommonKeylessBackupProps [KeylessBackupEvents.cab_sign_in_with_google_success]: CommonKeylessBackupProps [KeylessBackupEvents.cab_sign_in_with_email_screen_cancel]: CommonKeylessBackupProps + [KeylessBackupEvents.cab_sign_in_with_email_screen_skip]: CommonKeylessBackupProps [KeylessBackupEvents.cab_enter_phone_number_continue]: CommonKeylessBackupProps [KeylessBackupEvents.cab_enter_phone_number_cancel]: CommonKeylessBackupProps [KeylessBackupEvents.cab_intro_continue]: CommonKeylessBackupProps diff --git a/src/analytics/docs.ts b/src/analytics/docs.ts index 2b8edde1336..78b2677d6f0 100644 --- a/src/analytics/docs.ts +++ b/src/analytics/docs.ts @@ -127,9 +127,11 @@ export const eventDocs: Record = { [SettingsEvents.settings_delete_keyless_backup]: ``, [KeylessBackupEvents.wallet_security_primer_get_started]: ``, [KeylessBackupEvents.cab_setup_recovery_phrase]: `When the recovery phrase link is pressed in the setup wallet backup screen`, + [KeylessBackupEvents.cab_sign_in_another_way]: `When the sign in another way button is pressed in the setup wallet backup screen`, [KeylessBackupEvents.cab_sign_in_with_google]: ``, [KeylessBackupEvents.cab_sign_in_with_google_success]: ``, [KeylessBackupEvents.cab_sign_in_with_email_screen_cancel]: ``, + [KeylessBackupEvents.cab_sign_in_with_email_screen_skip]: `When the skip button is pressed on the sign in with email bottom sheet`, [KeylessBackupEvents.cab_get_torus_keyshare_failed]: ``, [KeylessBackupEvents.cab_enter_phone_number_continue]: ``, [KeylessBackupEvents.cab_enter_phone_number_cancel]: `When the cancel button is pressed on the phone input screen`, diff --git a/src/components/header/CustomHeader.tsx b/src/components/header/CustomHeader.tsx index 372c7e77b64..c093fc32fa3 100644 --- a/src/components/header/CustomHeader.tsx +++ b/src/components/header/CustomHeader.tsx @@ -1,17 +1,23 @@ import React from 'react' import { Platform, StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native' -import { styles as headerStyles } from 'src/navigator/Headers' +import { HeaderTitleWithSubtitle, styles as headerStyles } from 'src/navigator/Headers' interface Props { left?: React.ReactNode right?: React.ReactNode title?: React.ReactNode | string + subTitle?: string | React.ReactNode style?: StyleProp } -function CustomHeader({ left, right, title, style }: Props) { - const titleComponent = - typeof title === 'string' ? {title} : title +function CustomHeader({ left, right, title, style, subTitle }: Props) { + const titleComponent = subTitle ? ( + + ) : typeof title === 'string' ? ( + {title} + ) : ( + title + ) return ( {!!title && {titleComponent}} diff --git a/src/images/Images.ts b/src/images/Images.ts index cf5dc36b6b4..5e44c6fc927 100644 --- a/src/images/Images.ts +++ b/src/images/Images.ts @@ -20,6 +20,7 @@ export const dappListLogo = require('src/images/dapp-list-logo.png') export const earn1 = require('src/images/earn1.png') export const earn2 = require('src/images/earn2.png') export const earn3 = require('src/images/earn3.png') +export const email = require('src/images/email.png') export const fiatExchange = require('src/images/fiat-exchange.png') export const getVerified = require('src/images/get-verified.png') export const inviteFriends = require('src/images/invite-friends.png') diff --git a/src/keylessBackup/SignInWithEmail.tsx b/src/keylessBackup/SignInWithEmail.tsx index 1d56a77a233..11861b1014d 100644 --- a/src/keylessBackup/SignInWithEmail.tsx +++ b/src/keylessBackup/SignInWithEmail.tsx @@ -1,20 +1,29 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack' -import React, { useState } from 'react' +import React, { useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { SafeAreaView, ScrollView, StyleSheet, Text } from 'react-native' +import { Image, SafeAreaView, ScrollView, StyleSheet, Text, View } from 'react-native' import { useAuth0 } from 'react-native-auth0' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import { KeylessBackupEvents } from 'src/analytics/Events' import ValoraAnalytics from 'src/analytics/ValoraAnalytics' +import BackButton from 'src/components/BackButton' +import BottomSheet, { BottomSheetRefType } from 'src/components/BottomSheet' import Button, { BtnSizes, BtnTypes } from 'src/components/Button' +import CustomHeader from 'src/components/header/CustomHeader' import GoogleIcon from 'src/icons/Google' +import { email } from 'src/images/Images' import KeylessBackupCancelButton from 'src/keylessBackup/KeylessBackupCancelButton' import { googleSignInCompleted, keylessBackupStarted } from 'src/keylessBackup/slice' -import { KeylessBackupFlow } from 'src/keylessBackup/types' -import { emptyHeader } from 'src/navigator/Headers' +import { KeylessBackupFlow, KeylessBackupOrigin } from 'src/keylessBackup/types' import { navigate } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { StackParamList } from 'src/navigator/types' -import { useDispatch } from 'src/redux/hooks' +import { + getOnboardingStepValues, + goToNextOnboardingScreen, + onboardingPropsSelector, +} from 'src/onboarding/steps' +import { useDispatch, useSelector } from 'src/redux/hooks' import Colors from 'src/styles/colors' import { typeScale } from 'src/styles/fonts' import { Spacing } from 'src/styles/styles' @@ -22,6 +31,47 @@ import Logger from 'src/utils/Logger' const TAG = 'keylessBackup/SignInWithEmail' +function SignInWithEmailBottomSheet({ + onPressContinue, + onPressSkip, + bottomSheetRef, +}: { + onPressContinue: () => void + onPressSkip: () => void + bottomSheetRef: React.RefObject +}) { + const { t } = useTranslation() + + return ( + + + {t('signInWithEmail.bottomSheet.description')} + + +