Skip to content

Commit

Permalink
feat(llm/post onboarding): auto redirection to Recover upsell & post …
Browse files Browse the repository at this point in the history
…onboarding
  • Loading branch information
ofreyssinet-ledger committed Oct 30, 2024
1 parent ac8696f commit 46fea4c
Show file tree
Hide file tree
Showing 22 changed files with 557 additions and 128 deletions.
5 changes: 4 additions & 1 deletion .changeset/green-rice-cheer.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
"live-mobile": patch
---

Hide Backup section during onboarding on Flex and Stax
Stax/Flex onboarding:
- Hide "Backup with Recover" section
- Auto redirect to Recover upsell between the onboarding and the post onboarding

6 changes: 6 additions & 0 deletions apps/ledger-live-mobile/src/actions/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import {
SettingsAddStarredMarketcoinsPayload,
SettingsRemoveStarredMarketcoinsPayload,
SettingsSetFromLedgerSyncOnboardingPayload,
SettingsSetHasBeenRedirectedToPostOnboardingPayload,
} from "./types";
import { ImageType } from "~/components/CustomImage/types";

Expand Down Expand Up @@ -264,6 +265,11 @@ export const setHasBeenUpsoldProtect = createAction<SettingsSetHasBeenUpsoldProt
SettingsActionTypes.SET_HAS_BEEN_UPSOLD_PROTECT,
);

export const setHasBeenRedirectedToPostOnboarding =
createAction<SettingsSetHasBeenRedirectedToPostOnboardingPayload>(
SettingsActionTypes.SET_HAS_BEEN_REDIRECTED_TO_POST_ONBOARDING,
);

export const setGeneralTermsVersionAccepted = createAction<SettingsSetGeneralTermsVersionAccepted>(
SettingsActionTypes.SET_GENERAL_TERMS_VERSION_ACCEPTED,
);
Expand Down
3 changes: 3 additions & 0 deletions apps/ledger-live-mobile/src/actions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export enum SettingsActionTypes {
SET_FEATURE_FLAGS_BANNER_VISIBLE = "SET_FEATURE_FLAGS_BANNER_VISIBLE",
SET_DEBUG_APP_LEVEL_DRAWER_OPENED = "SET_DEBUG_APP_LEVEL_DRAWER_OPENED",
SET_HAS_BEEN_UPSOLD_PROTECT = "SET_HAS_BEEN_UPSOLD_PROTECT",
SET_HAS_BEEN_REDIRECTED_TO_POST_ONBOARDING = "SET_HAS_BEEN_REDIRECTED_TO_POST_ONBOARDING",
SET_GENERAL_TERMS_VERSION_ACCEPTED = "SET_GENERAL_TERMS_VERSION_ACCEPTED",
SET_ONBOARDING_TYPE = "SET_ONBOARDING_TYPE",
SET_CLOSED_NETWORK_BANNER = "SET_CLOSED_NETWORK_BANNER",
Expand Down Expand Up @@ -379,6 +380,8 @@ export type SettingsSetDebugAppLevelDrawerOpenedPayload =
SettingsState["debugAppLevelDrawerOpened"];

export type SettingsSetHasBeenUpsoldProtectPayload = SettingsState["hasBeenUpsoldProtect"];
export type SettingsSetHasBeenRedirectedToPostOnboardingPayload =
SettingsState["hasBeenRedirectedToPostOnboarding"];

export type SettingsCompleteOnboardingPayload = void | SettingsState["hasCompletedOnboarding"];
export type SettingsSetGeneralTermsVersionAccepted = SettingsState["generalTermsVersionAccepted"];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useEffect } from "react";
import { useSelector } from "react-redux";
import { lastConnectedDeviceSelector } from "~/reducers/settings";
import { useOpenPostOnboardingCallback } from "./useOpenPostOnboardingCallback";
import { useShouldRedirect } from "./useShouldRedirect";
import { useOpenProtectUpsellCallback } from "./useOpenProtectUpsellCallback";
import { useIsFocused } from "@react-navigation/core";

