-
Notifications
You must be signed in to change notification settings - Fork 364
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9215 from LedgerHQ/feat/LIVE-16967
💄 (llm) empty accounts/assets screen
- Loading branch information
Showing
12 changed files
with
523 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"live-mobile": minor | ||
--- | ||
|
||
Create reusable emptyList component and use it for accountsList and assetsList |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
apps/ledger-live-mobile/src/newArch/components/EmptyList/AccountsEmptyList/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<boolean>(false); | ||
|
||
const openAddModal = () => { | ||
track("button_clicked", { button: "Add a new account", page: sourceScreenName }); | ||
setIsAddModalOpened(true); | ||
}; | ||
const closeAddModal = () => setIsAddModalOpened(false); | ||
|
||
return ( | ||
<> | ||
<EmptyList | ||
titleKey="emptyList.accounts.title" | ||
subTitleKey="emptyList.accounts.subTitle" | ||
buttonTextKey="emptyList.accounts.cta" | ||
onButtonPress={openAddModal} | ||
linkTextKey="emptyList.accounts.link" | ||
urlLink={urls.addAccount} | ||
/> | ||
<AddAccountDrawer isOpened={isAddModalOpened} onClose={closeAddModal} /> | ||
</> | ||
); | ||
}; | ||
|
||
export default AccountsEmptyList; |
58 changes: 58 additions & 0 deletions
58
.../ledger-live-mobile/src/newArch/components/EmptyList/__tests__/AccountsEmptyList.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 }) => ( | ||
<Stack.Navigator> | ||
<Stack.Screen name="MockScreen">{() => children}</Stack.Screen> | ||
</Stack.Navigator> | ||
); | ||
|
||
describe("AccountsEmptyList", () => { | ||
it("should render the empty list screen", () => { | ||
const { getByText } = renderWithReactQuery( | ||
<MockNavigator> | ||
<AccountsEmptyList sourceScreenName="AccountsEmptyList" /> | ||
</MockNavigator>, | ||
); | ||
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( | ||
<MockNavigator> | ||
<AccountsEmptyList sourceScreenName="AccountsEmptyList" /> | ||
</MockNavigator>, | ||
); | ||
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( | ||
<MockNavigator> | ||
<AccountsEmptyList sourceScreenName="AccountsEmptyList" /> | ||
</MockNavigator>, | ||
); | ||
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); | ||
}); | ||
}); |
86 changes: 86 additions & 0 deletions
86
apps/ledger-live-mobile/src/newArch/components/EmptyList/components/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Props> = ({ | ||
titleKey, | ||
subTitleKey, | ||
buttonTextKey, | ||
linkTextKey, | ||
urlLink, | ||
onButtonPress, | ||
}) => { | ||
const { t } = useTranslation(); | ||
|
||
const onLinkPress = (url: string) => Linking.openURL(url); | ||
|
||
return ( | ||
<Flex flex={1} alignItems="center" justifyContent="center" px={6}> | ||
{!!titleKey && ( | ||
<Text | ||
textAlign="center" | ||
variant="h1Inter" | ||
fontWeight="semiBold" | ||
color="neutral.c100" | ||
mb={6} | ||
> | ||
{t(titleKey)} | ||
</Text> | ||
)} | ||
{!!subTitleKey && ( | ||
<Text | ||
textAlign="center" | ||
variant="bodyLineHeight" | ||
fontWeight="semiBold" | ||
color="neutral.c80" | ||
mb={8} | ||
> | ||
{t(subTitleKey)} | ||
</Text> | ||
)} | ||
{!!buttonTextKey && ( | ||
<Button onPress={onButtonPress} size="large" type="main" mb={8}> | ||
{t(buttonTextKey)} | ||
</Button> | ||
)} | ||
{!!linkTextKey && ( | ||
<Link onPress={() => onLinkPress(urlLink)} size="medium"> | ||
<Text | ||
fontWeight="semiBold" | ||
variant="paragraph" | ||
textAlign="center" | ||
style={{ textDecorationLine: "underline" }} | ||
> | ||
{t(linkTextKey)} | ||
</Text> | ||
</Link> | ||
)} | ||
</Flex> | ||
); | ||
}; | ||
export default EmptyList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
...c/newArch/features/Accounts/screens/AccountsList/hooks/useGenericAccountsListViewModel.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<AccountsListNavigator, ScreenName.AccountsList> | ||
>; | ||
|
||
export type GenericAccountsType = ReturnType<typeof useGenericAccountsListViewModel>; | ||
|
||
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, | ||
}; | ||
} |
Oops, something went wrong.