diff --git a/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx b/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx index 18a99ef18c7..15a6299f598 100644 --- a/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx +++ b/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx @@ -1,10 +1,13 @@ -import React, { useMemo } from "react"; +import React, { useMemo, useCallback } from "react"; import { createStackNavigator, TransitionPresets, } from "@react-navigation/stack"; import { useTranslation } from "react-i18next"; import { useTheme } from "styled-components/native"; +import { TouchableOpacity } from "react-native"; +import { Box, Icons } from "@ledgerhq/native-ui"; +import { useNavigation } from "@react-navigation/native"; import { ScreenName } from "../../const"; import BenchmarkQRStream from "../../screens/BenchmarkQRStream"; import DebugSwap from "../../screens/DebugSwap"; @@ -46,6 +49,8 @@ import OnboardingStepLanguage from "../../screens/Onboarding/steps/language"; import { GenerateMockAccountSelectScreen } from "../../screens/Settings/Debug/GenerateMockAccountsSelect"; import HiddenNftCollections from "../../screens/Settings/Accounts/HiddenNftCollections"; import DebugStoryly from "../../screens/DebugStoryly"; +import { track } from "../../analytics"; +import { useCurrentRouteName } from "../../helpers/routeHooks"; export default function SettingsNavigator() { const { t } = useTranslation(); @@ -53,6 +58,18 @@ export default function SettingsNavigator() { const stackNavConfig = useMemo(() => getStackNavigatorConfig(colors), [ colors, ]); + + const navigation = useNavigation(); + const currentRoute = useCurrentRouteName(); + + const goBackFromNotifications = useCallback(() => { + track("button_clicked", { + button: "Back Arrow", + screen: currentRoute, + }); + navigation.goBack(); + }, [navigation, currentRoute]); + return ( ( + + + + + + ), title: t("settings.notifications.title"), }} /> diff --git a/apps/ledger-live-mobile/src/logic/notifications.tsx b/apps/ledger-live-mobile/src/logic/notifications.tsx index 228ac6b00e7..57e28097002 100644 --- a/apps/ledger-live-mobile/src/logic/notifications.tsx +++ b/apps/ledger-live-mobile/src/logic/notifications.tsx @@ -27,6 +27,7 @@ import { import { notificationsSelector } from "../reducers/settings"; import { ScreenName, NavigatorName } from "../const"; import { setRatingsModalLocked } from "../actions/ratings"; +import { track } from "../analytics"; export type EventTrigger = { /** Name of the route that will trigger the push notification modal */ @@ -136,6 +137,10 @@ const useNotifications = () => { }, [notificationsToken]); const handlePushNotificationsPermission = useCallback(async () => { + track("button_clicked", { + button: "Go to system settings", + screen: pushNotificationsOldRoute, + }); if (Platform.OS === "android") { Linking.openSettings(); } else { @@ -148,7 +153,7 @@ const useNotifications = () => { fcm.requestPermission(); } } - }, []); + }, [pushNotificationsOldRoute]); const setPushNotificationsModalOpenCallback = useCallback( isModalOpen => { @@ -362,16 +367,34 @@ const useNotifications = () => { }, [pushNotificationsDataOfUser, updatePushNotificationsDataOfUserInStateAndStore]); const modalAllowNotifications = useCallback(() => { + track("button_clicked", { + button: "Allow", + screen: pushNotificationsOldRoute, + drawer: "Notif", + }); setPushNotificationsModalOpenCallback(false); navigation.navigate(NavigatorName.Settings, { screen: ScreenName.NotificationsSettings }); if (pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts) { - handleSetDateOfNextAllowedRequest(pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts); + handleSetDateOfNextAllowedRequest( + pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts, + ); } - }, [handleSetDateOfNextAllowedRequest, navigation, pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts, setPushNotificationsModalOpenCallback]); + }, [ + pushNotificationsOldRoute, + handleSetDateOfNextAllowedRequest, + navigation, + pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts, + setPushNotificationsModalOpenCallback, + ]); const modalDelayLater = useCallback(() => { + track("button_clicked", { + button: "Maybe Later", + screen: pushNotificationsOldRoute, + drawer: "Notif", + }); setPushNotificationsModalOpenCallback(false); if (pushNotificationsDataOfUser?.alreadyDelayedToLater) { updatePushNotificationsDataOfUserInStateAndStore({ @@ -386,12 +409,21 @@ const useNotifications = () => { }, ); } - }, [handleSetDateOfNextAllowedRequest, pushNotificationsDataOfUser, pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts, pushNotificationsFeature?.params?.conditions?.maybe_later_delay, setPushNotificationsModalOpenCallback, updatePushNotificationsDataOfUserInStateAndStore]); + }, [ + pushNotificationsOldRoute, + handleSetDateOfNextAllowedRequest, + pushNotificationsDataOfUser, + pushNotificationsFeature?.params?.conditions?.default_delay_between_two_prompts, + pushNotificationsFeature?.params?.conditions?.maybe_later_delay, + setPushNotificationsModalOpenCallback, + updatePushNotificationsDataOfUserInStateAndStore, + ]); return { initPushNotifications, initPushNotificationsData, cleanPushNotifications, + pushNotificationsOldRoute, pushNotificationsModalType, isPushNotificationsModalOpen, getIsNotifEnabled, diff --git a/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx b/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx index 935d7c2c146..d6e7a14e58f 100644 --- a/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx +++ b/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx @@ -17,10 +17,13 @@ const ReadOnlyAccountRow = ({ navigation, currency, screen }: Props) => { const onAccountPress = useCallback(() => { track("account_clicked", { currency: name, screen }); navigation.navigate(NavigatorName.Portfolio, { - screen: ScreenName.Account, + screen: NavigatorName.PortfolioAccounts, params: { - currencyId: id, - currencyType: type, + screen: ScreenName.Account, + params: { + currencyId: id, + currencyType: type, + }, }, }); }, [name, screen, navigation, id, type]); diff --git a/apps/ledger-live-mobile/src/screens/NotificationCenter/News.tsx b/apps/ledger-live-mobile/src/screens/NotificationCenter/News.tsx index d40de8e5358..66c70ec6bca 100644 --- a/apps/ledger-live-mobile/src/screens/NotificationCenter/News.tsx +++ b/apps/ledger-live-mobile/src/screens/NotificationCenter/News.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { StyleSheet, SectionList, RefreshControl, View } from "react-native"; import { useAnnouncements } from "@ledgerhq/live-common/notifications/AnnouncementProvider/index"; import { groupAnnouncements } from "@ledgerhq/live-common/notifications/AnnouncementProvider/helpers"; diff --git a/apps/ledger-live-mobile/src/screens/PushNotificationsModal/index.tsx b/apps/ledger-live-mobile/src/screens/PushNotificationsModal/index.tsx index c096ac56f20..995df1ef43f 100644 --- a/apps/ledger-live-mobile/src/screens/PushNotificationsModal/index.tsx +++ b/apps/ledger-live-mobile/src/screens/PushNotificationsModal/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useEffect } from "react"; import { useSelector } from "react-redux"; import { useTranslation } from "react-i18next"; import { @@ -15,6 +15,7 @@ import PromptNotifGenericLight from "../../images/illustration/Light/_PromptNoti import PromptNotifMarketDark from "../../images/illustration/Dark/_PromptNotifMarket.png"; import PromptNotifMarketLight from "../../images/illustration/Light/_PromptNotifMarket.png"; import { notificationsSelector } from "../../reducers/settings"; +import { TrackScreen } from "../../analytics"; const PushNotificationsModal = () => { const { t } = useTranslation(); @@ -29,6 +30,7 @@ const PushNotificationsModal = () => { getIsNotifEnabled, listenForNotifications, clearNotificationsListeners, + pushNotificationsOldRoute, } = useNotifications(); const notificationsSettings = useSelector(notificationsSelector); @@ -78,6 +80,16 @@ const PushNotificationsModal = () => { isOpen={isPushNotificationsModalOpen} noCloseButton > + diff --git a/apps/ledger-live-mobile/src/screens/Settings/Notifications/index.tsx b/apps/ledger-live-mobile/src/screens/Settings/Notifications/index.tsx index 5b321124690..976503d75e0 100644 --- a/apps/ledger-live-mobile/src/screens/Settings/Notifications/index.tsx +++ b/apps/ledger-live-mobile/src/screens/Settings/Notifications/index.tsx @@ -3,17 +3,26 @@ import { Platform } from "react-native"; import { useDispatch, useSelector } from "react-redux"; import { useTranslation } from "react-i18next"; import { capitalize } from "lodash/fp"; -import { Box, Switch, Text, Button, Icons, InfiniteLoader } from "@ledgerhq/native-ui"; - +import { + Box, + Switch, + Text, + Button, + Icons, + InfiniteLoader, +} from "@ledgerhq/native-ui"; import SettingsNavigationScrollView from "../SettingsNavigationScrollView"; import SettingsRow from "../../../components/SettingsRow"; import Track from "../../../analytics/Track"; -import { TrackScreen } from "../../../analytics"; - +import { track, TrackScreen } from "../../../analytics"; import { notificationsSelector } from "../../../reducers/settings"; import { setNotifications } from "../../../actions/settings"; import { State } from "../../../reducers"; import useNotifications from "../../../logic/notifications"; +import { + usePreviousRouteName, + useCurrentRouteName, +} from "../../../helpers/routeHooks"; type NotificationRowProps = { disabled?: boolean; @@ -31,6 +40,10 @@ function NotificationSettingsRow({ const { t } = useTranslation(); + const capitalizedKey = capitalize(notificationKey); + + const screen = useCurrentRouteName(); + const onChange = useCallback( (value: boolean) => { dispatch( @@ -38,12 +51,17 @@ function NotificationSettingsRow({ [notificationKey]: value, }), ); + track("toggle_clicked", { + toggle: `Toggle_${ + capitalizedKey === "Allowed" ? "Allow" : capitalizedKey + }`, + enabled: value, + screen, + }); }, - [dispatch, notificationKey], + [capitalizedKey, dispatch, notificationKey, screen], ); - const capitalizedKey = capitalize(notificationKey); - return ( { @@ -85,27 +106,36 @@ function NotificationsSettings() { return () => { clearInterval(interval); - } + }; }, [refreshNotifPermission]); - + const disableSubSettings = !notifications.allowed; - const platformData = useMemo(() => { - return Platform.OS === "ios" ? { - osName: "iOS", - ctaTransKey: "turnOnNotif", - ctaIcon: Icons.NotificationsMedium, - } : { - osName: "Android", - ctaTransKey: "goToSettings", - ctaIcon: Icons.SettingsMedium, - }; - }, []); + const platformData = useMemo( + () => + Platform.OS === "ios" + ? { + osName: "iOS", + ctaTransKey: "turnOnNotif", + ctaIcon: Icons.NotificationsMedium, + } + : { + osName: "Android", + ctaTransKey: "goToSettings", + ctaIcon: Icons.SettingsMedium, + }, + [], + ); return ( - - {isNotifPermissionEnabled === null || isNotifPermissionEnabled === undefined ? ( + + {isNotifPermissionEnabled === null || + isNotifPermissionEnabled === undefined ? ( ) : ( @@ -120,7 +150,9 @@ function NotificationsSettings() { {t(`settings.notifications.disabledNotifications.title`)} - {t(`settings.notifications.disabledNotifications.desc`, { platform: platformData.osName })} + {t(`settings.notifications.disabledNotifications.desc`, { + platform: platformData.osName, + })} ) : null} - + { @@ -48,6 +50,14 @@ export default function Settings({ navigation }: Props) { } }, [debugVisible]); + const onNotifClick = useCallback(() => { + navigation.navigate(ScreenName.NotificationsSettings); + track("button_clicked", { + button: "Notifications", + screen: route.name, + }); + }, [navigation, route.name]); + return (