/**
* Redirects the user to the post onboarding or the protect (Ledger Recover) upsell if needed
* */
export function useAutoRedirectToPostOnboarding() {
const focused = useIsFocused();
const lastConnectedDevice = useSelector(lastConnectedDeviceSelector);

const { shouldRedirectToProtectUpsell, shouldRedirectToPostOnboarding } = useShouldRedirect();

const openProtectUpsell = useOpenProtectUpsellCallback();
const openPostOnboarding = useOpenPostOnboardingCallback();

const isFocused = useIsFocused();

useEffect(() => {
if (!isFocused) return;
if (shouldRedirectToProtectUpsell) {
openProtectUpsell();
} else if (shouldRedirectToPostOnboarding && lastConnectedDevice) {
openPostOnboarding(lastConnectedDevice.modelId);
}
}, [
lastConnectedDevice,
openPostOnboarding,
openProtectUpsell,
shouldRedirectToPostOnboarding,
shouldRedirectToProtectUpsell,
focused,
isFocused,
]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useStartPostOnboardingCallback } from "@ledgerhq/live-common/postOnboarding/hooks/useStartPostOnboardingCallback";
import { DeviceModelId } from "@ledgerhq/types-devices";
import { useCallback } from "react";

/**
* Returns a callback to open the post onboarding screen
* */
export function useOpenPostOnboardingCallback() {
const startPostOnboarding = useStartPostOnboardingCallback();
return useCallback(
(deviceModelId: DeviceModelId) => {
startPostOnboarding({
deviceModelId: deviceModelId,
resetNavigationStack: false,
});
},
[startPostOnboarding],
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import {
Source,
useAlreadyOnboardedURI,
useHomeURI,
usePostOnboardingURI,
useTouchScreenOnboardingUpsellURI,
} from "@ledgerhq/live-common/hooks/recoverFeatureFlag";
import { DeviceModelId } from "@ledgerhq/types-devices";
import { useIsFocused } from "@react-navigation/core";
import { useCallback, useEffect, useState } from "react";
import { Linking } from "react-native";
import { useDispatch, useSelector } from "react-redux";
import { setHasBeenUpsoldProtect } from "~/actions/settings";
import { internetReachable } from "~/logic/internetReachable";
import { lastConnectedDeviceSelector, onboardingTypeSelector } from "~/reducers/settings";
import { OnboardingType } from "~/reducers/types";

/**
* Returns a callback to open the Protect (Ledger Recover) upsell
* */
export function useOpenProtectUpsellCallback() {
const lastConnectedDevice = useSelector(lastConnectedDeviceSelector);
const onboardingType = useSelector(onboardingTypeSelector);
const protectFeature = useFeature("protectServicesMobile");
const recoverAlreadyOnboardedURI = useAlreadyOnboardedURI(protectFeature);
const recoverPostOnboardingURI = usePostOnboardingURI(protectFeature);
const touchScreenURI = useTouchScreenOnboardingUpsellURI(
protectFeature,
Source.LLM_ONBOARDING_24,
);
const recoverHomeURI = useHomeURI(protectFeature);
const dispatch = useDispatch();
const [redirectionStarted, setRedirectionStarted] = useState(false);
const isFocused = useIsFocused();

useEffect(() => {
if (redirectionStarted && !isFocused) {
dispatch(setHasBeenUpsoldProtect(true));
}
}, [redirectionStarted, isFocused, dispatch]);

const redirect = useCallback((url: string) => {
Linking.openURL(url);
setRedirectionStarted(true);
}, []);

return useCallback(async () => {
const internetConnected = await internetReachable();
if (internetConnected && protectFeature?.enabled) {
if (
lastConnectedDevice &&
touchScreenURI &&
[DeviceModelId.stax, DeviceModelId.europa].includes(lastConnectedDevice.modelId)
) {
redirect(touchScreenURI);
} else if (recoverPostOnboardingURI && onboardingType === OnboardingType.restore) {
redirect(recoverPostOnboardingURI);
} else if (recoverHomeURI && onboardingType === OnboardingType.setupNew) {
redirect(recoverHomeURI);
} else if (recoverAlreadyOnboardedURI) {
redirect(recoverAlreadyOnboardedURI);
}
}
}, [
lastConnectedDevice,
onboardingType,
protectFeature?.enabled,
recoverAlreadyOnboardedURI,
recoverHomeURI,
recoverPostOnboardingURI,
redirect,
touchScreenURI,
]);
}
Loading

0 comments on commit 46fea4c

Please sign in to comment.