diff --git a/.changeset/hungry-bobcats-sneeze.md b/.changeset/hungry-bobcats-sneeze.md new file mode 100644 index 000000000000..2f1aa0538426 --- /dev/null +++ b/.changeset/hungry-bobcats-sneeze.md @@ -0,0 +1,5 @@ +--- +"live-mobile": minor +--- + +Add account v2 close process management diff --git a/apps/ledger-live-mobile/src/components/ConfirmationModal.tsx b/apps/ledger-live-mobile/src/components/ConfirmationModal.tsx index 563b0322d8d7..74420020ced4 100644 --- a/apps/ledger-live-mobile/src/components/ConfirmationModal.tsx +++ b/apps/ledger-live-mobile/src/components/ConfirmationModal.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from "react"; import { Trans } from "react-i18next"; -import { View, StyleSheet, Image } from "react-native"; +import { View, StyleSheet, Image, StyleProp, ViewStyle } from "react-native"; import { rgba, Theme, withTheme } from "../colors"; import QueuedDrawer from "./QueuedDrawer"; import LText from "./LText"; @@ -25,6 +25,8 @@ type Props = { preventBackdropClick?: boolean; iconMarginBottom?: number; testID?: string; + customTitleStyle?: StyleProp; + customDescriptionStyle?: StyleProp; }; class ConfirmationModal extends PureComponent { @@ -48,6 +50,8 @@ class ConfirmationModal extends PureComponent { hideRejectButton, colors, iconMarginBottom, + customTitleStyle, + customDescriptionStyle, ...rest } = this.props; const iColor = iconColor || colors.live; @@ -77,12 +81,12 @@ class ConfirmationModal extends PureComponent { )} {confirmationTitle && ( - + {confirmationTitle} )} {confirmationDesc && ( - + {confirmationDesc} )} diff --git a/apps/ledger-live-mobile/src/components/NavigationHeaderCloseButton.tsx b/apps/ledger-live-mobile/src/components/NavigationHeaderCloseButton.tsx index 37d7cbd5bba2..3483928d52f5 100644 --- a/apps/ledger-live-mobile/src/components/NavigationHeaderCloseButton.tsx +++ b/apps/ledger-live-mobile/src/components/NavigationHeaderCloseButton.tsx @@ -1,4 +1,4 @@ -import { Flex, IconsLegacy } from "@ledgerhq/native-ui"; +import { Button, Flex, IconsLegacy } from "@ledgerhq/native-ui"; import { ParamListBase, useNavigation } from "@react-navigation/native"; import { StackNavigationProp } from "@react-navigation/stack"; import React, { useCallback, useState } from "react"; @@ -78,6 +78,9 @@ type AdvancedProps = { confirmationDesc?: React.ReactNode; onClose?: () => void; rounded?: boolean; + showButton?: boolean; + buttonText?: string; + customDrawerStyle?: Record; }; /** @@ -96,6 +99,9 @@ export const NavigationHeaderCloseButtonAdvanced: React.FC = Reac confirmationDesc, onClose = emptyFunction, rounded = false, + showButton = false, + buttonText, + customDrawerStyle, }) => { const navigation = useNavigation(); const [isConfirmationModalOpened, setIsConfirmationModalOpened] = useState(false); @@ -157,13 +163,21 @@ export const NavigationHeaderCloseButtonAdvanced: React.FC = Reac setIsConfirmationModalOpened(false); }, [close]); + const renderCloseElement = useCallback(() => { + if (showButton && buttonText) + return ( + + ); + + if (rounded) return ; + else return ; + }, [buttonText, showButton, onPress, rounded, color]); + return ( <> - {rounded ? ( - - ) : ( - - )} + {renderCloseElement()} {withConfirmation && ( = Reac confirmationTitle={confirmationTitle} confirmationDesc={confirmationDesc} onModalHide={onModalHide} + customTitleStyle={customDrawerStyle?.title ?? {}} + customDescriptionStyle={customDrawerStyle?.description ?? {}} /> )} diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index a75fd860805e..c0b222ee32a8 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -3991,7 +3991,11 @@ }, "quitConfirmation": { "title": "Cancel add account", - "desc": "Are you sure you want to cancel adding accounts?" + "desc": "Are you sure you want to cancel adding accounts?", + "v2": { + "title": "Cancel adding account?", + "desc": "No account wll be added to Ledger Live." + } }, "imported": "Asset added successfully", "added": "Account added to your portfolio", diff --git a/apps/ledger-live-mobile/src/newArch/components/CloseWithConfirmation/index.tsx b/apps/ledger-live-mobile/src/newArch/components/CloseWithConfirmation/index.tsx new file mode 100644 index 000000000000..d7393b31d46f --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/components/CloseWithConfirmation/index.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { Trans } from "react-i18next"; +import { useRoute } from "@react-navigation/native"; +import { NavigationHeaderCloseButtonAdvanced } from "~/components/NavigationHeaderCloseButton"; +import { ScreenName } from "~/const"; + +const routesWithConfirmation: string[] = [ + ScreenName.SelectDevice, + ScreenName.SelectNetwork, + ScreenName.AddAccountsSelectCrypto, + ScreenName.ScanDeviceAccounts, + ScreenName.NoAssociatedAccounts, +]; +export default function CloseWithConfirmation({ + onClose, + showButton, + buttonText, +}: { + onClose?: () => void; + showButton?: boolean; + buttonText?: string; +}) { + const route = useRoute(); + return ( + } + confirmationDesc={} + {...(onClose && { onClose })} + {...(showButton && { showButton })} + {...(buttonText && { buttonText })} + customDrawerStyle={{ + title: { + textAlign: "left", + fontSize: 24, + fontWeight: 600, + lineHeight: 32.4, + letterSpacing: -0.72, + }, + description: { + textAlign: "left", + paddingHorizontal: 0, + fontSize: 14, + fontWeight: 500, + lineHeight: 21, + }, + }} + /> + ); +} diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/Navigator.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/Navigator.tsx index 24e8ded4bf33..67dbd3c2366d 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/Navigator.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/Navigator.tsx @@ -7,7 +7,6 @@ import { ScreenName } from "~/const"; import { getStackNavigatorConfig } from "~/navigation/navigatorConfig"; import { track } from "~/analytics"; import type { NetworkBasedAddAccountNavigator } from "LLM/features/Accounts/screens/AddAccount/types"; -import { NavigationHeaderCloseButtonAdvanced } from "~/components/NavigationHeaderCloseButton"; import ScanDeviceAccounts from "LLM/features/Accounts/screens/ScanDeviceAccounts"; import { AccountsListNavigator } from "./screens/AccountsList/types"; import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; @@ -17,24 +16,30 @@ import AddAccountsSuccess from "./screens/AddAccountSuccess"; import SelectAccounts from "./screens/SelectAccounts"; import AddAccountsWarning from "./screens/AddAccountWarning"; import NoAssociatedAccountsView from "./screens/NoAssociatedAccountsView"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; +import { StackNavigatorNavigation } from "~/components/RootNavigator/types/helpers"; +import { BaseNavigatorStackParamList } from "~/components/RootNavigator/types/BaseNavigator"; export default function Navigator() { const { colors } = useTheme(); const route = useRoute(); const accountListUIFF = useFeature("llmAccountListUI"); - const navigation = useNavigation(); + const navigation = useNavigation>(); const onClose = useCallback(() => { track("button_clicked", { button: "Close", screen: route.name, }); - }, [route]); + const rootParent = navigation.getParent(); + // this is the only way to go back to the root navigator + navigation.replace(rootParent?.getState().routeNames[0] as keyof BaseNavigatorStackParamList); + }, [route, navigation]); const stackNavigationConfig = useMemo( () => ({ ...getStackNavigatorConfig(colors, true), - headerRight: () => , + headerRight: () => , }), [colors, onClose], ); @@ -90,6 +95,9 @@ export default function Navigator() { headerLeft: () => null, headerTransparent: true, }} + initialParams={{ + onCloseNavigation: onClose, + }} /> null, headerTransparent: true, }} + initialParams={{ + onCloseNavigation: onClose, + }} /> null, + headerLeft: () => , headerTransparent: true, }} + initialParams={{ + onCloseNavigation: onClose, + }} /> ); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/types.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/types.ts index 39b830fd86cf..618d1e74b684 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/types.ts +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/types.ts @@ -7,6 +7,7 @@ import { Props as TouchableProps } from "~/components/Touchable"; type CommonParams = { context?: "addAccounts" | "receiveFunds"; onSuccess?: () => void; + onCloseNavigation?: () => void; currency: CryptoOrTokenCurrency; }; export type NetworkBasedAddAccountNavigator = { @@ -27,7 +28,7 @@ export type NetworkBasedAddAccountNavigator = { emptyAccount?: Account; emptyAccountName?: string; }; - [ScreenName.NoAssociatedAccounts]: { + [ScreenName.NoAssociatedAccounts]: Pick & { CustomNoAssociatedAccounts: ({ style, }: { diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountSuccess/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountSuccess/index.tsx index 31418641182d..9f70664e94af 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountSuccess/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountSuccess/index.tsx @@ -1,4 +1,4 @@ -import { Button, Flex, Icons, rgba, Text } from "@ledgerhq/native-ui"; +import { Flex, Icons, rgba, Text } from "@ledgerhq/native-ui"; import React, { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { @@ -25,6 +25,7 @@ import { getCurrencyColor } from "@ledgerhq/live-common/currencies/index"; import { useNavigation } from "@react-navigation/core"; import useAnimatedStyle from "../ScanDeviceAccounts/components/ScanDeviceAccountsFooter/useAnimatedStyle"; import AddFundsButton from "../../components/AddFundsButton"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; type Props = BaseComposite< StackNavigatorProps @@ -46,7 +47,7 @@ export default function AddAccountsSuccess({ route }: Props) { [navigation], ); - const { currency, accountsToAdd } = route.params || {}; + const { currency, accountsToAdd, onCloseNavigation } = route.params || {}; const renderItem = useCallback( ({ item }: ListRenderItemInfo) => ( @@ -98,9 +99,11 @@ export default function AddAccountsSuccess({ route }: Props) { - + ); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountWarning/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountWarning/index.tsx index 7f8d27811bac..f5ee414065fb 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountWarning/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccountWarning/index.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { Button, Flex, Icons, rgba, Text } from "@ledgerhq/native-ui"; +import { Flex, Icons, rgba, Text } from "@ledgerhq/native-ui"; import { useTranslation } from "react-i18next"; import { Animated, StyleSheet, TouchableOpacity, View } from "react-native"; import { useTheme } from "styled-components/native"; @@ -16,6 +16,7 @@ import BigNumber from "bignumber.js"; import { useNavigation } from "@react-navigation/core"; import useAnimatedStyle from "../ScanDeviceAccounts/components/ScanDeviceAccountsFooter/useAnimatedStyle"; import AddFundsButton from "../../components/AddFundsButton"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; type Props = BaseComposite< StackNavigatorProps >; @@ -36,7 +37,7 @@ export default function AddAccountsWarning({ route }: Props) { }, [navigation], ); - const { emptyAccount, emptyAccountName, currency } = route.params || {}; + const { emptyAccount, emptyAccountName, currency, onCloseNavigation } = route.params || {}; const statusColor = colors.warning.c70; @@ -85,9 +86,11 @@ export default function AddAccountsWarning({ route }: Props) { - + ); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/NoAssociatedAccountsView/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/NoAssociatedAccountsView/index.tsx index 3218989a70fc..3ff95699c09b 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/NoAssociatedAccountsView/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/NoAssociatedAccountsView/index.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Flex, Icons, rgba, Button } from "@ledgerhq/native-ui"; +import { Flex, Icons, rgba } from "@ledgerhq/native-ui"; import { StyleSheet, View } from "react-native"; import { useTheme } from "styled-components/native"; import SafeAreaView from "~/components/SafeAreaView"; @@ -10,6 +10,7 @@ import { useTranslation } from "react-i18next"; import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; import { NetworkBasedAddAccountNavigator } from "../AddAccount/types"; import { ScreenName } from "~/const"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; type Props = BaseComposite< StackNavigatorProps @@ -18,7 +19,7 @@ export default function NoAssociatedAccountsView({ route }: Props) { const { colors } = useTheme(); const insets = useSafeAreaInsets(); const { t } = useTranslation(); - const { CustomNoAssociatedAccounts } = route.params || {}; + const { CustomNoAssociatedAccounts, onCloseNavigation } = route.params || {}; const statusColor = colors.primary.c70; return ( @@ -48,9 +49,11 @@ export default function NoAssociatedAccountsView({ route }: Props) { {} - + ); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/ScanDeviceAccounts/useScanDeviceAccountsViewModel.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/ScanDeviceAccounts/useScanDeviceAccountsViewModel.ts index 6005a345827b..6750884f901d 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/ScanDeviceAccounts/useScanDeviceAccountsViewModel.ts +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/ScanDeviceAccounts/useScanDeviceAccountsViewModel.ts @@ -43,6 +43,7 @@ export default function useScanDeviceAccountsViewModel({ device: { deviceId }, inline, returnToSwap, + onCloseNavigation, } = route.params || {}; const newAccountSchemes = useMemo(() => { @@ -292,5 +293,6 @@ export default function useScanDeviceAccountsViewModel({ viewAllCreatedAccounts, returnToSwap, currency, + onCloseNavigation, }; } diff --git a/apps/ledger-live-mobile/src/newArch/features/AssetSelection/Navigator.tsx b/apps/ledger-live-mobile/src/newArch/features/AssetSelection/Navigator.tsx index d6aae06a7341..7f85ce9fed2c 100644 --- a/apps/ledger-live-mobile/src/newArch/features/AssetSelection/Navigator.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/AssetSelection/Navigator.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useMemo } from "react"; import { Platform } from "react-native"; import { createStackNavigator } from "@react-navigation/stack"; import { useTheme } from "styled-components/native"; -import { useRoute } from "@react-navigation/native"; +import { useNavigation, useRoute } from "@react-navigation/native"; import { NavigatorName, ScreenName } from "~/const"; import { getStackNavigatorConfig } from "~/navigation/navigatorConfig"; import { track } from "~/analytics"; @@ -13,10 +13,10 @@ import { hasClosedNetworkBannerSelector } from "~/reducers/settings"; import { urls } from "~/utils/urls"; import SelectCrypto from "LLM/features/AssetSelection/screens/SelectCrypto"; import SelectNetwork from "LLM/features/AssetSelection/screens/SelectNetwork"; -import { NavigationHeaderCloseButtonAdvanced } from "~/components/NavigationHeaderCloseButton"; import { NavigationHeaderBackButton } from "~/components/NavigationHeaderBackButton"; import { AssetSelectionNavigatorParamsList } from "./types"; import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; type NavigationProps = BaseComposite< StackNavigatorProps @@ -28,20 +28,22 @@ export default function Navigator() { const hasClosedNetworkBanner = useSelector(hasClosedNetworkBannerSelector); const { token, currency } = route.params || {}; + const navigation = useNavigation(); - const onClose = useCallback(() => { + const handleOnCloseAssetSelectionNavigator = useCallback(() => { track("button_clicked", { button: "Close", screen: route.name, }); - }, [route]); + navigation.getParent()?.goBack(); + }, [route, navigation]); const stackNavigationConfig = useMemo( () => ({ ...getStackNavigatorConfig(colors, true), - headerRight: () => , + headerRight: () => , }), - [colors, onClose], + [colors, handleOnCloseAssetSelectionNavigator], ); return ( @@ -60,7 +62,6 @@ export default function Navigator() { options={{ headerLeft: () => , title: "", - headerRight: () => , }} initialParams={route.params} /> @@ -76,7 +77,7 @@ export default function Navigator() { {hasClosedNetworkBanner && ( )} - + {stackNavigationConfig.headerRight()} ), }} diff --git a/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/Navigator.tsx b/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/Navigator.tsx index d21a580b0c0d..f945136adbd6 100644 --- a/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/Navigator.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/Navigator.tsx @@ -3,33 +3,33 @@ import { Platform } from "react-native"; import { createStackNavigator } from "@react-navigation/stack"; import { useTheme } from "styled-components/native"; import { useTranslation } from "react-i18next"; -import { useRoute } from "@react-navigation/native"; +import { useNavigation, useRoute } from "@react-navigation/native"; import { ScreenName } from "~/const"; import { getStackNavigatorConfig } from "~/navigation/navigatorConfig"; import { track } from "~/analytics"; -import SelectDevice, { - addAccountsSelectDeviceHeaderOptions, -} from "LLM/features/DeviceSelection/screens/SelectDevice"; +import SelectDevice from "LLM/features/DeviceSelection/screens/SelectDevice"; import StepHeader from "~/components/StepHeader"; -import { NavigationHeaderCloseButtonAdvanced } from "~/components/NavigationHeaderCloseButton"; import { DeviceSelectionNavigatorParamsList } from "./types"; +import CloseWithConfirmation from "LLM/components/CloseWithConfirmation"; export default function Navigator() { const { colors } = useTheme(); const { t } = useTranslation(); const route = useRoute(); + const navigation = useNavigation(); const onClose = useCallback(() => { track("button_clicked", { button: "Close", screen: route.name, }); - }, [route]); + navigation.getParent()?.goBack(); + }, [route, navigation]); const stackNavigationConfig = useMemo( () => ({ ...getStackNavigatorConfig(colors, true), - headerRight: () => , + headerRight: () => , }), [colors, onClose], ); @@ -55,7 +55,6 @@ export default function Navigator() { title={t("transfer.receive.stepperHeader.connectDevice")} /> ), - ...addAccountsSelectDeviceHeaderOptions(onClose), }} initialParams={route.params} /> diff --git a/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/types.ts b/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/types.ts index 2de24308e2f9..24c040a6d2c5 100644 --- a/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/types.ts +++ b/apps/ledger-live-mobile/src/newArch/features/DeviceSelection/types.ts @@ -7,6 +7,7 @@ import { StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; type CommonParams = { context?: "addAccounts" | "receiveFunds"; onSuccess?: () => void; + onCloseNavigation?: () => void; }; export type SelectDeviceRouteParams = CommonParams & {