Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(LIVE-9486): add specific featureFlags deeplinks tutorial #5027

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
1f89f9a
fix(recover): add specific featureFlags deeplinks tutorial
stephane-lieumont-ledger Oct 11, 2023
8165f42
fix(live-9486): update changlog
stephane-lieumont-ledger Oct 11, 2023
2d776a8
fix(live-9486): revert test file after prettier
stephane-lieumont-ledger Oct 11, 2023
1cde86a
fix(live-9486): fix ci libs
stephane-lieumont-ledger Oct 11, 2023
d3a8238
fix(live-9486): replace history push redirect
stephane-lieumont-ledger Oct 11, 2023
5f88029
fix(live-9486): add custom hook path for recover
stephane-lieumont-ledger Oct 12, 2023
cfc957f
fix(live-9486): add custom link for restore stax after onboarding
stephane-lieumont-ledger Oct 12, 2023
c835493
fix(live-9486): add restore redirection on recover restore
stephane-lieumont-ledger Oct 12, 2023
715a219
fix(live-9486): fix blackscreen stax onboarding
stephane-lieumont-ledger Oct 12, 2023
a6b1c4e
fix(live-9486): improve custom path for recover
stephane-lieumont-ledger Oct 20, 2023
262605d
Merge branch 'bugfix/deeplink-redirection-tracking-lld' of github.com…
stephane-lieumont-ledger Oct 20, 2023
31367fd
fix(live-9486): add restore redirection on recover restore
stephane-lieumont-ledger Oct 12, 2023
268f705
fix(live-9486): fix blackscreen stax onboarding
stephane-lieumont-ledger Oct 12, 2023
f8fda0c
Merge branch 'bugfix/deeplink-redirection-tracking-lld' of github.com…
stephane-lieumont-ledger Oct 20, 2023
946217c
Merge branch 'develop' into bugfix/deeplink-redirection-tracking-lld
stephane-lieumont-ledger Oct 20, 2023
d3e00b9
fix(live-9486): remove breaking change release replacing URI restore 24
stephane-lieumont-ledger Oct 23, 2023
843834a
fix(live-9486): add useMemo on useCustomPath
stephane-lieumont-ledger Oct 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/curly-coats-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ledgerhq/types-live": patch
"ledger-live-desktop": patch
"@ledgerhq/live-common": patch
---

Add specific deeplinks for useCase tutorial onboarding
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { CARD_APP_ID } from "~/renderer/screens/card";
import TopGradient from "./TopGradient";
import Hide from "./Hide";
import { track } from "~/renderer/analytics/segment";
import { useAccountPath } from "@ledgerhq/live-common/hooks/recoverFeatureFlag";

