From 5c55fccb8ca85d70f87b8738635b645e50af6704 Mon Sep 17 00:00:00 2001 From: Matt Reetz Date: Mon, 18 Sep 2023 09:10:22 -0500 Subject: [PATCH] Create component to display words, use when creating and revealing passphrase. --- src/components/RevealWords.tsx | 140 ++++++++++++++++++ .../create/AccountCreatePassphraseScreen.tsx | 135 +++-------------- src/features/settings/RevealWordsScreen.tsx | 134 ++--------------- 3 files changed, 174 insertions(+), 235 deletions(-) create mode 100644 src/components/RevealWords.tsx diff --git a/src/components/RevealWords.tsx b/src/components/RevealWords.tsx new file mode 100644 index 000000000..e3e9f5158 --- /dev/null +++ b/src/components/RevealWords.tsx @@ -0,0 +1,140 @@ +import React, { memo, useCallback, useMemo } from 'react' +import { upperCase } from 'lodash' +import { useTranslation } from 'react-i18next' +import Text from '@components/Text' +import { ReAnimatedBox } from '@components/AnimatedBox' +import Box from '@components/Box' +import ButtonPressable from '@components/ButtonPressable' +import { FlatList } from 'react-native' +import { useColors, useSpacing } from '@theme/themeHooks' +import CopyAddress from '@assets/images/copyAddress.svg' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import useCopyText from '@hooks/useCopyText' +import useHaptic from '@hooks/useHaptic' +import { FadeIn } from 'react-native-reanimated' + +type Props = { + mnemonic: string[] + onDone: () => void + ListHeaderComponent?: React.ReactNode +} +const RevealWords = ({ mnemonic, onDone, ListHeaderComponent }: Props) => { + const { t } = useTranslation() + const spacing = useSpacing() + const { secondaryText } = useColors() + const copyText = useCopyText() + const { triggerImpact } = useHaptic() + + const handleCopySeedPhrase = useCallback(() => { + triggerImpact('light') + copyText({ + message: t('generic.copiedSeedPhrase'), + copyText: mnemonic.join(' ') || '', + }) + }, [copyText, triggerImpact, mnemonic, t]) + + const renderItem = useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item, index }: { item: string; index: number }) => { + return ( + + {`${index + 1}. `} + + {upperCase(item)} + + + ) + }, + [], + ) + + const contentContainerStyle = useMemo( + () => ({ + flexGrow: 1, + paddingHorizontal: spacing.l, + }), + [spacing], + ) + + const ListFooterComponent = useCallback(() => { + return ( + + + + + {t('generic.copyToClipboard')} + + + + + + ) + }, [handleCopySeedPhrase, secondaryText, t, onDone]) + + return ( + + + + ) +} + +export default memo(RevealWords) diff --git a/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx b/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx index 785aaa092..a6f842529 100644 --- a/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx +++ b/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx @@ -1,19 +1,15 @@ -import React, { useState, useEffect, useCallback, memo } from 'react' +import React, { useCallback, memo, useMemo } from 'react' import { useNavigation } from '@react-navigation/native' import { useTranslation } from 'react-i18next' import { useAsync } from 'react-async-hook' -import Carousel, { Pagination } from 'react-native-snap-carousel' -import { upperCase } from 'lodash' import Close from '@assets/images/close.svg' import InfoError from '@assets/images/infoError.svg' -import { useSafeAreaInsets } from 'react-native-safe-area-context' import Box from '@components/Box' import Text from '@components/Text' -import { wp } from '@utils/layout' import { useAccountStorage } from '@storage/AccountStorageProvider' -import ButtonPressable from '@components/ButtonPressable' import { useColors } from '@theme/themeHooks' import TouchableOpacityBox from '@components/TouchableOpacityBox' +import RevealWords from '@components/RevealWords' import { CreateAccountNavigationProp } from './createAccountNavTypes' import { useOnboarding } from '../OnboardingProvider' import { OnboardingNavigationProp } from '../onboardingTypes' @@ -28,35 +24,11 @@ const AccountCreatePassphraseScreen = () => { } = useOnboarding() const parentNav = useNavigation() const navigation = useNavigation() - const [wordIndex, setWordIndex] = useState(0) - const [disabled, setDisabled] = useState(true) - const [viewedWords, setViewedWords] = useState(new Array(24).fill(false)) - const { bottom } = useSafeAreaInsets() const { result: secureAccount } = useAsync( async () => createSecureAccount({ netType, use24Words: true }), [createSecureAccount, netType], ) - const onSnapToItem = useCallback( - (index: number) => { - setWordIndex(index) - setViewedWords( - Object.assign(new Array(24).fill(false), viewedWords, { - 0: true, - [index]: true, - }), - ) - }, - [viewedWords], - ) - - useEffect(() => { - const viewedAll = viewedWords.every((w) => w) - if (!viewedAll && !__DEV__) return - - setDisabled(false) - }, [viewedWords]) - const navToTop = useCallback(() => { if (hasAccounts) { parentNav.popToTop() @@ -72,44 +44,16 @@ const AccountCreatePassphraseScreen = () => { navigation.navigate('AccountEnterPassphraseScreen') }, [navigation, secureAccount, setOnboardingData]) - const renderItem = ({ item, index }: { item: string; index: number }) => { - const isFirst = index === 0 - const isLast = index + 1 === secureAccount?.mnemonic?.length + const ListHeaderComponent = useMemo(() => { return ( - - - {`${index + 1}. `} - - + - {upperCase(item)} - - - ) - } - - return ( - - - - - + + @@ -129,57 +73,22 @@ const AccountCreatePassphraseScreen = () => { variant="subtitle1" color="red500" textAlign="center" - marginTop="m" + marginVertical="l" marginHorizontal="xl" > {t('accountSetup.passphrase.subtitle2')} - - - - - - - - + + ) + }, [colors.primaryText, navToTop, t]) + + return ( + + ) } diff --git a/src/features/settings/RevealWordsScreen.tsx b/src/features/settings/RevealWordsScreen.tsx index 01b372e9a..53143ba43 100644 --- a/src/features/settings/RevealWordsScreen.tsx +++ b/src/features/settings/RevealWordsScreen.tsx @@ -1,39 +1,19 @@ -import React, { memo, useCallback, useMemo, useState } from 'react' -import { upperCase } from 'lodash' +import React, { memo, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useAsync } from 'react-async-hook' import { useNavigation } from '@react-navigation/native' -import Text from '@components/Text' import { useAccountStorage } from '@storage/AccountStorageProvider' import Box from '@components/Box' -import ButtonPressable from '@components/ButtonPressable' import BackScreen from '@components/BackScreen' import TextTransform from '@components/TextTransform' import { getSecureAccount } from '@storage/secureStorage' -import { FlatList } from 'react-native' -import { useColors, useSpacing } from '@theme/themeHooks' -import CopyAddress from '@assets/images/copyAddress.svg' -import TouchableOpacityBox from '@components/TouchableOpacityBox' -import useCopyText from '@hooks/useCopyText' -import useHaptic from '@hooks/useHaptic' +import RevealWords from '@components/RevealWords' const RevealWordsScreen = () => { const { currentAccount } = useAccountStorage() const { t } = useTranslation() const navigation = useNavigation() const [mnemonic, setMnemonic] = useState() - const spacing = useSpacing() - const { secondaryText } = useColors() - const copyText = useCopyText() - const { triggerImpact } = useHaptic() - - const handleCopySeedPhrase = useCallback(() => { - triggerImpact('light') - copyText({ - message: t('generic.copiedSeedPhrase'), - copyText: mnemonic?.join(' ') || '', - }) - }, [copyText, triggerImpact, mnemonic, t]) useAsync(async () => { if (!currentAccount || !currentAccount.address) return @@ -41,58 +21,14 @@ const RevealWordsScreen = () => { setMnemonic(secureAccount?.mnemonic) }, [currentAccount]) - const renderItem = useCallback( - // eslint-disable-next-line react/no-unused-prop-types - ({ item, index }: { item: string; index: number }) => { - return ( - - {`${index + 1}. `} - - {upperCase(item)} - - - ) - }, - [], - ) - - const contentContainerStyle = useMemo( - () => ({ - marginTop: spacing.m, - flexGrow: 1, - padding: spacing.l, - }), - [spacing], - ) - - const ListHeaderComponent = useCallback(() => { + const ListHeaderComponent = useMemo(() => { return ( { ) }, [mnemonic?.length]) - const ListFooterComponent = useCallback(() => { - return ( - - - - - {t('generic.copyToClipboard')} - - - - - - ) - }, [handleCopySeedPhrase, secondaryText, t, navigation]) - return ( - - {/* */} ) }