Skip to content

Commit

Permalink
feat: add analytics to add account v2 flow
Browse files Browse the repository at this point in the history
  • Loading branch information
themooneer committed Jan 23, 2025
1 parent c018d19 commit b37bbf9
Show file tree
Hide file tree
Showing 30 changed files with 856 additions and 127 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-worms-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

Add analytics to all add account v2 workflow
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export type BaseNavigatorStackParamList = {
context?: "addAccounts" | "receiveFunds";
token?: string;
currency?: string;
sourceScreenName?: string;
} // in some cases we need to pass directly the context to the navigator and let it handle the logic
>;
[NavigatorName.Assets]?: Partial<NavigatorScreenParams<AssetsNavigatorParamsList>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Platform } from "react-native";
import { createStackNavigator } from "@react-navigation/stack";
import { useTheme } from "styled-components/native";
import { useNavigation, useRoute } from "@react-navigation/native";
import { ScreenName } from "~/const";
import { NavigatorName, ScreenName } from "~/const";
import { getStackNavigatorConfig } from "~/navigation/navigatorConfig";
import { track } from "~/analytics";
import type { NetworkBasedAddAccountNavigator } from "LLM/features/Accounts/screens/AddAccount/types";
Expand All @@ -17,25 +17,51 @@ 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";
import {
BaseComposite,
StackNavigatorNavigation,
StackNavigatorProps,
} from "~/components/RootNavigator/types/helpers";
import { NavigationHeaderCloseButtonAdvanced } from "~/components/NavigationHeaderCloseButton";

import useAnalytics from "LLM/hooks/useAnalytics";
import { AddAccountsNavigatorParamList } from "~/components/RootNavigator/types/AddAccountsNavigator";
type NavigationProps = BaseComposite<
StackNavigatorProps<AddAccountsNavigatorParamList, NavigatorName.AddAccounts>
>;
export default function Navigator() {
const { colors } = useTheme();
const route = useRoute();
const route = useRoute<NavigationProps["route"]>();
const accountListUIFF = useFeature("llmAccountListUI");
const navigation = useNavigation<StackNavigatorNavigation<BaseNavigatorStackParamList>>();
const navigation = useNavigation<StackNavigatorNavigation<AddAccountsNavigatorParamList>>();

const { analyticsMetadata } = useAnalytics("addAccounts");

const exitProcess = useCallback(() => {
const rootParent = navigation.getParent();
// this is the only way to go back to the root navigator
navigation.replace(rootParent?.getState().routeNames[0] as keyof AddAccountsNavigatorParamList);
}, [navigation]);

const onClose = useCallback(() => {
track("button_clicked", {
button: "Close",
screen: route.name,
});
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]);
exitProcess();
}, [route, exitProcess]);

const onExitScanDeviceAccounts = useCallback(() => {
const clickMetadata = analyticsMetadata[ScreenName.ScanDeviceAccounts]?.onClose;
track(clickMetadata?.eventName, clickMetadata?.payload);
exitProcess();
}, [exitProcess, analyticsMetadata]);

const onBackScanDeviceAccounts = useCallback(() => {
const clickMetadata = analyticsMetadata[ScreenName.ScanDeviceAccounts]?.onBack;
track(clickMetadata?.eventName, clickMetadata?.payload);
navigation.goBack();
}, [navigation, analyticsMetadata]);