const MAIN_SIDEBAR_WIDTH = 230;
const TagText = styled.div.attrs<{ collapsed?: boolean }>(p => ({
Expand Down Expand Up @@ -229,6 +230,8 @@ const MainSideBar = () => {
const referralProgramConfig = useFeature("referralProgramDesktopSidebar");
const ptxEarnConfig = useFeature("ptxEarn");
const recoverFeature = useFeature("protectServicesDesktop");
const recoverHomePath = useAccountPath(recoverFeature);

const handleCollapse = useCallback(() => {
dispatch(setSidebarCollapsed(!collapsed));
}, [dispatch, collapsed]);
Expand Down Expand Up @@ -316,8 +319,8 @@ const MainSideBar = () => {
const openRecoverFromSidebar = recoverFeature?.params?.openRecoverFromSidebar;
const liveAppId = recoverFeature?.params?.protectId;

if (enabled && openRecoverFromSidebar && liveAppId) {
push(`/recover/${liveAppId}`);
if (enabled && openRecoverFromSidebar && liveAppId && recoverHomePath) {
history.push(recoverHomePath);
} else if (enabled) {
dispatch(openModal("MODAL_PROTECT_DISCOVER", undefined));
}
Expand All @@ -328,7 +331,8 @@ const MainSideBar = () => {
recoverFeature?.enabled,
recoverFeature?.params?.openRecoverFromSidebar,
recoverFeature?.params?.protectId,
push,
recoverHomePath,
history,
dispatch,
]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import {
usePostOnboardingPath,
useAlreadySeededDevicePath,
useRestore24Path,
useUpsellPath,
useCustomPath,
} from "@ledgerhq/live-common/hooks/recoverFeatureFlag";
import { useStartPostOnboardingCallback } from "@ledgerhq/live-common/postOnboarding/hooks/index";
import {
Expand Down Expand Up @@ -230,7 +232,9 @@ export default function Tutorial({ useCase }: Props) {
const { pathname } = useLocation();
const recoverFF = useFeature("protectServicesDesktop");
const upsellPath = useUpsellPath(recoverFF);
const postOnboardingPath = usePostOnboardingPath(recoverFF);
const restore24Path = useRestore24Path(recoverFF);
const devicePairingPath = useAlreadySeededDevicePath(recoverFF);
const recoverRestorePath = useCustomPath(recoverFF, "restore", "lld-restore-with-recover");
const recoverDiscoverPath = useMemo(() => {
return `/recover/${recoverFF?.params?.protectId}?redirectTo=disclaimerRestore`;
}, [recoverFF?.params?.protectId]);
Expand Down Expand Up @@ -567,15 +571,29 @@ export default function Tutorial({ useCase }: Props) {
deviceModelId: connectedDevice.modelId,
fallbackIfNoAction: () => history.push("/"),
});
if (upsellPath) {

if (useCase === UseCase.setupDevice && upsellPath) {
history.push(upsellPath);
} else if (useCase === UseCase.recoveryPhrase && restore24Path) {
history.push(restore24Path);
} else if (useCase === UseCase.connectDevice && devicePairingPath) {
history.push(devicePairingPath);
}
}, 0);
return () => {
clearTimeout(timeout);
};
}
}, [connectedDevice, handleStartPostOnboarding, history, onboardingDone, upsellPath]);
}, [
connectedDevice,
devicePairingPath,
handleStartPostOnboarding,
history,
onboardingDone,
restore24Path,
upsellPath,
useCase,
]);

const steps = useMemo(() => {
const stepList = [
Expand Down Expand Up @@ -681,8 +699,8 @@ export default function Tutorial({ useCase }: Props) {
const handleNextPin = useCallback(() => {
let targetPath: string | object = `${path}/${ScreenId.existingRecoveryPhrase}`;

if (useCase === UseCase.recover && postOnboardingPath) {
const [pathname, search] = postOnboardingPath.split("?");
if (useCase === UseCase.recover && recoverRestorePath) {
const [pathname, search] = recoverRestorePath.split("?");
targetPath = {
pathname,
search: search ? `?${search}` : undefined,
Expand All @@ -696,7 +714,7 @@ export default function Tutorial({ useCase }: Props) {
}

handleNextInDrawer(setHelpPinCode, targetPath);
}, [connectedDevice?.deviceId, dispatch, handleNextInDrawer, path, postOnboardingPath, useCase]);
}, [connectedDevice?.deviceId, dispatch, handleNextInDrawer, path, recoverRestorePath, useCase]);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React, {
import { useHistory } from "react-router-dom";
import { Box, Flex, Text, VerticalTimeline } from "@ledgerhq/react-ui";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useOnboardingStatePolling } from "@ledgerhq/live-common/onboarding/hooks/useOnboardingStatePolling";
import { getDeviceModel } from "@ledgerhq/devices";
import { DeviceModelInfo, SeedPhraseType } from "@ledgerhq/types-live";
Expand All @@ -19,7 +19,7 @@ import {
fromSeedPhraseTypeToNbOfSeedWords,
} from "@ledgerhq/live-common/hw/extractOnboardingState";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { usePostOnboardingPath } from "@ledgerhq/live-common/hooks/recoverFeatureFlag";
import { useCustomPath } from "@ledgerhq/live-common/hooks/recoverFeatureFlag";
import { lastSeenDeviceSelector } from "~/renderer/reducers/settings";
import { DesyncOverlay } from "./DesyncOverlay";
import SeedStep, { SeedPathStatus } from "./SeedStep";
Expand All @@ -34,6 +34,7 @@ import { Device } from "@ledgerhq/live-common/hw/actions/types";
import { setDrawer } from "~/renderer/drawers/Provider";
import LockedDeviceDrawer, { Props as LockedDeviceDrawerProps } from "./LockedDeviceDrawer";
import { LockedDeviceError } from "@ledgerhq/errors";
import { saveSettings } from "~/renderer/actions/settings";

const READY_REDIRECT_DELAY_MS = 2500;
const POLLING_PERIOD_MS = 1000;
Expand Down Expand Up @@ -101,14 +102,15 @@ const SyncOnboardingCompanion: React.FC<SyncOnboardingCompanionProps> = ({
}) => {
const { t } = useTranslation();
const history = useHistory<RecoverState>();
const dispatch = useDispatch();
const [stepKey, setStepKey] = useState<StepKey>(StepKey.Paired);
const [shouldRestoreApps, setShouldRestoreApps] = useState<boolean>(false);
const deviceToRestore = useSelector(lastSeenDeviceSelector) as DeviceModelInfo | null | undefined;
const lastCompanionStepKey = useRef<StepKey>();
const [seedPathStatus, setSeedPathStatus] = useState<SeedPathStatus>("choice_new_or_restore");

const servicesConfig = useFeature("protectServicesDesktop");
const postOnboardingPath = usePostOnboardingPath(servicesConfig);
const recoverRestoreStaxPath = useCustomPath(servicesConfig, "restore", "lld-stax-onboarding");

const productName = device
? getDeviceModel(device.modelId).productName || device.modelId
Expand Down Expand Up @@ -466,15 +468,20 @@ const SyncOnboardingCompanion: React.FC<SyncOnboardingCompanionProps> = ({
}, [device, allowedError, handleDesyncTimerRunsOut, desyncTimeout]);

useEffect(() => {
if (seedPathStatus === "recover_seed" && postOnboardingPath) {
const [pathname, search] = postOnboardingPath.split("?");
if (seedPathStatus === "recover_seed" && recoverRestoreStaxPath) {
const [pathname, search] = recoverRestoreStaxPath.split("?");
dispatch(
saveSettings({
hasCompletedOnboarding: true,
}),
);
history.push({
pathname,
search: search ? `?${search}` : undefined,
state: { fromOnboarding: true },
});
}
}, [history, postOnboardingPath, seedPathStatus]);
}, [dispatch, history, recoverRestoreStaxPath, seedPathStatus]);

return (
<Flex width="100%" height="100%" flexDirection="column" justifyContent="flex-start">
Expand Down
16 changes: 12 additions & 4 deletions libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,24 @@ export const DEFAULT_FEATURES: Features = {
params: {
availableOnDesktop: false,
account: {
homeURI: "ledgerlive://recover/protect-simu?redirectTo=account",
loginURI: "ledgerlive://recover/protect-simu?redirectTo=login",
homeURI:
"ledgerlive://recover/protect-simu?redirectTo=account&source=lld-sidebar-navigation&ajs_recover_source=lld-sidebar-navigation&ajs_recover_campaign=recover-launch",
loginURI:
"ledgerlive://recover/protect-simu?redirectTo=login&source=lld-welcome-login&ajs_recover_source=lld-welcome-login&ajs_recover_campaign=recover-launch",
},
discoverTheBenefitsLink: "https://www.ledger.com/recover",
onboardingCompleted: {
alreadySubscribedURI: "ledgerlive://recover/protect-simu?redirectTo=login",
upsellURI: "ledgerlive://recover/protect-simu?redirectTo=upsell",
alreadyDeviceSeededURI:
"ledgerlive://recover/protect-simu?redirectTo=upsell&source=lld-pairing&ajs_recover_source=lld-pairing&ajs_recover_campaign=recover-launch",
upsellURI:
"ledgerlive://recover/protect-simu?redirectTo=upsell&source=lld-onboarding-24&ajs_recover_source=lld-onboarding-24&ajs_recover_campaign=recover-launch",
restore24URI:
"ledgerlive://recover/protect-simu?redirectTo=upsell&source=lld-restore-24&ajs_recover_source=lld-restore-24&ajs_recover_campaign=recover-launch",
},
onboardingRestore: {
postOnboardingURI: "ledgerlive://recover/protect-simu?redirectTo=restore",
postOnboardingURI:
"ledgerlive://recover/protect-simu?redirectTo=restore&source=lld-restore",
restoreInfoDrawer: {
enabled: true,
manualStepsURI:
Expand Down
74 changes: 74 additions & 0 deletions libs/ledger-live-common/src/hooks/recoverFeatureFlag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,77 @@ export function useLoginPath(

return usePath(servicesConfig, uri);
}

export function useRestore24URI(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = servicesConfig?.params?.onboardingCompleted?.restore24URI;
const id = servicesConfig?.params?.protectId;

return useReplacedURI(uri, id);
}

export function useRestore24Path(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = useRestore24URI(servicesConfig);

return usePath(servicesConfig, uri);
}

export function useAccountURI(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = servicesConfig?.params?.account?.homeURI;
const id = servicesConfig?.params?.protectId;

return useReplacedURI(uri, id);
}

export function useAccountPath(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = useAccountURI(servicesConfig);

return usePath(servicesConfig, uri);
}

export function useAlreadySeededDeviceURI(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = servicesConfig?.params?.onboardingCompleted?.alreadyDeviceSeededURI;
const id = servicesConfig?.params?.protectId;

return useReplacedURI(uri, id);
}

export function useAlreadySeededDevicePath(
servicesConfig: Feature_ProtectServicesDesktop | null,
): string | undefined {
const uri = useAlreadySeededDeviceURI(servicesConfig);

return usePath(servicesConfig, uri);
}

export function useCustomPath(
servicesConfig: Feature_ProtectServicesDesktop | Feature_ProtectServicesMobile | null,
page?: string,
source?: string,
deeplinkCampaign?: string,
): string | undefined {
const modelUri = usePostOnboardingURI(servicesConfig);
const customUri = useMemo(() => {
const [basicUri] = modelUri ? modelUri.split("?") : [];
const uri = new URL(basicUri);

if (page) uri.searchParams.append("redirectTo", page);
if (source) uri.searchParams.append("source", source);
if (source && deeplinkCampaign) {
uri.searchParams.append("ajs_recover_source", source);
uri.searchParams.append("ajs_recover_campaign", deeplinkCampaign);
}
return uri;
}, [deeplinkCampaign, modelUri, page, source]);

return usePath(servicesConfig, customUri.toString()) ?? undefined;
}
2 changes: 2 additions & 0 deletions libs/ledgerjs/packages/types-live/src/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ export type Feature_ProtectServicesDesktop = Feature<{
};
onboardingCompleted: {
upsellURI: string;
restore24URI: string;
alreadySubscribedURI: string;
alreadyDeviceSeededURI: string;
};
account: {
homeURI: string;
Expand Down
Loading