Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(llm): new add account drawer on assets screen with WS entrypoint #7064

Merged
merged 10 commits into from
Jun 19, 2024
5 changes: 5 additions & 0 deletions .changeset/cool-dingos-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Create a new drawer component on add account. This new drawer has new UI and an entry point to walletSync. This entrypoint is hidden under a feature flag. Also update translations related to WS.
18 changes: 17 additions & 1 deletion apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@
"subtitle": "Select how you’d like to access your wallet:",
"connect": "Connect your Ledger",
"sync": "Sync with Ledger Live desktop",
"walletSync": "Sync with another Ledger Live"
"walletSync": "Sync with another Ledger Live app"
},
"discoverLive": {
"exploreWithoutADevice": "Explore without a device",
Expand Down Expand Up @@ -2288,6 +2288,22 @@
"import": {
"title": "Import from desktop",
"description": "Import asset from Ledger Live Desktop"
},
"drawer": {
"drawerTitleHasAccount": "Add another account",
"drawerSubTitle": "Add your assets using your Ledger, or import them directly from your Ledger Live Desktop app.",
"import": {
"title": "Import from desktop",
"description": "Import asset from Ledger Live Desktop"
},
"add": {
"title": "Add with your Ledger",
"description": "Create or import your assets using your Ledger device"
},
"walletSync": {
"title": "Import via another Ledger Live app",
"description": "Activate Ledger Sync"
}
}
},
"byteSize": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we follow the guidelines we can't add a drawers folder here.
We should put AddAccount (PascalCase) under screens or components folder.
https://ledgerhq.atlassian.net/wiki/spaces/WXP/pages/4508058220/Code+Guidelines+-+React+Native#Folder-organization

import React from "react";
import useAddAccountDrawer from "LLM/features/WalletSync/hooks/useAddAccountDrawer";
import DummyDrawer from "../DummyDrawer";
import ActionRow from "../components/ActionRow";
import QueuedDrawer from "~/components/QueuedDrawer";
import { useTranslation } from "react-i18next";
import { TrackScreen } from "~/analytics";
import { Flex, Icons, Text } from "@ledgerhq/native-ui";
import { AddAccountDrawerProps } from "LLM/features/WalletSync/types/addAccountDrawer";

const AddAccountDrawer = ({
isOpened,
currency,
doesNotHaveAccount,
onClose,
reopenDrawer,
}: AddAccountDrawerProps) => {
const { t } = useTranslation();
const rows = [];

const {
isWalletSyncEnabled,
isReadOnlyModeEnabled,
isAddAccountDrawerVisible,
isWalletSyncDrawerVisible,
onClickAdd,
onClickImport,
onClickWalletSync,
onCloseAddAccountDrawer,
onCloseWalletSyncDrawer,
} = useAddAccountDrawer({ isOpened, currency, onClose, reopenDrawer });

if (!isReadOnlyModeEnabled) {
rows.push({
titleKey: "addAccountsModal.drawer.add.title",
descriptionKey: "addAccountsModal.drawer.add.description",
onPress: onClickAdd,
icon: <Icons.LedgerDevices color={"primary.c80"} />,
testID: "add-accounts-modal-add-button",
});
}

if (isWalletSyncEnabled) {
rows.push({
titleKey: "addAccountsModal.drawer.walletSync.title",
descriptionKey: "addAccountsModal.drawer.walletSync.description",
onPress: onClickWalletSync,
icon: <Icons.QrCode color={"primary.c80"} />,
});
} else {
rows.push({
titleKey: "addAccountsModal.drawer.import.title",
descriptionKey: "addAccountsModal.drawer.import.description",
onPress: onClickImport,
icon: <Icons.QrCode color={"primary.c80"} />,
});
}

return (
<>
<QueuedDrawer
isRequestingToBeOpened={isAddAccountDrawerVisible}
onClose={onCloseAddAccountDrawer}
>
<TrackScreen category="Add/Import accounts" type="drawer" />
<Text variant="h4" fontWeight="semiBold" fontSize="24px" mb={16}>
{doesNotHaveAccount
? t("addAccountsModal.title")
: t("addAccountsModal.drawer.drawerTitleHasAccount")}
</Text>
<Text variant="large" fontWeight="medium" fontSize="14px" color="neutral.c70" mb="32px">
{t("addAccountsModal.drawer.drawerSubTitle")}
</Text>
<Flex flexDirection="column" rowGap={16}>
{rows.map((row, index) => (
<ActionRow
key={index}
title={t(row.titleKey)}
description={t(row.descriptionKey)}
onPress={row.onPress}
icon={row.icon}
testID={row.testID}
/>
))}
</Flex>
</QueuedDrawer>
<DummyDrawer isOpen={isWalletSyncDrawerVisible} handleClose={onCloseWalletSyncDrawer} />
</>
);
};

export default AddAccountDrawer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Flex, Text } from "@ledgerhq/native-ui";
import React from "react";
import Touchable from "~/components/Touchable";
import styled from "styled-components/native";
import { AddAccountDrawerRowProps } from "LLM/features/WalletSync/types/addAccountDrawer";

const TouchableCard = styled(Touchable)`
background-color: ${p => p.theme.colors.opacityDefault.c05};
border-radius: 8px;
padding: 16px;
align-items: center;
gap: 12px;
flex-direction: row;
align-self: stretch;
`;

const CardTitle = styled(Text)`
font-size: 16px;
color: ${p => p.theme.colors.neutral.c100};
`;

const CardDescription = styled(Text)`
font-size: 14px;
color: ${p => p.theme.colors.neutral.c70};
line-height: 18.2px;
`;