const stackNavigationConfig = useMemo(
() => ({
Expand Down Expand Up @@ -67,6 +93,8 @@ export default function Navigator() {
options={{
headerTitle: "",
headerTransparent: true,
headerRight: () => <CloseWithConfirmation onClose={onExitScanDeviceAccounts} />,
headerLeft: () => <NavigationHeaderBackButton onPress={onBackScanDeviceAccounts} />,
}}
/>
{/* Select Accounts */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@ import { useTheme } from "styled-components/native";
import getAccountListKeyExtractor from "../../utils/getAccountListKeyExtractor";
import AccountListEmpty from "../AccountListEmpty";
import { useTranslation } from "react-i18next";
import { TrackScreen } from "~/analytics";
import useAnalytics from "LLM/hooks/useAnalytics";

type AccountListDrawerProps = {
isOpen: boolean;
onClose: () => void;
onBack: () => void;
data: (Account | TokenAccount)[];
onPressAccount: (account: Account | TokenAccount) => void;
};

const AccountListDrawer = ({
isOpen,
onClose,
onBack,
data,
onPressAccount,
}: AccountListDrawerProps) => {
const AccountListDrawer = ({ isOpen, onClose, data, onPressAccount }: AccountListDrawerProps) => {
const { colors } = useTheme();
const { t } = useTranslation();
const { analyticsMetadata } = useAnalytics("addAccounts", "tata");

const renderItem = useCallback(
({ item: account }: ListRenderItemInfo<Account | TokenAccount>) => {
Expand All @@ -43,33 +39,38 @@ const AccountListDrawer = ({

const keyExtractor = useCallback(getAccountListKeyExtractor, []);

const pageTrackingEvent = analyticsMetadata.AddFunds?.onAccessScreen;

return (
<QueuedDrawer
isRequestingToBeOpened={isOpen}
onClose={onClose}
onBack={onBack}
CustomHeader={() => (
<CustomHeader
onClose={onClose}
backgroundColor={colors.opacityDefault.c10}
iconColor={colors.neutral.c100}
title={t("addAccounts.chooseAccountToFund")}
/>
<>
{isOpen && (
<TrackScreen name={pageTrackingEvent?.eventName} {...pageTrackingEvent?.payload} />
)}
>
<Flex justifyContent="center" alignItems="centers" width="100%">
<FlatList
testID="added-accounts-list"
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ height: 16 }} />}
style={{ paddingHorizontal: 16 }}
ListEmptyComponent={<AccountListEmpty />}
/>
</Flex>
</QueuedDrawer>
<QueuedDrawer
isRequestingToBeOpened={isOpen}
CustomHeader={() => (
<CustomHeader
onClose={onClose}
backgroundColor={colors.opacityDefault.c10}
iconColor={colors.neutral.c100}
title={t("addAccounts.chooseAccountToFund")}
/>
)}
>
<Flex justifyContent="center" alignItems="centers" width="100%">
<FlatList
testID="added-accounts-list"
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ height: 16 }} />}
style={{ paddingHorizontal: 16 }}
ListEmptyComponent={<AccountListEmpty />}
/>
</Flex>
</QueuedDrawer>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ import TransferButton from "~/components/TransferButton";
import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
import CustomHeader from "./CustomHeader";
import { useTheme } from "styled-components/native";
import { TrackScreen } from "~/analytics";
import useAnalytics from "LLM/hooks/useAnalytics";

type AccountListDrawerProps = {
isOpen: boolean;
onClose: () => void;
onBack: () => void;
account: Account | TokenAccount | null;
currency: CryptoOrTokenCurrency;
};

const AccountQuickActionsDrawer = ({
isOpen,
onClose,
onBack,
account,
currency,
}: AccountListDrawerProps) => {
Expand All @@ -29,29 +29,34 @@ const AccountQuickActionsDrawer = ({
currency,
});
const { colors } = useTheme();
const { analyticsMetadata } = useAnalytics("addAccounts");
const pageTrackingEvent = analyticsMetadata.AddFunds?.onQuickActionOpen;

return (
<QueuedDrawer
isRequestingToBeOpened={isOpen}
onClose={onClose}
onBack={onBack}
CustomHeader={() => (
<CustomHeader
account={account}
onClose={onClose}
backgroundColor={colors.opacityDefault.c10}
iconColor={colors.neutral.c100}
/>
<>
{isOpen && (
<TrackScreen name={pageTrackingEvent?.eventName} {...pageTrackingEvent?.payload} />
)}
>
<Flex width="100%" rowGap={6}>
{actions.map((button, index) => (
<Box mb={index === actions.length - 1 ? 0 : 8} key={button?.title as string}>
<TransferButton {...button} testID={button?.testID as string} />
</Box>
))}
</Flex>
</QueuedDrawer>
<QueuedDrawer
isRequestingToBeOpened={isOpen}
CustomHeader={() => (
<CustomHeader
account={account}
onClose={onClose}
backgroundColor={colors.opacityDefault.c10}
iconColor={colors.neutral.c100}
/>
)}
>
<Flex width="100%" rowGap={6}>
{actions.map((button, index) => (
<Box mb={index === actions.length - 1 ? 0 : 8} key={button?.title as string}>
<TransferButton {...button} testID={button?.testID as string} />
</Box>
))}
</Flex>
</QueuedDrawer>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { StackNavigatorNavigation } from "~/components/RootNavigator/types/helpe
import { IconType } from "@ledgerhq/native-ui/components/Icon/type";
import { StyleProp, ViewStyle } from "react-native";
import { track } from "~/analytics";
import { AnalyticButtons, AnalyticEvents } from "~/newArch/hooks/useAnalytics/enums";

type ActionItem = {
title: string;
Expand Down Expand Up @@ -40,9 +41,8 @@ export default function useAccountQuickActionDrawerViewModel({
const actions: ActionItem[] = [
RECEIVE && {
eventProperties: {
button: "transfer_receive",
//page, TODO: add it in the analytics ticket
drawer: "trade",
button: AnalyticButtons.Receive,
page: AnalyticEvents.FundingQuickAction,
},
title: t("transfer.receive.title"),
description: t("transfer.receive.description"),
Expand All @@ -54,9 +54,8 @@ export default function useAccountQuickActionDrawerViewModel({
},
BUY && {
eventProperties: {
button: "transfer_buy",
//page, TODO: add it in the analytics ticket
drawer: "trade",
button: AnalyticButtons.Buy,
page: AnalyticEvents.FundingQuickAction,
},
title: t("transfer.buy.title"),
description: t("transfer.buy.description"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import { Account, AccountLike } from "@ledgerhq/types-live";
import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
import AccountListDrawer from "../AccountListDrawer";
import AccountQuickActionsDrawer from "../AccountQuickActionsDrawer";
import useAnalytics from "LLM/hooks/useAnalytics";
import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";

export default function AddFundsButton({
accounts,
currency,
sourceScreenName,
}: {
accounts: Account[];
currency: CryptoOrTokenCurrency;
sourceScreenName: string;
}) {
const { t } = useTranslation();
const [isAccountListDrawerOpen, setIsAccountListDrawerOpen] = useState<boolean>(false);
Expand All @@ -23,23 +27,49 @@ export default function AddFundsButton({
const [selectedAccount, setSelectedAccount] = useState<AccountLike | null>(
accounts.length === 1 ? accounts[0] : null,
);
const openFundOrAccountListDrawer = () => {
track("button_clicked", { button: "Add a new account" });
const { analyticsMetadata } = useAnalytics("addAccounts", sourceScreenName);

const openFundOrAccountListDrawer = useCallback(() => {
let clickMetadata;
if (accounts.length === 1) {
clickMetadata = analyticsMetadata.AddFunds?.onQuickActionOpen;
setIsAccountQuickActionsDrawerOpen(true);
} else setIsAccountListDrawerOpen(true);
};
} else {
clickMetadata = analyticsMetadata.AddFunds?.onOpenDrawer;
setIsAccountListDrawerOpen(true);
}
track(clickMetadata.eventName, clickMetadata.payload);
}, [
accounts.length,
analyticsMetadata.AddFunds?.onQuickActionOpen,
analyticsMetadata.AddFunds?.onOpenDrawer,
]);

const closeAccountListDrawer = () => setIsAccountListDrawerOpen(false);
const closeAccountListDrawer = useCallback(() => {
const clickMetadata = analyticsMetadata.AddFunds?.onCloseDrawer;
setIsAccountListDrawerOpen(false);
track(clickMetadata.eventName, clickMetadata.payload);
}, [analyticsMetadata.AddFunds?.onCloseDrawer]);

const handleOnSelectAccoount = useCallback((account: AccountLike) => {
closeAccountListDrawer();
setSelectedAccount(account);
setIsAccountQuickActionsDrawerOpen(true);
}, []);
const handleOnSelectAccoount = useCallback(
(account: AccountLike) => {
closeAccountListDrawer();
setSelectedAccount(account);
setIsAccountQuickActionsDrawerOpen(true);
const selectAccountMetadata = analyticsMetadata.AddFunds?.onSelectAccount;
track(selectAccountMetadata.eventName, {
...selectAccountMetadata.payload,
account: getDefaultAccountName(account),
currency: currency.id,
});
},
[closeAccountListDrawer, currency, analyticsMetadata.AddFunds?.onSelectAccount],
);

const handleOnCloseQuickActions = () => {
const clickMetadata = analyticsMetadata.AddFunds?.onQuickActionClose;
setIsAccountQuickActionsDrawerOpen(false);
track(clickMetadata.eventName, clickMetadata.payload);
};

return (
Expand All @@ -55,14 +85,12 @@ export default function AddFundsButton({
<AccountListDrawer
isOpen={isAccountListDrawerOpen}
onClose={closeAccountListDrawer}
onBack={closeAccountListDrawer}
data={accounts}
onPressAccount={handleOnSelectAccoount}
/>
<AccountQuickActionsDrawer
isOpen={isAccountQuickActionsDrawerOpen}
onClose={handleOnCloseQuickActions}
onBack={handleOnCloseQuickActions}
account={selectedAccount}
currency={currency}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export default function AccountsList({ route }: Props) {
params: {
currency: currency.id,
context: "addAccounts",
sourceScreenName: ScreenName.AccountsList,
},
});
} else {
Expand Down
Loading

0 comments on commit b37bbf9

Please sign in to comment.