Skip to content

Commit

Permalink
support(Deeplink): Add Deeplink for Add Account and Accounts page
Browse files Browse the repository at this point in the history
  • Loading branch information
mcayuelas-ledger authored and LFBarreto committed Sep 26, 2022
1 parent 521582f commit 198d934
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-garlics-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": patch
---

Add Deeplink for Add Account and Accounts page
17 changes: 16 additions & 1 deletion apps/ledger-live-mobile/docs/linking.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ They all are prefixed by **_ledgerlive://_**

`ledgerlive://account` will redirect to accounts page

`ledgerlive://account?currency=btc` will open first bitcoin account found
`ledgerlive://account?currency=ethereum&address={{eth_account_address}}` will open a given ethereum account if found, will falback to the currency page found and if not to the list of accounts

`?currency` param can be name or ticker of the currency targeted
`?address` param requires currency to work, address of the account to select

- **_send?currency_** 🠒 Send Flow

Expand Down Expand Up @@ -49,6 +50,20 @@ They all are prefixed by **_ledgerlive://_**

`ledgerlive://swap` will redirect to swap page

- **_add_account_** 🠒 Add Account Crypto Flow

`ledgerlive://add-account` will redirect to add account page
`ledgerlive://add-account?currency=ethereum` will redirect to add account page with ethereum accounts search prefilled

- **_accounts_** 🠒 Accounts page

`ledgerlive://accounts` will redirect to accounts page

`ledgerlive://accounts?currency=ethereum&address={{eth_account_address}}` will open a given ethereum account if found, will falback to the currency page found and if not to the list of accounts

`?currency` param can be name or ticker of the currency targeted
`?address` param requires currency to work, address of the account to select

- **_discover_** 🠒 Live discover catalog

