diff --git a/.changeset/clever-dolls-greet.md b/.changeset/clever-dolls-greet.md new file mode 100644 index 000000000000..78a76f114535 --- /dev/null +++ b/.changeset/clever-dolls-greet.md @@ -0,0 +1,5 @@ +--- +"live-mobile": minor +--- + +Create reusable emptyList component and use it for accountsList and assetsList diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json index 64487a73fa99..0585b9592546 100644 --- a/apps/ledger-live-mobile/src/locales/en/common.json +++ b/apps/ledger-live-mobile/src/locales/en/common.json @@ -7235,5 +7235,13 @@ "detectedAccounts": "{{count}} account (detected)", "detectedAccounts_plural": "{{count}} accounts (detected)" } + }, + "emptyList": { + "accounts": { + "title": "No accounts found", + "subTitle": "Looks like you haven’t added an account yet. Get started now.", + "cta": "Add an account", + "link": "Need help? Learn how to add an account to Ledger\u00a0Live." + } } } diff --git a/apps/ledger-live-mobile/src/newArch/components/EmptyList/AccountsEmptyList/index.tsx b/apps/ledger-live-mobile/src/newArch/components/EmptyList/AccountsEmptyList/index.tsx new file mode 100644 index 000000000000..8561fcd92feb --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/components/EmptyList/AccountsEmptyList/index.tsx @@ -0,0 +1,35 @@ +import React, { useState } from "react"; +import AddAccountDrawer from "LLM/features/Accounts/screens/AddAccount"; +import { urls } from "~/utils/urls"; +import EmptyList from "../components"; +import { track } from "~/analytics"; + +type Props = { + sourceScreenName: string; +}; + +const AccountsEmptyList = ({ sourceScreenName }: Props) => { + const [isAddModalOpened, setIsAddModalOpened] = useState(false); + + const openAddModal = () => { + track("button_clicked", { button: "Add a new account", page: sourceScreenName }); + setIsAddModalOpened(true); + }; + const closeAddModal = () => setIsAddModalOpened(false); + + return ( + <> + + + + ); +}; + +export default AccountsEmptyList; diff --git a/apps/ledger-live-mobile/src/newArch/components/EmptyList/__tests__/AccountsEmptyList.test.tsx b/apps/ledger-live-mobile/src/newArch/components/EmptyList/__tests__/AccountsEmptyList.test.tsx new file mode 100644 index 000000000000..d6b8e146eeec --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/components/EmptyList/__tests__/AccountsEmptyList.test.tsx @@ -0,0 +1,58 @@ +import React, { ReactNode } from "react"; +import { renderWithReactQuery } from "@tests/test-renderer"; +import AccountsEmptyList from "../AccountsEmptyList/index"; +import { track } from "~/analytics"; +import { Linking } from "react-native"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; + +const Stack = createNativeStackNavigator(); + +const MockNavigator = ({ children }: { children: ReactNode }) => ( + + {() => children} + +); + +describe("AccountsEmptyList", () => { + it("should render the empty list screen", () => { + const { getByText } = renderWithReactQuery( + + + , + ); + expect(getByText(/no accounts found/i)).toBeVisible(); + expect( + getByText(/looks like you haven’t added an account yet. get started now/i), + ).toBeVisible(); + expect(getByText("Add an account")).toBeVisible(); + expect(getByText(/need help\? learn how to add an account to ledger live./i)).toBeVisible(); + }); + + it("should trigger the track on the button and open the drawer", async () => { + const { getByText, user } = renderWithReactQuery( + + + , + ); + expect(getByText("Add an account")).toBeVisible(); + await user.press(getByText("Add an account")); + expect(track).toHaveBeenCalledWith("button_clicked", { + button: "Add a new account", + page: "AccountsEmptyList", + }); + expect(getByText(/add another account/i)).toBeVisible(); + }); + + it("should trigger the openUrl with good url", async () => { + const { getByText, user } = renderWithReactQuery( + + + , + ); + const url = "https://support.ledger.com/article/4404389482641-zd"; + const link = getByText(/need help\? learn how to add an account to ledger live./i); + expect(link).toBeVisible(); + await user.press(link); + expect(Linking.openURL).toHaveBeenCalledWith(url); + }); +}); diff --git a/apps/ledger-live-mobile/src/newArch/components/EmptyList/components/index.tsx b/apps/ledger-live-mobile/src/newArch/components/EmptyList/components/index.tsx new file mode 100644 index 000000000000..bece432b7c3f --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/components/EmptyList/components/index.tsx @@ -0,0 +1,86 @@ +import React from "react"; +import { Flex, Text, Button, Link } from "@ledgerhq/native-ui"; +import { useTranslation } from "react-i18next"; +import { Linking } from "react-native"; + +type Props = { + titleKey: string; + subTitleKey?: string; +} & ( + | { + buttonTextKey: string; + onButtonPress: () => void; + } + | { + buttonTextKey?: never; + onButtonPress?: never; + } +) & + ( + | { + linkTextKey: string; + urlLink: string; + } + | { + linkTextKey?: never; + urlLink?: never; + } + ); + +const EmptyList: React.FC = ({ + titleKey, + subTitleKey, + buttonTextKey, + linkTextKey, + urlLink, + onButtonPress, +}) => { + const { t } = useTranslation(); + + const onLinkPress = (url: string) => Linking.openURL(url); + + return ( + + {!!titleKey && ( + + {t(titleKey)} + + )} + {!!subTitleKey && ( + + {t(subTitleKey)} + + )} + {!!buttonTextKey && ( + + )} + {!!linkTextKey && ( + onLinkPress(urlLink)} size="medium"> + + {t(linkTextKey)} + + + )} + + ); +}; +export default EmptyList; diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/__integrations__/accountsListScreen.integration.test.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/__integrations__/accountsListScreen.integration.test.tsx index 0950d3f3cea2..080effe48648 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/__integrations__/accountsListScreen.integration.test.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/__integrations__/accountsListScreen.integration.test.tsx @@ -40,7 +40,10 @@ jest.mock("@ledgerhq/live-countervalues-react", () => ({ })); describe("AccountsList Screen", () => { - const renderComponent = (params: AccountsListNavigator[ScreenName.AccountsList]) => { + const renderComponent = ( + params: AccountsListNavigator[ScreenName.AccountsList], + withoutAccount: boolean = false, + ) => { const Stack = createStackNavigator(); return renderWithReactQuery( @@ -53,6 +56,15 @@ describe("AccountsList Screen", () => { , { ...INITIAL_STATE, + ...(withoutAccount && { + overrideInitialState: (state: State) => ({ + ...state, + accounts: { + ...state.accounts, + active: [], + }, + }), + }), }, ); }; @@ -139,4 +151,22 @@ describe("AccountsList Screen", () => { expect(getByText(/use your ledger device/i)).toBeVisible(); expect(getByText(/use ledger sync/i)).toBeVisible(); }); + + it("should render the empty list screen", async () => { + const { getByText } = renderComponent( + { + sourceScreenName: ScreenName.AccountsList, + showHeader: true, + canAddAccount: true, + }, + true, + ); + + expect(getByText(/no accounts found/i)).toBeVisible(); + expect( + getByText(/looks like you haven’t added an account yet. get started now/i), + ).toBeVisible(); + expect(getByText("Add an account")).toBeVisible(); + expect(getByText(/need help\? learn how to add an account to ledger live./i)).toBeVisible(); + }); }); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useGenericAccountsListViewModel.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useGenericAccountsListViewModel.ts new file mode 100644 index 000000000000..caca439002ba --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useGenericAccountsListViewModel.ts @@ -0,0 +1,44 @@ +import { useSelector } from "react-redux"; +import { useGlobalSyncState } from "@ledgerhq/live-common/bridge/react/useGlobalSyncState"; +import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; +import { ScreenName } from "~/const"; +import { hasNoAccountsSelector, isUpToDateSelector } from "~/reducers/accounts"; +import { parseBoolean } from "LLM/utils/parseBoolean"; +import { TrackingEvent } from "../../../enums"; +import { AccountsListNavigator } from "../types"; +export type Props = BaseComposite< + StackNavigatorProps +>; + +export type GenericAccountsType = ReturnType; + +export default function useGenericAccountsListViewModel({ route }: Props) { + const { params } = route; + + const hasNoAccount = useSelector(hasNoAccountsSelector); + const isUpToDate = useSelector(isUpToDateSelector); + + const canAddAccount = + (params?.canAddAccount ? parseBoolean(params?.canAddAccount) : false) && !hasNoAccount; + const showHeader = + (params?.showHeader ? parseBoolean(params?.showHeader) : false) && !hasNoAccount; + const isSyncEnabled = params?.isSyncEnabled ? parseBoolean(params?.isSyncEnabled) : false; + const sourceScreenName = params?.sourceScreenName; + const specificAccounts = params?.specificAccounts; + + const globalSyncState = useGlobalSyncState(); + const syncPending = globalSyncState.pending && !isUpToDate; + + const pageTrackingEvent = TrackingEvent.AccountsList; + + return { + hasNoAccount, + isSyncEnabled, + canAddAccount, + showHeader, + pageTrackingEvent, + syncPending, + sourceScreenName, + specificAccounts, + }; +} diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useSpecificAccountsListViewModel.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useSpecificAccountsListViewModel.ts new file mode 100644 index 000000000000..dac32ef9b564 --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/hooks/useSpecificAccountsListViewModel.ts @@ -0,0 +1,116 @@ +import { useMemo } from "react"; +import { useSelector } from "react-redux"; +import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; +import { getAccountCurrency } from "@ledgerhq/live-common/account/index"; +import { useGlobalSyncState } from "@ledgerhq/live-common/bridge/react/useGlobalSyncState"; +import { LoadingBasedGroupedCurrencies, LoadingStatus } from "@ledgerhq/live-common/deposit/type"; +import { useGroupedCurrenciesByProvider } from "@ledgerhq/live-common/deposit/index"; +import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; +import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; +import { ScreenName } from "~/const"; +import { hasNoAccountsSelector, isUpToDateSelector } from "~/reducers/accounts"; +import { parseBoolean } from "LLM/utils/parseBoolean"; +import { TrackingEvent } from "../../../enums"; +import { AccountsListNavigator } from "../types"; +import { useNavigation } from "@react-navigation/core"; +import { + navigateToAssetSelection, + navigateToDeviceSelection, + navigateToNetworkSelection, +} from "../utils/navigation"; +import { getTicker } from "../utils/getTicker"; +import { Account, TokenAccount } from "@ledgerhq/types-live"; + +export type Props = BaseComposite< + StackNavigatorProps +> & { + specificAccounts: Account[] | TokenAccount[]; +}; + +export type SpecificAccountsType = ReturnType; + +export default function useSpecificAccountsListViewModel({ route, specificAccounts }: Props) { + const navigation = useNavigation(); + const { params } = route; + + const llmNetworkBasedAddAccountFlow = useFeature("llmNetworkBasedAddAccountFlow"); + const isLlmNetworkBasedAddAccountFlowEnabled = llmNetworkBasedAddAccountFlow?.enabled; + + const hasNoAccount = useSelector(hasNoAccountsSelector); + const isUpToDate = useSelector(isUpToDateSelector); + + const canAddAccount = + (params?.canAddAccount ? parseBoolean(params?.canAddAccount) : false) && !hasNoAccount; + const showHeader = + (params?.showHeader ? parseBoolean(params?.showHeader) : false) && !hasNoAccount; + const isSyncEnabled = params?.isSyncEnabled ? parseBoolean(params?.isSyncEnabled) : false; + const sourceScreenName = params?.sourceScreenName; + + const globalSyncState = useGlobalSyncState(); + const syncPending = globalSyncState.pending && !isUpToDate; + + const { result, loadingStatus: providersLoadingStatus } = useGroupedCurrenciesByProvider( + true, + ) as LoadingBasedGroupedCurrencies; + + const ticker = getTicker(specificAccounts[0]); + const currency = getAccountCurrency(specificAccounts[0]); + const { currenciesByProvider } = result; + + const provider = useMemo( + () => + currenciesByProvider.find(elem => + elem.currenciesByNetwork.some( + currencyByNetwork => + (currencyByNetwork as CryptoCurrency | TokenCurrency).id === currency.id, + ), + ), + [currenciesByProvider, currency], + ); + + const isAddAccountCtaDisabled = [LoadingStatus.Pending, LoadingStatus.Error].includes( + providersLoadingStatus, + ); + + const hasNetworksProviders = provider && currenciesByProvider.length > 1; + + const onAddAccount = () => { + if (isLlmNetworkBasedAddAccountFlowEnabled && currency) { + if (hasNetworksProviders) { + navigateToNetworkSelection({ + navigation, + currency, + }); + } else { + navigateToDeviceSelection({ + navigation, + currency, + }); + } + } else { + navigateToAssetSelection({ + navigation, + currency, + }); + } + }; + + const onClick = onAddAccount; + const pageTrackingEvent = TrackingEvent.AccountListSummary; + const currencyToTrack = currency.name; + + return { + hasNoAccount, + isSyncEnabled, + canAddAccount, + showHeader, + isAddAccountCtaDisabled, + pageTrackingEvent, + currencyToTrack, + ticker, + syncPending, + sourceScreenName, + specificAccounts, + onClick, + }; +} diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/index.tsx index 3c31f3d0300f..32155e3292db 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/index.tsx @@ -1,117 +1,43 @@ -import React, { useCallback, useMemo } from "react"; +import React from "react"; import AccounstListView from "LLM/features/Accounts/components/AccountsListView"; -import { NavigatorName, ScreenName } from "~/const"; +import { ScreenName } from "~/const"; import { ReactNavigationPerformanceView } from "@shopify/react-native-performance-navigation"; -import { StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; import SafeAreaView from "~/components/SafeAreaView"; import { Flex, Text } from "@ledgerhq/native-ui"; import AddAccountButton from "LLM/features/Accounts/components/AddAccountButton"; -import { AccountsListNavigator } from "./types"; import { useTranslation } from "react-i18next"; import { TrackScreen } from "~/analytics"; -import { useGlobalSyncState } from "@ledgerhq/live-common/bridge/react/useGlobalSyncState"; import { RefreshMedium } from "@ledgerhq/icons-ui/nativeLegacy"; -import { useSelector } from "react-redux"; import Spinning from "~/components/Spinning"; -import { isUpToDateSelector } from "~/reducers/accounts"; +import AccountsEmptyList from "LLM/components/EmptyList/AccountsEmptyList"; +import useGenericAccountsListViewModel, { + GenericAccountsType, +} from "./hooks/useGenericAccountsListViewModel"; +import useSpecificAccountsListViewModel, { + SpecificAccountsType, +} from "./hooks/useSpecificAccountsListViewModel"; import { Account, TokenAccount } from "@ledgerhq/types-live"; -import { - getAccountCurrency, - isTokenAccount as isTokenAccountChecker, -} from "@ledgerhq/live-common/account/index"; -import { useNavigation } from "@react-navigation/native"; -import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; -import { useGroupedCurrenciesByProvider } from "@ledgerhq/live-common/deposit/index"; -import { LoadingBasedGroupedCurrencies, LoadingStatus } from "@ledgerhq/live-common/deposit/type"; -import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; -import { TrackingEvent } from "../../enums"; -import { parseBoolean } from "LLM/utils/parseBoolean"; -import { AddAccountContexts } from "../AddAccount/enums"; -type Props = StackNavigatorProps; - -export default function AccountsList({ route }: Props) { - const { params } = route; - const { t } = useTranslation(); - - const canAddAccount = params?.canAddAccount ? parseBoolean(params?.canAddAccount) : false; - const showHeader = params?.showHeader ? parseBoolean(params?.showHeader) : false; - const isSyncEnabled = params?.isSyncEnabled ? parseBoolean(params?.isSyncEnabled) : false; - const sourceScreenName = params?.sourceScreenName; - - const specificAccounts = params?.specificAccounts; - const navigation = useNavigation(); - const llmNetworkBasedAddAccountFlow = useFeature("llmNetworkBasedAddAccountFlow"); - - const isTokenAccount = specificAccounts && isTokenAccountChecker(specificAccounts[0]); - const ticker = specificAccounts - ? isTokenAccount - ? (specificAccounts[0] as TokenAccount).token.ticker - : (specificAccounts[0] as Account).currency.ticker - : undefined; - - const isUpToDate = useSelector(isUpToDateSelector); - const globalSyncState = useGlobalSyncState(); - const syncPending = globalSyncState.pending && !isUpToDate; - - const currency = specificAccounts ? getAccountCurrency(specificAccounts?.[0]) : null; - - const { result, loadingStatus: providersLoadingStatus } = useGroupedCurrenciesByProvider( - true, - ) as LoadingBasedGroupedCurrencies; - - const isAddAccountCtaDisabled = [LoadingStatus.Pending, LoadingStatus.Error].includes( - providersLoadingStatus, - ); - - const { currenciesByProvider } = result; - - const provider = useMemo( - () => - currency && - currenciesByProvider.find(elem => - elem.currenciesByNetwork.some( - currencyByNetwork => - (currencyByNetwork as CryptoCurrency | TokenCurrency).id === currency.id, - ), - ), - [currenciesByProvider, currency], - ); +import { BaseComposite, StackNavigatorProps } from "~/components/RootNavigator/types/helpers"; +import { AccountsListNavigator } from "./types"; - const onAddAccount = useCallback(() => { - if (!specificAccounts) return; +type ViewProps = GenericAccountsType & Partial; - if (llmNetworkBasedAddAccountFlow?.enabled && currency) { - if (provider && provider?.currenciesByNetwork.length > 1) { - navigation.navigate(NavigatorName.AssetSelection, { - screen: ScreenName.SelectNetwork, - params: { - currency: currency.id, - context: AddAccountContexts.AddAccounts, - sourceScreenName: ScreenName.AccountsList, - }, - }); - } else { - navigation.navigate(NavigatorName.DeviceSelection, { - screen: ScreenName.SelectDevice, - params: { - currency: currency as CryptoCurrency, - context: AddAccountContexts.AddAccounts, - }, - }); - } - } else { - navigation.navigate(NavigatorName.AddAccounts, { - screen: undefined, - currency, - }); - } - }, [currency, llmNetworkBasedAddAccountFlow?.enabled, navigation, provider, specificAccounts]); +function View({ + hasNoAccount, + isSyncEnabled, + canAddAccount, + showHeader, + pageTrackingEvent, + syncPending, + sourceScreenName, + specificAccounts, + isAddAccountCtaDisabled, + currencyToTrack, + ticker, + onClick, +}: ViewProps) { + const { t } = useTranslation(); - const onClick = specificAccounts ? onAddAccount : undefined; - const pageTrackingEvent = specificAccounts - ? TrackingEvent.AccountListSummary - : TrackingEvent.AccountsList; - const currencyToTrack = specificAccounts ? currency?.name : undefined; return ( <> @@ -142,13 +68,47 @@ export default function AccountsList({ route }: Props) { onClick={onClick} /> )} - + {hasNoAccount ? ( + + ) : ( + + )} ); } + +export type Props = BaseComposite< + StackNavigatorProps +>; + +const GenericAccountsList = (props: Props) => { + return ; +}; + +const SpecificAccountsList = ({ + props, + specificAccounts, +}: { + props: Props; + specificAccounts: Account[] | TokenAccount[]; +}) => { + return ; +}; + +const AccountsList = (props: Props) => { + const { params } = props.route; + const hasSpecificAccounts = params?.specificAccounts && params?.specificAccounts.length > 0; + return hasSpecificAccounts ? ( + + ) : ( + + ); +}; + +export default AccountsList; diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/getTicker.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/getTicker.ts new file mode 100644 index 000000000000..92999b6d7f39 --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/getTicker.ts @@ -0,0 +1,8 @@ +import { Account, TokenAccount } from "@ledgerhq/types-live"; +import { isTokenAccount as isTokenAccountChecker } from "@ledgerhq/live-common/account/index"; + +export function getTicker(specificAccount: Account | TokenAccount) { + const isTokenAccount = isTokenAccountChecker(specificAccount); + if (isTokenAccount) return specificAccount.token.ticker; + return specificAccount.currency.ticker; +} diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/navigation.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/navigation.ts new file mode 100644 index 000000000000..8987f89e3512 --- /dev/null +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AccountsList/utils/navigation.ts @@ -0,0 +1,55 @@ +import { TokenCurrency, CryptoCurrency } from "@ledgerhq/types-cryptoassets"; +import { NavigationProp, NavigationState } from "@react-navigation/core"; +import { NavigatorName, ScreenName } from "~/const"; +import { AddAccountContexts } from "../../AddAccount/enums"; + +type NavigationType = Omit, "getState"> & { + getState(): NavigationState | undefined; +}; + +type NavigateFunctionsType = { + navigation: NavigationType; + currency: TokenCurrency | CryptoCurrency | null | undefined; +}; + +export function navigateToAssetSelection({ + navigation, + currency, +}: Readonly) { + navigation.navigate(NavigatorName.AddAccounts, { + screen: undefined, + currency, + }); +} + +export function navigateToDeviceSelection({ + navigation, + currency, +}: Readonly) { + navigation.navigate(NavigatorName.DeviceSelection, { + screen: ScreenName.SelectDevice, + params: { + currency: currency as CryptoCurrency, + context: AddAccountContexts.AddAccounts, + }, + }); +} + +type NavigateToNetworkSelectionType = { + navigation: NavigationType; + currency: TokenCurrency | CryptoCurrency; +}; + +export function navigateToNetworkSelection({ + navigation, + currency, +}: Readonly) { + navigation.navigate(NavigatorName.AssetSelection, { + screen: ScreenName.SelectNetwork, + params: { + currency: currency.id, + context: AddAccountContexts.AddAccounts, + sourceScreenName: ScreenName.AccountsList, + }, + }); +} diff --git a/apps/ledger-live-mobile/src/newArch/features/Assets/screens/AssetsList/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Assets/screens/AssetsList/index.tsx index 481e1259521a..a338c48a1ff6 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Assets/screens/AssetsList/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Assets/screens/AssetsList/index.tsx @@ -9,18 +9,22 @@ import { AssetsListNavigator } from "./types"; import { useTranslation } from "react-i18next"; import { TrackScreen } from "~/analytics"; import { useSelector } from "react-redux"; -import { isUpToDateSelector } from "~/reducers/accounts"; +import { hasNoAccountsSelector, isUpToDateSelector } from "~/reducers/accounts"; import { useGlobalSyncState } from "@ledgerhq/live-common/bridge/react/useGlobalSyncState"; import { RefreshMedium } from "@ledgerhq/icons-ui/nativeLegacy"; import Spinning from "~/components/Spinning"; import { parseBoolean } from "LLM/utils/parseBoolean"; +import AccountsEmptyList from "LLM/components/EmptyList/AccountsEmptyList"; type Props = StackNavigatorProps; export default function AssetsList({ route }: Props) { const { params } = route; const { t } = useTranslation(); - const showHeader = params?.showHeader ? parseBoolean(params?.showHeader) : false; + const hasNoAccount = useSelector(hasNoAccountsSelector); + + const showHeader = + (params?.showHeader ? parseBoolean(params?.showHeader) : false) && !hasNoAccount; const isSyncEnabled = params?.isSyncEnabled ? parseBoolean(params?.isSyncEnabled) : false; const sourceScreenName = params?.sourceScreenName; @@ -48,7 +52,11 @@ export default function AssetsList({ route }: Props) { )} - + {hasNoAccount ? ( + + ) : ( + + )}