const ActionRow: React.FC<AddAccountDrawerRowProps> = ({
title,
description,
icon,
testID,
onPress,
}: AddAccountDrawerRowProps) => {
return (
<TouchableCard onPress={onPress} testID={testID}>
{icon}
<Flex flexDirection={"column"} rowGap={4} flex={1}>
<CardTitle>{title}</CardTitle>
{description && <CardDescription>{description}</CardDescription>}
</Flex>
</TouchableCard>
);
};
export default ActionRow;
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useSelector } from "react-redux";
import { BaseNavigation } from "~/components/RootNavigator/types/helpers";
import { readOnlyModeEnabledSelector } from "~/reducers/settings";
import { useNavigation } from "@react-navigation/native";
import { NavigatorName } from "~/const";
import { useCallback, useMemo, useState } from "react";
import { track } from "~/analytics";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { AddAccountDrawerProps } from "LLM/features/WalletSync/types/addAccountDrawer";

const useAddAccountDrawer = ({
isOpened,
currency,
onClose,
reopenDrawer,
}: AddAccountDrawerProps) => {
const navigation = useNavigation<BaseNavigation>();
const walletSyncFeatureFlag = useFeature("llmWalletSync");

const isReadOnlyModeEnabled = useSelector(readOnlyModeEnabledSelector);
const isWalletSyncEnabled = walletSyncFeatureFlag?.enabled;
const hasCurrency = !!currency;

const [isWalletSyncDrawerVisible, setWalletSyncDrawerVisible] = useState(false);

const navigationParams = useMemo(() => {
return hasCurrency
? currency.type === "TokenCurrency"
? { token: currency }
: { currency }
: {};
}, [hasCurrency, currency]);

const trackButtonClick = useCallback((button: string) => {
track("button_clicked", {
button,
drawer: "AddAccountsModal",
});
}, []);

const onClickImport = useCallback(() => {
trackButtonClick("Import from Desktop");
onClose();
navigation.navigate(NavigatorName.ImportAccounts);
}, [navigation, onClose, trackButtonClick]);

const onClickAdd = useCallback(() => {
trackButtonClick("With your Ledger");
onClose();
navigation.navigate(NavigatorName.AddAccounts, navigationParams);
}, [navigation, navigationParams, onClose, trackButtonClick]);

const onClickWalletSync = useCallback(() => {
trackButtonClick("With Wallet Sync");
onClose();
setWalletSyncDrawerVisible(true);
}, [trackButtonClick, onClose]);

const onCloseAddAccountDrawer = useCallback(() => {
trackButtonClick("Close 'x'");
onClose();
}, [trackButtonClick, onClose]);

const onCloseWalletSyncDrawer = useCallback(() => {
setWalletSyncDrawerVisible(false);
reopenDrawer();
}, [setWalletSyncDrawerVisible, reopenDrawer]);

return {
isWalletSyncEnabled,
isReadOnlyModeEnabled,
isAddAccountDrawerVisible: isOpened,
isWalletSyncDrawerVisible,
onClickAdd,
onClickImport,
onClickWalletSync,
onCloseAddAccountDrawer,
onCloseWalletSyncDrawer,
};
};

export default useAddAccountDrawer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
import Touchable from "~/components/Touchable";

export type AddAccountDrawerProps = {
isOpened: boolean;
currency?: CryptoCurrency | TokenCurrency | null;
doesNotHaveAccount?: boolean;
onClose: () => void;
reopenDrawer: () => void;
};

export type AddAccountDrawerRowProps = {
title: string;
description?: string;
icon: React.ReactNode;
testID?: string;
onPress: React.ComponentProps<typeof Touchable>["onPress"];
};
41 changes: 22 additions & 19 deletions apps/ledger-live-mobile/src/screens/Accounts/AddAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import React, { memo, useState } from "react";
import { useNavigation } from "@react-navigation/native";
import { Flex } from "@ledgerhq/native-ui";
import { PlusMedium } from "@ledgerhq/native-ui/assets/icons";
import { findCryptoCurrencyById, findTokenById } from "@ledgerhq/live-common/currencies/index";
import Touchable from "~/components/Touchable";
import AddAccountsModal from "../AddAccounts/AddAccountsModal";
import { track } from "~/analytics";
import { BaseNavigation } from "~/components/RootNavigator/types/helpers";
import AddAccountDrawer from "LLM/features/WalletSync/drawers/addAccount";

function AddAccount({ currencyId }: { currencyId?: string }) {
const navigation = useNavigation<BaseNavigation>();
const currency = currencyId
? findCryptoCurrencyById(currencyId) || findTokenById(currencyId)
: undefined;
Expand All @@ -26,26 +23,32 @@ function AddAccount({ currencyId }: { currencyId?: string }) {
setIsAddModalOpened(false);
}

function reopenAddModal() {
setIsAddModalOpened(true);
}

return (
<Touchable event="OpenAddAccountModal" onPress={openAddModal} testID="OpenAddAccountModal">
<Flex
bg={"neutral.c100"}
width={"32px"}
height={"32px"}
alignItems={"center"}
justifyContent={"center"}
borderRadius={32}
testID="add-account-button"
>
<PlusMedium size={20} color={"neutral.c00"} />
</Flex>
<AddAccountsModal
navigation={navigation}
<>
<Touchable event="OpenAddAccountModal" onPress={openAddModal} testID="OpenAddAccountModal">
<Flex
bg={"neutral.c100"}
width={"32px"}
height={"32px"}
alignItems={"center"}
justifyContent={"center"}
borderRadius={32}
testID="add-account-button"
>
<PlusMedium size={20} color={"neutral.c00"} />
</Flex>
</Touchable>
<AddAccountDrawer
isOpened={isAddModalOpened}
onClose={closeAddModal}
reopenDrawer={reopenAddModal}
currency={currency}
/>
</Touchable>
</>
);
}

Expand Down
Loading
Loading