`ledgerlive://discover` will redirect to discover page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ const totalSteps = "3";
export default function AddAccountsNavigator({ route }: { route: Route }) {
const { colors } = useTheme();
const { t } = useTranslation();
const currency = route.params?.currency;
const token = route.params?.token;
const returnToSwap = route.params?.returnToSwap;
const stackNavConfig = useMemo(
() => getStackNavigatorConfig(colors),
[colors],
);
const analyticsPropertyFlow = route.params?.analyticsPropertyFlow;

const { currency, token, returnToSwap, analyticsPropertyFlow } =
route.params || {};

return (
<Stack.Navigator
initialRouteName={
Expand Down
25 changes: 24 additions & 1 deletion apps/ledger-live-mobile/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ const linkingOptions: LinkingOptions<ReactNavigation.RootParamList> = {
* @params ?currency: string
* ie: "ledgerlive://receive?currency=bitcoin" will open the prefilled search account in the receive flow
*/
[ScreenName.ReceiveSelectAccount]: "receive",
[ScreenName.ReceiveSelectCrypto]: "receive",
},
},
[NavigatorName.Swap]: {
Expand All @@ -389,6 +389,29 @@ const linkingOptions: LinkingOptions<ReactNavigation.RootParamList> = {
},
},

[NavigatorName.Accounts]: {
screens: {
/**
* @params ?id: string
* ie: "ledgerlive://accounts?currency=ethereum&address={{eth_account_address}}"
*/
[ScreenName.Accounts]: "accounts",
},
},

[NavigatorName.AddAccounts]: {
screens: {
/**
* ie: "ledgerlive://add-account" will open the add account flow
*
* @params ?currency: string
* ie: "ledgerlive://add-account?currency=bitcoin" will open the add account flow with "bitcoin" prefilled in the search input
*
*/
[ScreenName.AddAccountsSelectCrypto]: "add-account",
},
},

/**
* ie: "ledgerlive://buy" -> will redirect to the main exchange page
*/
Expand Down
31 changes: 23 additions & 8 deletions apps/ledger-live-mobile/src/navigation/useDeepLinking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { filterPlatformApps } from "@ledgerhq/live-common/platform/filters";
import { getPlatformVersion } from "@ledgerhq/live-common/lib/platform/version";
import { NavigatorName, ScreenName } from "../const";

function getSettingsScreen(pathname) {
function getSettingsScreen(pathname: string) {
const secondPath = pathname.replace(/(^\/+|\/+$)/g, "");
let screen;

Expand Down Expand Up @@ -64,7 +64,12 @@ export function useDeepLinkHandler() {

switch (hostname) {
case "accounts":
navigate(NavigatorName.Accounts);
if (currency) {
navigate(NavigatorName.Accounts, {
screen: ScreenName.Asset,
params: { currency },
});
} else navigate(NavigatorName.Accounts);
break;

case "buy": {
Expand Down Expand Up @@ -95,7 +100,7 @@ export function useDeepLinkHandler() {

case "receive":
navigate(NavigatorName.ReceiveFunds, {
screen: ScreenName.ReceiveSelectAccount,
screen: ScreenName.ReceiveSelectCrypto,
params: {
currency,
},
Expand Down Expand Up @@ -124,11 +129,11 @@ export function useDeepLinkHandler() {
screen: ScreenName.PlatformCatalog,
params: dapp
? {
platform: dapp.id,
name: dapp.name,
// $FlowFixMe Nope I want query to be spread last. Sry Flow.
...query,
}
platform: dapp.id,
name: dapp.name,
// $FlowFixMe Nope I want query to be spread last. Sry Flow.
...query,
}
: query,
});
break;
Expand All @@ -142,6 +147,16 @@ export function useDeepLinkHandler() {
break;
}

case "add-account": {
navigate(NavigatorName.AddAccounts, {
screen: ScreenName.AddAccountsSelectCrypto,
params: {
currency,
},
});
break;
}

case "portfolio":
default:
navigate(NavigatorName.Main, {
Expand Down
38 changes: 23 additions & 15 deletions apps/ledger-live-mobile/src/screens/Accounts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ const List = globalSyncRefreshControl(FlatList);

type Props = {
navigation: any;
route: {
params?: {
currency?: string;
search?: string;
currencyTicker?: string;
currencyId?: string;
};
};
route: { params?: Params };
};

type Params = {
currency?: string;
search?: string;
address?: string;
currencyTicker?: string;
currencyId?: string;
};

function Accounts({ navigation, route }: Props) {
const accounts = useSelector(accountsSelector);
const isUpToDate = useSelector(isUpToDateSelector);
const globalSyncState = useGlobalSyncState();

const { t } = useTranslation();

const refreshAccountsOrdering = useRefreshAccountsOrdering();
Expand All @@ -63,7 +63,7 @@ function Accounts({ navigation, route }: Props) {
? flattenAccounts(accounts, {
enforceHideEmptySubAccounts: true,
}).filter(
account =>
(account: Account | TokenAccount) =>
getAccountCurrency(account).id === route?.params?.currencyId,
)
: flattenAccounts(accounts, {
Expand All @@ -80,20 +80,28 @@ function Accounts({ navigation, route }: Props) {
params.currency.toUpperCase(),
);
if (currency) {
const account = accounts.find(acc => acc.currency.id === currency.id);
const account = params.address
? accounts.find(
acc =>
acc.currency.id === currency.id &&
acc.freshAddress === params.address,
)
: null;

if (account) {
// reset params so when we come back the redirection doesn't loop
navigation.setParams({ ...params, currency: undefined });
navigation.navigate(ScreenName.Account, {
navigation.replace(ScreenName.Account, {
accountId: account.id,
});
} else {
navigation.replace(ScreenName.Asset, {
currency,
isForwardedFromAccounts: true,
});
}
}
}
}
}, [params, accounts, navigation]);
}, [params, accounts, navigation, account]);

const renderItem = useCallback(
({ item, index }: { item: Account | TokenAccount; index: number }) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Props = {
route: {
params: {
filterCurrencyIds?: string[];
currency?: string;
};
};
};
Expand All @@ -45,8 +46,7 @@ const listSupportedTokens = () =>

export default function AddAccountsSelectCrypto({ navigation, route }: Props) {
const { colors } = useTheme();
const { filterCurrencyIds = [] } = route.params || {};

const { filterCurrencyIds = [], currency } = route.params || {};
const osmo = useFeature("currencyOsmosisMobile");
const fantom = useFeature("currencyFantomMobile");
const moonbeam = useFeature("currencyMoonbeamMobile");
Expand Down Expand Up @@ -134,6 +134,7 @@ export default function AddAccountsSelectCrypto({ navigation, route }: Props) {
list={sortedCryptoCurrencies}
renderList={renderList}
renderEmptySearch={renderEmptyList}
initialQuery={currency}
/>
</View>
</SafeAreaView>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from "react";
import React, { useCallback, useEffect, useMemo } from "react";
import { Trans, useTranslation } from "react-i18next";
import { StyleSheet, FlatList } from "react-native";
import type { Account, TokenAccount } from "@ledgerhq/types-live";
Expand All @@ -11,6 +11,7 @@ import {
listTokens,
useCurrenciesByMarketcap,
listSupportedCurrencies,
findCryptoCurrencyByKeyword,
} from "@ledgerhq/live-common/currencies/index";

import { Flex } from "@ledgerhq/native-ui";
Expand All @@ -27,7 +28,7 @@ const SEARCH_KEYS = ["name", "ticker"];
type Props = {
devMode: boolean;
navigation: any;
route: { params: { filterCurrencyIds?: string[] } };
route: { params: { filterCurrencyIds?: string[]; currency?: string } };
};

const keyExtractor = (currency: CryptoCurrency | TokenCurrency) => currency.id;
Expand All @@ -54,6 +55,8 @@ const findAccountByCurrency = (
);

export default function AddAccountsSelectCrypto({ navigation, route }: Props) {
const paramsCurrency = route?.params?.currency;

const { t } = useTranslation();
const filterCurrencyIds = useMemo(
() => route.params?.filterCurrencyIds || [],
Expand All @@ -72,6 +75,18 @@ export default function AddAccountsSelectCrypto({ navigation, route }: Props) {

const accounts = useSelector(flattenAccountsSelector);

useEffect(() => {
if (paramsCurrency) {
const selectedCurrency = findCryptoCurrencyByKeyword(
paramsCurrency.toUpperCase(),
);

if (selectedCurrency) {
onPressItem(selectedCurrency);
}
}
}, [onPressItem, paramsCurrency]);

const sortedCryptoCurrencies = useCurrenciesByMarketcap(cryptoCurrencies);

const onPressItem = useCallback(
Expand Down

0 comments on commit 198d934

Please sign in to comment.