diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx index a689ee28658..a42f0ddf45f 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/SuiteLayout.tsx @@ -33,6 +33,7 @@ import { MobileMenu } from './MobileMenu/MobileMenu'; import { Sidebar } from './Sidebar/Sidebar'; import { useAppShortcuts } from './useAppShortcuts'; import { ModalSwitcher } from '../../modals/ModalSwitcher/ModalSwitcher'; +import { PassphraseModalProvider } from '../../modals/ReduxModal/DeviceContextModal/PassphraseModalContext'; export const SCROLL_WRAPPER_ID = 'layout-scroll'; export const Wrapper = styled.div` @@ -162,49 +163,53 @@ export const SuiteLayout = ({ children }: SuiteLayoutProps) => { - - - - - - {isMobileLayout && } - - {isMobileLayout && } - - - - - - - {!isMobileLayout && ( - - - - )} - - {!isMobileLayout && } - - - - {isMobileLayout && isAccountPage && ( - - )} - {layoutHeader} - - {children} - - - - - - - - {!isMobileLayout && } - + + + + + + + {isMobileLayout && } + + {isMobileLayout && } + + + + + + + {!isMobileLayout && ( + + + + )} + + {!isMobileLayout && } + + + + {isMobileLayout && isAccountPage && ( + + )} + {layoutHeader} + + + {children} + + + + + + + + + {!isMobileLayout && } + + diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx new file mode 100644 index 00000000000..b277119c7a8 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/ConfirmPassphraseBeforeAction.tsx @@ -0,0 +1,65 @@ +import { TrezorDevice } from '@suite-common/suite-types'; +import { selectDeviceModel } from '@suite-common/wallet-core'; +import { Column, H3, Paragraph } from '@trezor/components'; +import TrezorConnect from '@trezor/connect'; +import { PassphraseTypeCard } from '@trezor/product-components'; +import { spacings } from '@trezor/theme'; + +import { useSelector } from '../../../../../hooks/suite'; +import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice'; +import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal'; +import { OpenGuideFromTooltip } from '../../../../guide'; +import { Translation } from '../../../Translation'; + +type ConfirmPassphraseBeforeActionProps = { + onDeviceOffer: boolean; + onSubmit: (value: string, passphraseOnDevice?: boolean) => void; + device: TrezorDevice; +}; + +export const ConfirmPassphraseBeforeAction = ({ + device, + onSubmit, + onDeviceOffer, +}: ConfirmPassphraseBeforeActionProps) => { + const deviceModel = useSelector(selectDeviceModel); + + const onEnterPassphraseDialogCancel = () => { + TrezorConnect.cancel('enter-passphrase-cancel'); + }; + + return ( + + + +

+ +

+ + + + } + type="hidden" + singleColModal + offerPassphraseOnDevice={onDeviceOffer} + onSubmit={onSubmit} + deviceModel={deviceModel ?? undefined} + deviceBackup={device.features?.backup_type} + learnMoreTooltipOnClick={ + + } + /> +
+
+
+ ); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx new file mode 100644 index 00000000000..73d57f58fc9 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/EnterPassphrase.tsx @@ -0,0 +1,91 @@ +import { TrezorDevice } from '@suite-common/suite-types/libDev/src'; +import { selectDeviceModel } from '@suite-common/wallet-core'; +import { Column, H3, Icon, List } from '@trezor/components'; +import TrezorConnect from '@trezor/connect'; +import { PassphraseTypeCard } from '@trezor/product-components'; +import { spacings } from '@trezor/theme'; +import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls'; + +import { useSelector } from '../../../../../hooks/suite'; +import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice'; +import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal'; +import { OpenGuideFromTooltip } from '../../../../guide'; +import { Translation } from '../../../Translation'; +import { TrezorLink } from '../../../TrezorLink'; + +type EnterPassphraseProps = { + onDeviceOffer: boolean; + onSubmit: (value: string, passphraseOnDevice?: boolean) => void; + device: TrezorDevice; +}; + +export const EnterPassphrase = ({ device, onDeviceOffer, onSubmit }: EnterPassphraseProps) => { + const deviceModel = useSelector(selectDeviceModel); + + const onEnterPassphraseDialogCancel = () => { + TrezorConnect.cancel('enter-passphrase-cancel'); + }; + + const onEnterPassphraseDialogBack = () => { + TrezorConnect.cancel('enter-passphrase-back'); + }; + + return ( + + + +

+ +

+ + }> + ( + + {chunks} + + ), + }} + /> + + }> + + + }> + + + + } + type="hidden" + singleColModal + offerPassphraseOnDevice={onDeviceOffer} + onSubmit={(value: string, passphraseOnDevice?: boolean) => + onSubmit(value, passphraseOnDevice) + } + deviceModel={deviceModel ?? undefined} + deviceBackup={device.features?.backup_type} + learnMoreTooltipOnClick={ + + } + /> +
+
+
+ ); +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx index e547385a214..dd3f2797569 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModal.tsx @@ -1,39 +1,24 @@ import { useCallback } from 'react'; -import { - onPassphraseSubmit, - selectDeviceModel, - selectIsDiscoveryAuthConfirmationRequired, -} from '@suite-common/wallet-core'; -import { Column, H3, Icon, List, Paragraph } from '@trezor/components'; -import TrezorConnect from '@trezor/connect'; -import { PassphraseTypeCard } from '@trezor/product-components'; -import { spacings } from '@trezor/theme'; -import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls'; +import { onPassphraseSubmit } from '@suite-common/wallet-core'; -import { OpenGuideFromTooltip } from 'src/components/guide'; -import { Translation } from 'src/components/suite'; -import { TrezorLink } from 'src/components/suite/TrezorLink'; -import { useDispatch, useSelector } from 'src/hooks/suite'; +import { useDispatch } from 'src/hooks/suite'; import type { TrezorDevice } from 'src/types/suite'; -import { CardWithDevice } from 'src/views/suite/SwitchDevice/CardWithDevice'; -import { SwitchDeviceModal } from 'src/views/suite/SwitchDevice/SwitchDeviceModal'; -import { PassphraseWalletConfirmation } from './PassphraseWalletConfirmation'; +import { ConfirmPassphraseBeforeAction } from './ConfirmPassphraseBeforeAction'; +import { usePassphraseModalContext } from './PassphraseModalContext'; +import { PassphraseWalletExistsFlow } from './PassphraseWalletExistsFlow'; +import { PassphraseWalletIsNotExistFlow } from './PassphraseWalletIsNotExistFlow'; interface PassphraseModalProps { device: TrezorDevice; } export const PassphraseModal = ({ device }: PassphraseModalProps) => { - const authConfirmation = - useSelector(selectIsDiscoveryAuthConfirmationRequired) || device.authConfirm; - - const deviceModel = useSelector(selectDeviceModel); - // @ts-expect-error device.state should not be '' const hasDeviceState = device.state !== undefined && device.state !== ''; + const { passphraseState, setPassphraseState, isExisting } = usePassphraseModalContext(); const onDeviceOffer = !!( device.features && device.features.capabilities && @@ -42,138 +27,47 @@ export const PassphraseModal = ({ device }: PassphraseModalProps) => { const dispatch = useDispatch(); - const onConfirmPassphraseDialogCancel = () => { - TrezorConnect.cancel('auth-confirm-cancel'); - }; - - const onConfirmPassphraseDialogRetry = () => { - TrezorConnect.cancel('auth-confirm-retry'); - }; - - const onEnterPassphraseDialogCancel = () => { - TrezorConnect.cancel('enter-passphrase-cancel'); - }; - const onEnterPassphraseDialogBack = () => { - TrezorConnect.cancel('enter-passphrase-back'); - }; - const onSubmit = useCallback( (value: string, passphraseOnDevice?: boolean) => { + if (isExisting) { + setPassphraseState('exists-empty-wallet'); + } else { + setPassphraseState('not-exist-confirm-passphrase'); + } dispatch(onPassphraseSubmit({ value, passphraseOnDevice: !!passphraseOnDevice })); }, - [dispatch], + [dispatch, isExisting, setPassphraseState], ); - const PassphraseDefaultForm = () => ( - - - -

- -

- - }> - ( - - {chunks} - - ), - }} - /> - - }> - - - }> - - - - } - type="hidden" - singleColModal - offerPassphraseOnDevice={onDeviceOffer} - onSubmit={onSubmit} - deviceModel={deviceModel ?? undefined} - deviceBackup={device.features?.backup_type} - learnMoreTooltipOnClick={ - - } - /> -
-
-
- ); + onSubmit={onSubmit} + onDeviceOffer={onDeviceOffer} + /> + ); + } - const ConfirmPassphraseBeforeAction = () => ( - - - -

- -

- - - - } - type="hidden" - singleColModal - offerPassphraseOnDevice={onDeviceOffer} - onSubmit={onSubmit} - deviceModel={deviceModel ?? undefined} - deviceBackup={device.features?.backup_type} - learnMoreTooltipOnClick={ - - } - /> -
-
-
- ); + console.log('___!!!', passphraseState); - // passphrase needs to be confirmed because wallet is empty - if (authConfirmation) { + if (isExisting) return ( - + ); + if (!isExisting) + return ( + ); - } - - // "view-only" is active, device is reconnected and you fired an action that needs passphrase (e.g. add coin, show receive address) - if (hasDeviceState) { - return ; - } - // first step of adding passphrase wallet from switch device modal - return ; + throw new Error('Unexpected passphrase state'); }; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx new file mode 100644 index 00000000000..5077569be76 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext.tsx @@ -0,0 +1,79 @@ +import React, { createContext, useContext, useState } from 'react'; + +import type { TrezorDevice } from '@suite-common/suite-types/libDev/src'; + +type PassphraseWalletExistsState = + | 'exists-enter-passphrase' + | 'exists-best-practices' + | 'exists-empty-wallet' + | 'exists-confirm-passphrase'; + +type PassphraseWalletNotExistsState = + | 'not-exist-enter-passphrase' + | 'not-exist-best-practices' + | 'not-exist-confirm-passphrase'; + +type PassphraseWalletState = + | 'initial' + | PassphraseWalletExistsState + | PassphraseWalletNotExistsState; + +const INITIAL_STATE: PassphraseWalletState = 'initial'; + +type PassphraseModalContextType = { + passphraseState: PassphraseWalletState; + setPassphraseState: (passphraseState: PassphraseWalletState) => void; + device: TrezorDevice | undefined; + setDevice: (device: TrezorDevice) => void; + isExisting: boolean; + setIsExisting: (isExisting: boolean) => void; +}; + +type PassphraseModalProviderProps = { + children: React.ReactNode; +}; + +const initialPassphraseModal: PassphraseModalContextType = { + passphraseState: INITIAL_STATE, + setPassphraseState: () => {}, + device: undefined, + setDevice: () => {}, + isExisting: false, + setIsExisting: () => {}, +}; + +export const PassphraseModalContext = + createContext(initialPassphraseModal); + +// move this to redux +export const PassphraseModalProvider = ({ children }: PassphraseModalProviderProps) => { + const [passphraseState, setPassphraseState] = useState( + initialPassphraseModal.passphraseState, + ); + const [device, setDevice] = useState(undefined); + const [isExisting, setIsExisting] = useState(false); + + const value: PassphraseModalContextType = { + passphraseState, + setPassphraseState, + device, + setDevice, + isExisting, + setIsExisting, + }; + + return ( + {children} + ); +}; + +PassphraseModalProvider.displayName = 'PassphraseModalProvider'; + +export const usePassphraseModalContext = () => { + const context = useContext(PassphraseModalContext); + if (!context) { + throw new Error('usePassphraseModalContext must be used within a PassphraseModalProvider'); + } + + return context; +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx similarity index 60% rename from packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx rename to packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx index eab9031fa95..6ea9a4d5abc 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep2.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices.tsx @@ -1,18 +1,23 @@ -import { Dispatch } from 'react'; - import { Banner, Button, Card, Column, H3, Icon, List, Text } from '@trezor/components'; import { spacings } from '@trezor/theme'; -import { Translation } from 'src/components/suite/Translation'; +import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice'; +import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal'; +import { Translation } from '../../../Translation'; -import { ContentType } from './types'; +type PassphraseWalletBestPracticesProps = { + onCancel: () => void; + onNext: () => void; + onBack: () => void; + device: any; +}; type PassphraseWalletConfirmationStep2Props = { - setContentType: Dispatch>; + onNext: () => void; }; -export const PassphraseWalletConfirmationStep2 = ({ - setContentType, +const PassphraseWalletBestPracticesContent = ({ + onNext, }: PassphraseWalletConfirmationStep2Props) => (

@@ -37,14 +42,26 @@ export const PassphraseWalletConfirmationStep2 = ({ - ); + +export const PassphraseWalletBestPractices = ({ + onCancel, + onNext, + onBack, + device, +}: PassphraseWalletBestPracticesProps) => ( + + + + + +); diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx index e4761045849..701e3e27119 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmation.tsx @@ -1,97 +1,81 @@ -import { Dispatch, SetStateAction, useState } from 'react'; - import { TrezorDevice } from '@suite-common/suite-types'; +import { selectDeviceFeatures, selectDeviceModel } from '@suite-common/wallet-core'; +import { Banner, Column, H3 } from '@trezor/components'; +import { PassphraseTypeCard } from '@trezor/product-components'; +import { spacings } from '@trezor/theme'; import { CardWithDevice } from 'src/views/suite/SwitchDevice/CardWithDevice'; import { SwitchDeviceModal } from 'src/views/suite/SwitchDevice/SwitchDeviceModal'; -import { PassphraseWalletConfirmationStep1 } from './PassphraseWalletConfirmationStep1'; -import { PassphraseWalletConfirmationStep2 } from './PassphraseWalletConfirmationStep2'; -import { PassphraseWalletConfirmationStep3 } from './PassphraseWalletConfirmationStep3'; -import { ContentType } from './types'; +import { useSelector } from '../../../../../hooks/suite'; +import { OpenGuideFromTooltip } from '../../../../guide'; +import { Translation } from '../../../Translation'; type PassphraseWalletConfirmationContentProps = { - onSubmit: (value: string, passphraseOnDevice?: boolean) => void; onDeviceOffer: boolean; - onRetry: () => void; - onCancel: () => void; - contentType: ContentType; - setContentType: Dispatch>; + onSubmit: (value: string, passphraseOnDevice?: boolean) => void; }; const PassphraseWalletConfirmationContent = ({ - onSubmit, onDeviceOffer, - onRetry, - onCancel, - contentType, - setContentType, -}: PassphraseWalletConfirmationContentProps): React.JSX.Element => { - switch (contentType) { - case 'step1': - return ( - - ); - case 'step2': - return ; - case 'step3': - return ( - - ); - } + onSubmit, +}: PassphraseWalletConfirmationContentProps) => { + const deviceModel = useSelector(selectDeviceModel); + const deviceFeatures = useSelector(selectDeviceFeatures); + + return ( + +

+ +

+ + + + } + offerPassphraseOnDevice={onDeviceOffer} + onSubmit={onSubmit} + singleColModal + deviceModel={deviceModel ?? undefined} + deviceBackup={deviceFeatures?.backup_type} + learnMoreTooltipOnClick={ + + } + /> +
+ ); }; type PassphraseWalletConfirmationProps = { onSubmit: (value: string, passphraseOnDevice?: boolean) => void; onDeviceOffer: boolean; onCancel: () => void; - onRetry: () => void; + onBack: () => void; device: TrezorDevice; }; export const PassphraseWalletConfirmation = ({ onCancel, - onRetry, + onBack, onSubmit, onDeviceOffer, device, -}: PassphraseWalletConfirmationProps) => { - const [contentType, setContentType] = useState('step1'); - - const handleBackButtonClick = () => { - const map: Record void> = { - step1: onRetry, - step2: () => setContentType('step1'), - step3: () => setContentType('step2'), - }; - - map[contentType](); - }; - - return ( - - - - - - ); -}; +}: PassphraseWalletConfirmationProps) => ( + + + + + +); diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx deleted file mode 100644 index 7c1c4824120..00000000000 --- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep3.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { selectDeviceFeatures, selectDeviceModel } from '@suite-common/wallet-core'; -import { Banner, Column, H3 } from '@trezor/components'; -import { PassphraseTypeCard } from '@trezor/product-components'; -import { spacings } from '@trezor/theme'; - -import { OpenGuideFromTooltip } from 'src/components/guide'; -import { Translation } from 'src/components/suite/Translation'; -import { useSelector } from 'src/hooks/suite'; - -type PassphraseWalletConfirmationStep3Props = { - onDeviceOffer: boolean; - onSubmit: (value: string, passphraseOnDevice?: boolean) => void; -}; - -export const PassphraseWalletConfirmationStep3 = ({ - onDeviceOffer, - onSubmit, -}: PassphraseWalletConfirmationStep3Props) => { - const deviceModel = useSelector(selectDeviceModel); - const deviceFeatures = useSelector(selectDeviceFeatures); - - return ( - -

- -

- - - - } - offerPassphraseOnDevice={onDeviceOffer} - onSubmit={onSubmit} - singleColModal - deviceModel={deviceModel ?? undefined} - deviceBackup={deviceFeatures?.backup_type} - learnMoreTooltipOnClick={ - - } - /> -
- ); -}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx new file mode 100644 index 00000000000..a54c3d52864 --- /dev/null +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletExistsFlow.tsx @@ -0,0 +1,87 @@ +import { TrezorDevice } from '@suite-common/suite-types'; +import { selectIsDiscoveryAuthConfirmationRequired } from '@suite-common/wallet-core'; +import TrezorConnect from '@trezor/connect'; + +import { EnterPassphrase } from './EnterPassphrase'; +import { usePassphraseModalContext } from './PassphraseModalContext'; +import { PassphraseWalletBestPractices } from './PassphraseWalletBestPractices'; +import { PassphraseWalletConfirmation } from './PassphraseWalletConfirmation'; +import { PassphraseWalletIsEmpty } from './PassphraseWalletIsEmpty'; +import { useSelector } from '../../../../../hooks/suite'; + +type PassphraseWalletExistsFlowProps = { + onDeviceOffer: boolean; + onSubmit: (value: string, passphraseOnDevice?: boolean) => void; + device: TrezorDevice; +}; + +export const PassphraseWalletExistsFlow = ({ + onDeviceOffer, + onSubmit, + device, +}: PassphraseWalletExistsFlowProps) => { + const authConfirmation = + useSelector(selectIsDiscoveryAuthConfirmationRequired) || device.authConfirm; + const { passphraseState, setPassphraseState } = usePassphraseModalContext(); + + const onConfirmPassphraseDialogCancel = () => { + TrezorConnect.cancel('auth-confirm-cancel'); + }; + + const onConfirmPassphraseDialogRetry = () => { + TrezorConnect.cancel('auth-confirm-retry'); + }; + + if (authConfirmation) { + if (passphraseState === 'exists-empty-wallet') { + return ( + { + setPassphraseState('exists-best-practices'); + }} + onBack={() => { + onConfirmPassphraseDialogRetry(); + setPassphraseState('exists-enter-passphrase'); + }} + device={device} + onRetry={onConfirmPassphraseDialogRetry} + /> + ); + } + + if (passphraseState === 'exists-best-practices') { + return ( + { + setPassphraseState('exists-confirm-passphrase'); + }} + onBack={() => { + setPassphraseState('exists-empty-wallet'); + }} + device={device} + /> + ); + } + if (passphraseState === 'exists-confirm-passphrase') { + return ( + { + setPassphraseState('exists-best-practices'); + }} + device={device} + onDeviceOffer={onDeviceOffer} + /> + ); + } + } + + if (passphraseState === 'exists-enter-passphrase') { + return ( + + ); + } +}; diff --git a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx similarity index 74% rename from packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx rename to packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx index a4f220ede03..64fbef63936 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletConfirmationStep1.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsEmpty.tsx @@ -1,32 +1,39 @@ -import { Dispatch } from 'react'; - +import { TrezorDevice } from '@suite-common/suite-types'; import { Button, Card, Column, H3, Paragraph, Row } from '@trezor/components'; import { CoinLogo } from '@trezor/product-components'; import { spacings } from '@trezor/theme'; import { HELP_CENTER_PASSPHRASE_URL } from '@trezor/urls'; -import { onCancel as onCancelModal } from 'src/actions/suite/modalActions'; -import { goto } from 'src/actions/suite/routerActions'; -import { Translation } from 'src/components/suite/Translation'; -import { useNetworkSupport } from 'src/hooks/settings/useNetworkSupport'; -import { useDispatch, useSelector } from 'src/hooks/suite'; -import { selectEnabledNetworks } from 'src/reducers/wallet/settingsReducer'; +import { onCancel as onCancelModal } from '../../../../../actions/suite/modalActions'; +import { goto } from '../../../../../actions/suite/routerActions'; +import { useNetworkSupport } from '../../../../../hooks/settings/useNetworkSupport'; +import { useDispatch, useSelector } from '../../../../../hooks/suite'; +import { selectEnabledNetworks } from '../../../../../reducers/wallet/settingsReducer'; +import { CardWithDevice } from '../../../../../views/suite/SwitchDevice/CardWithDevice'; +import { SwitchDeviceModal } from '../../../../../views/suite/SwitchDevice/SwitchDeviceModal'; +import { Translation } from '../../../Translation'; -import { ContentType } from './types'; +type PassphraseWalletIsEmptyProps = { + onRetry: () => void; + onCancel: () => void; + device: TrezorDevice; + onNext: () => void; + onBack: () => void; +}; -type PassphraseWalletConfirmationStep1Props = { - setContentType: Dispatch>; +type PassphraseWalletIsEmptyContentProps = { + onNext: () => void; onRetry: () => void; onCancel: () => void; 'data-testid'?: string; }; -export const PassphraseWalletConfirmationStep1 = ({ - setContentType, +const PassphraseWalletIsEmptyContent = ({ + onNext, onRetry, onCancel, 'data-testid': dataTest, -}: PassphraseWalletConfirmationStep1Props) => { +}: PassphraseWalletIsEmptyContentProps) => { const { supportedMainnets } = useNetworkSupport(); const enabledNetworks = useSelector(selectEnabledNetworks); const dispatch = useDispatch(); @@ -68,9 +75,7 @@ export const PassphraseWalletConfirmationStep1 = ({ )} {isPassphraseProtectionEnabled && ( - + + + + )} diff --git a/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx b/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx index 59d9a9b5e3c..93f5bac5b58 100644 --- a/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx +++ b/packages/suite/src/views/suite/SwitchDevice/SwitchDevice.tsx @@ -1,18 +1,25 @@ import * as deviceUtils from '@suite-common/suite-utils'; import { selectDevices, selectSelectedDevice } from '@suite-common/wallet-core'; +import { WalletType } from '@suite-common/wallet-types'; import { Column } from '@trezor/components'; +import TrezorConnect from '@trezor/connect'; import { spacings } from '@trezor/theme'; -import { useSelector } from 'src/hooks/suite'; +import { useDispatch, useSelector } from 'src/hooks/suite'; import { ForegroundAppProps } from 'src/types/suite'; import { DeviceItem } from './DeviceItem/DeviceItem'; import { SwitchDeviceModal } from './SwitchDeviceModal'; +import { addWalletThunk } from '../../../actions/wallet/addWalletThunk'; +import { usePassphraseModalContext } from '../../../components/suite/modals/ReduxModal/DeviceContextModal/PassphraseModalContext'; +import { PassphraseWalletBestPractices } from '../../../components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletBestPractices'; export const SwitchDevice = ({ onCancel }: ForegroundAppProps) => { const selectedDevice = useSelector(selectSelectedDevice); const devices = useSelector(selectDevices); + const { passphraseState, device, setPassphraseState, isExisting } = usePassphraseModalContext(); + const dispatch = useDispatch(); // exclude selectedDevice from list, because other devices could have a higher priority // and we want to have selectedDevice on top const sortedDevices = deviceUtils @@ -24,6 +31,31 @@ export const SwitchDevice = ({ onCancel }: ForegroundAppProps) => { sortedDevices.unshift(selectedDevice); } + // TODO: This is far from perfect. It should be on the same place with `packages/suite/src/components/suite/modals/ReduxModal/DeviceContextModal/PassphraseWalletIsNotExistFlow.tsx` but app is divided + if (selectedDevice && !isExisting && passphraseState === 'not-exist-best-practices') { + return ( + { + TrezorConnect.cancel('auth-confirm-cancel'); + }} + onNext={() => { + dispatch( + addWalletThunk({ + walletType: WalletType.PASSPHRASE, + device: selectedDevice, + }), + ); + onCancel(false); + setPassphraseState('not-exist-enter-passphrase'); + }} + onBack={() => { + setPassphraseState('initial'); + }} + device={device} + /> + ); + } + return (