From 700f8c621891f4eacd969e83eeaf8495d9f94a71 Mon Sep 17 00:00:00 2001 From: Martin Cayuelas Date: Thu, 5 Sep 2024 12:03:04 +0200 Subject: [PATCH] [FIX]: Analytics LedgerSync --- .changeset/witty-feet-dream.md | 5 ++ .../SelectAddAccountMethod/index.tsx | 6 +- .../useSelectAddAccountMethodViewModel.ts | 13 +++- .../WalletSync/WalletSyncNavigator.tsx | 24 ++++++- .../components/Activation/Actions.tsx | 5 +- .../hooks/useLedgerSyncAnalytics.ts | 11 ++-- .../WalletSync/hooks/useSpecificError.tsx | 65 +++++++++++-------- .../screens/Activation/ActivationDrawer.tsx | 2 +- .../WalletSync/screens/Manage/index.tsx | 7 +- .../screens/Synchronize/QrCodeMethod.tsx | 2 +- .../Onboarding/steps/accessExistingWallet.tsx | 7 +- 11 files changed, 100 insertions(+), 47 deletions(-) create mode 100644 .changeset/witty-feet-dream.md diff --git a/.changeset/witty-feet-dream.md b/.changeset/witty-feet-dream.md new file mode 100644 index 000000000000..b1c2e927fc7d --- /dev/null +++ b/.changeset/witty-feet-dream.md @@ -0,0 +1,5 @@ +--- +"live-mobile": patch +--- + +Fix Analytics LedgerSync diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/index.tsx b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/index.tsx index e231ff3f53c4..04e96eaee1f9 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/index.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/index.tsx @@ -11,7 +11,7 @@ type ViewProps = { doesNotHaveAccount?: boolean; onClickAdd: () => void; onClickImport: () => void; - setWalletSyncDrawerVisible?: () => void; + onClickImportLedgerSync?: () => void; }; type AddAccountScreenProps = { @@ -26,7 +26,7 @@ function View({ isReadOnlyModeEnabled, onClickAdd, onClickImport, - setWalletSyncDrawerVisible, + onClickImportLedgerSync, doesNotHaveAccount, }: ViewProps) { const { t } = useTranslation(); @@ -45,7 +45,7 @@ function View({ rows.push({ titleKey: "addAccountsModal.drawer.walletSync.title", descriptionKey: "addAccountsModal.drawer.walletSync.description", - onPress: setWalletSyncDrawerVisible, + onPress: onClickImportLedgerSync, icon: , testID: "add-accounts-modal-wallet-sync-button", }); diff --git a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/useSelectAddAccountMethodViewModel.ts b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/useSelectAddAccountMethodViewModel.ts index b2f865ae99a3..8c7c5c7b05c8 100644 --- a/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/useSelectAddAccountMethodViewModel.ts +++ b/apps/ledger-live-mobile/src/newArch/features/Accounts/screens/AddAccount/components/SelectAddAccountMethod/useSelectAddAccountMethodViewModel.ts @@ -11,9 +11,14 @@ import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets"; type AddAccountScreenProps = { currency?: CryptoCurrency | TokenCurrency | null; onClose?: () => void; + setWalletSyncDrawerVisible?: () => void; }; -const useSelectAddAccountMethodViewModel = ({ currency, onClose }: AddAccountScreenProps) => { +const useSelectAddAccountMethodViewModel = ({ + currency, + onClose, + setWalletSyncDrawerVisible, +}: AddAccountScreenProps) => { const navigation = useNavigation(); const walletSyncFeatureFlag = useFeature("llmWalletSync"); @@ -42,6 +47,11 @@ const useSelectAddAccountMethodViewModel = ({ currency, onClose }: AddAccountScr navigation.navigate(NavigatorName.ImportAccounts); }, [navigation, trackButtonClick, onClose]); + const onClickImportLedgerSync = useCallback(() => { + trackButtonClick("Import via another Ledger Live app"); + setWalletSyncDrawerVisible?.(); + }, [trackButtonClick, setWalletSyncDrawerVisible]); + const onClickAdd = useCallback(() => { trackButtonClick("With your Ledger"); onClose?.(); @@ -53,6 +63,7 @@ const useSelectAddAccountMethodViewModel = ({ currency, onClose }: AddAccountScr isReadOnlyModeEnabled, onClickAdd, onClickImport, + onClickImportLedgerSync, }; }; diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/WalletSyncNavigator.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/WalletSyncNavigator.tsx index a16759c17175..a77c7033b978 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/WalletSyncNavigator.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/WalletSyncNavigator.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from "react"; +import React, { useCallback, useMemo } from "react"; import { createStackNavigator } from "@react-navigation/stack"; import { useTheme } from "styled-components/native"; import { ScreenName } from "~/const"; @@ -16,6 +16,10 @@ import { ManageInstancesProcess } from "./screens/ManageInstances/ManageInstance import { WalletSyncManageInstanceDeletionSuccess } from "./screens/ManageInstances/DeletionSuccess"; import { LedgerSyncDeepLinkHandler } from "./screens/LedgerSyncDeepLinkHandler"; import { NavigationHeaderCloseButton } from "~/components/NavigationHeaderCloseButton"; +import { track } from "~/analytics"; +import { AnalyticsPage } from "./hooks/useLedgerSyncAnalytics"; +import { NavigationHeaderBackButton } from "~/components/NavigationHeaderBackButton"; +import { NavigationProp } from "@react-navigation/native"; const Stack = createStackNavigator(); @@ -25,6 +29,17 @@ export default function WalletSyncNavigator() { const { t } = useTranslation(); useInitMemberCredentials(); + const onHeaderBackButtonPress = useCallback( + (navigation: NavigationProp) => { + track("button_clicked", { + button: "Back", + page: AnalyticsPage.LedgerSyncSettings, + }); + navigation.goBack(); + }, + [], + ); + return ( ({ title: t("walletSync.title"), headerRight: () => null, - }} + headerLeft: () => ( + onHeaderBackButtonPress(navigation)} /> + ), + })} /> { - track("button_clicked", { button, page, flow }); + const onClickTrack = ({ button, page, hasFlow = false }: OnClickTrack) => { + track("button_clicked", { button, page, flow: hasFlow ? AnalyticsFlow.LedgerSync : undefined }); }; return { onClickTrack }; diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useSpecificError.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useSpecificError.tsx index 9834e3db193b..6fc563ebea6f 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useSpecificError.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/hooks/useSpecificError.tsx @@ -37,37 +37,42 @@ export type SpecificProps = { secondaryAction?: () => void; }; +type AnalyticsProps = { + page: AnalyticsPage; + hasFlow: boolean; + button?: AnalyticsButton; +}; export function useSpecificError({ primaryAction, secondaryAction }: SpecificProps) { const { onClickTrack } = useLedgerSyncAnalytics(); const { t } = useTranslation(); const { colors } = useTheme(); - const onTryAgain = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.UseAnother, page }); + const onTryAgain = (props: AnalyticsProps) => { + onClickTrack({ button: props.button ?? AnalyticsButton.UseAnother, ...props }); }; - const onTryAnotherLedger = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.TryAnotherLedger, page }); + const onTryAnotherLedger = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.TryAnotherLedger, ...props }); }; - const onGoToDelete = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.DeleteKey, page }); + const onGoToDelete = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.DeleteKey, ...props }); }; - const onUnderstood = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.Understand, page }); + const onUnderstood = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.Understand, ...props }); }; - const onCancel = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.Cancel, page }); + const onCancel = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.Cancel, ...props }); }; - const onCreate = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.CreateYourKey, page }); + const onCreate = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.CreateYourKey, ...props }); }; - const ContinueWihtoutSync = (page: AnalyticsPage) => { - onClickTrack({ button: AnalyticsButton.ContinueWihtoutSync, page }); + const ContinueWihtoutSync = (props: AnalyticsProps) => { + onClickTrack({ button: AnalyticsButton.ContinueWihtoutSync, ...props }); }; const errorConfig: Record = { @@ -86,11 +91,11 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onTryAgain(AnalyticsPage.RemoveInstanceWrongDevice); + onTryAgain({ page: AnalyticsPage.RemoveInstanceWrongDevice, hasFlow: false }); }, secondaryAction: () => { secondaryAction?.(); - onGoToDelete(AnalyticsPage.RemoveInstanceWrongDevice); + onGoToDelete({ page: AnalyticsPage.RemoveInstanceWrongDevice, hasFlow: false }); }, }, [ErrorReason.AUTO_REMOVE]: { @@ -108,11 +113,11 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onUnderstood(AnalyticsPage.AutoRemove); + onUnderstood({ page: AnalyticsPage.AutoRemove, hasFlow: false }); }, secondaryAction: () => { secondaryAction?.(); - onGoToDelete(AnalyticsPage.AutoRemove); + onGoToDelete({ page: AnalyticsPage.AutoRemove, hasFlow: false }); }, }, [ErrorReason.SAME_SEED]: { @@ -125,7 +130,7 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onUnderstood(AnalyticsPage.SameSeed); + onUnderstood({ page: AnalyticsPage.SameSeed, hasFlow: false }); }, }, [ErrorReason.OTHER_SEED]: { @@ -139,11 +144,11 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro outline: true, primaryAction: () => { primaryAction(); - onGoToDelete(AnalyticsPage.OtherSeed); + onGoToDelete({ page: AnalyticsPage.OtherSeed, hasFlow: false }); }, secondaryAction: () => { secondaryAction?.(); - onCancel(AnalyticsPage.OtherSeed); + onCancel({ page: AnalyticsPage.OtherSeed, hasFlow: false }); }, }, [ErrorReason.ALREADY_BACKED_SCAN]: { @@ -154,7 +159,7 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onUnderstood(AnalyticsPage.ScanAttemptWithSameBackup); + onUnderstood({ page: AnalyticsPage.ScanAttemptWithSameBackup, hasFlow: false }); }, }, [ErrorReason.DIFFERENT_BACKUPS]: { @@ -166,7 +171,7 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onGoToDelete(AnalyticsPage.ScanAttemptWithDifferentBackups); + onUnderstood({ page: AnalyticsPage.ScanAttemptWithDifferentBackups, hasFlow: false }); }, }, [ErrorReason.NO_BACKUP]: { @@ -178,7 +183,7 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onCreate(AnalyticsPage.SyncWithNoKey); + onCreate({ page: AnalyticsPage.SyncWithNoKey, hasFlow: false }); }, }, [ErrorReason.NO_BACKUP_ONBOARDING_QRCODE]: { @@ -191,11 +196,15 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onTryAgain(AnalyticsPage.OnBoardingQRCodeNoBackup); + onTryAgain({ + page: AnalyticsPage.OnBoardingQRCodeNoBackup, + hasFlow: false, + button: AnalyticsButton.TryAgain, + }); }, secondaryAction: () => { secondaryAction?.(); - ContinueWihtoutSync(AnalyticsPage.OnBoardingQRCodeNoBackup); + ContinueWihtoutSync({ page: AnalyticsPage.OnBoardingQRCodeNoBackup, hasFlow: false }); }, }, [ErrorReason.NO_BACKUP_ONBOARDING_DEVICE]: { @@ -207,11 +216,11 @@ export function useSpecificError({ primaryAction, secondaryAction }: SpecificPro buttonType: "main" as ButtonProps["type"], primaryAction: () => { primaryAction(); - onTryAnotherLedger(AnalyticsPage.OnBoardingDeviceNoBackup); + onTryAnotherLedger({ page: AnalyticsPage.OnBoardingDeviceNoBackup, hasFlow: false }); }, secondaryAction: () => { secondaryAction?.(); - ContinueWihtoutSync(AnalyticsPage.OnBoardingDeviceNoBackup); + ContinueWihtoutSync({ page: AnalyticsPage.OnBoardingDeviceNoBackup, hasFlow: false }); }, }, }; diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationDrawer.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationDrawer.tsx index 4eb884cfe76f..a25e175433f3 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationDrawer.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Activation/ActivationDrawer.tsx @@ -37,7 +37,7 @@ function View({ { const goToManageBackup = () => { manageKeyHook.openDrawer(); - onClickTrack({ button: AnalyticsButton.ManageKey, page: AnalyticsPage.LedgerSyncSettings }); + onClickTrack({ + button: AnalyticsButton.ManageKey, + page: AnalyticsPage.LedgerSyncSettings, + hasFlow: false, + }); }; const goToManageInstances = () => { @@ -54,6 +58,7 @@ const WalletSyncManage = () => { onClickTrack({ button: AnalyticsButton.ManageInstances, page: AnalyticsPage.LedgerSyncSettings, + hasFlow: false, }); }; diff --git a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Synchronize/QrCodeMethod.tsx b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Synchronize/QrCodeMethod.tsx index 0681e0498738..9af94affd711 100644 --- a/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Synchronize/QrCodeMethod.tsx +++ b/apps/ledger-live-mobile/src/newArch/features/WalletSync/screens/Synchronize/QrCodeMethod.tsx @@ -31,7 +31,7 @@ const QrCodeMethod = ({ setSelectedOption(option); const button = option === Options.SCAN ? AnalyticsButton.ScanQRCode : AnalyticsButton.ShowQRCode; - const page = option === Options.SCAN ? AnalyticsPage.ScanQRCode : AnalyticsPage.ShowQRCode; + const page = option === Options.SCAN ? AnalyticsPage.ShowQRCode : AnalyticsPage.ScanQRCode; onClickTrack({ button, page, diff --git a/apps/ledger-live-mobile/src/screens/Onboarding/steps/accessExistingWallet.tsx b/apps/ledger-live-mobile/src/screens/Onboarding/steps/accessExistingWallet.tsx index 1c281f235ef8..2a26de5abdfb 100644 --- a/apps/ledger-live-mobile/src/screens/Onboarding/steps/accessExistingWallet.tsx +++ b/apps/ledger-live-mobile/src/screens/Onboarding/steps/accessExistingWallet.tsx @@ -16,6 +16,10 @@ import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; import { logDrawer } from "LLM/components/QueuedDrawer/utils/logDrawer"; import ActivationDrawer from "LLM/features/WalletSync/screens/Activation/ActivationDrawer"; import { Steps } from "LLM/features/WalletSync/types/Activation"; +import { + AnalyticsButton, + AnalyticsPage, +} from "LLM/features/WalletSync/hooks/useLedgerSyncAnalytics"; type NavigationProps = StackNavigatorProps< OnboardingNavigatorParamList & BaseNavigatorStackParamList, @@ -87,7 +91,8 @@ function AccessExistingWallet() { title: t("onboarding.welcomeBackStep.walletSync"), event: "button_clicked", eventProperties: { - button: "Sync with WalletSync", + button: AnalyticsButton.SyncWithAnotherLedgerLive, + page: AnalyticsPage.OnboardingAccessExistingWallet, }, testID: "Existing Wallet | Wallet Sync", onPress: openDrawer,