Skip to content

Commit

Permalink
💄 [BUGFIX]: Add CTAs on missing screens for LedgerSync (#7627)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcayuelas-ledger authored Aug 20, 2024
1 parent 17ca82c commit a442d80
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-mangos-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ledger-live-desktop": patch
---

Add CTAs on missing screens for LedgerSync
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe("useFlows", () => {
expect(result.current.currentStep).toBe(Object.values(steps)[0]);

act(() => {
result.current.goToWelcomeScreenWalletSync(false);
result.current.goToWelcomeScreenWalletSync();
});
expect(store.getState().walletSync.step).toBe(Step.CreateOrSynchronize);
expect(store.getState().walletSync.flow).toBe(Flow.Activation);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { trustchainSelector } from "@ledgerhq/trustchain/store";
import { useDispatch, useSelector } from "react-redux";
import { setFlow } from "~/renderer/actions/walletSync";
import {
Expand Down Expand Up @@ -70,11 +71,12 @@ export const STEPS_WITH_BACK: Step[] = [
Step.ManageBackup,
Step.DeleteBackup,
Step.SynchronizedInstances,
Step.SynchronizeMode,
];

export const useFlows = () => {
const dispatch = useDispatch();

const trustchain = useSelector(trustchainSelector);
const currentFlow = useSelector(walletSyncFlowSelector);
const currentStep = useSelector(walletSyncStepSelector);

Expand All @@ -94,8 +96,8 @@ export const useFlows = () => {
dispatch(setFlow({ flow: currentFlow, step: stepsRecord[newStep] }));
};

const goToWelcomeScreenWalletSync = (isWalletSyncActivated: boolean) => {
if (isWalletSyncActivated) {
const goToWelcomeScreenWalletSync = () => {
if (trustchain?.rootId) {
dispatch(setFlow({ flow: Flow.WalletSyncActivated, step: Step.WalletSyncActivated }));
} else {
dispatch(setFlow({ flow: Flow.Activation, step: Step.CreateOrSynchronize }));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import React, { useState } from "react";
import React, { forwardRef, useImperativeHandle, useState } from "react";
import { useDispatch } from "react-redux";
import { Flex } from "@ledgerhq/react-ui";
import { Flow, Step } from "~/renderer/reducers/walletSync";
import { setFlow } from "~/renderer/actions/walletSync";

import { useFlows } from "../../hooks/useFlows";
import { FlowOptions, useFlows } from "../../hooks/useFlows";
import CreateOrSynchronizeStep from "./01-CreateOrSynchronizeStep";
import DeviceActionStep from "./02-DeviceActionStep";
import ActivationOrSynchroWithTrustchain from "./03-ActivationOrSynchroWithTrustchain";
import ActivationFinalStep from "./04-ActivationFinalStep";
import { Device } from "@ledgerhq/live-common/hw/actions/types";
import ErrorStep from "./05-ActivationOrSyncError";
import { AnalyticsPage, useWalletSyncAnalytics } from "../../hooks/useWalletSyncAnalytics";
import { BackRef, BackProps } from "../router";

const WalletSyncActivation = () => {
const WalletSyncActivation = forwardRef<BackRef, BackProps>((_props, ref) => {
const dispatch = useDispatch();
const [device, setDevice] = useState<Device | null>(null);

const { currentStep, goToNextScene } = useFlows();
const { currentStep, goToNextScene, goToPreviousScene, goToWelcomeScreenWalletSync } = useFlows();

const { onClickTrack } = useWalletSyncAnalytics();

useImperativeHandle(ref, () => ({
goBack,
}));

const goBack = () => {
if (currentStep === FlowOptions[Flow.Activation].steps[1]) {
goToWelcomeScreenWalletSync();
} else {
goToPreviousScene();
}
};

const goToSync = () => {
dispatch(setFlow({ flow: Flow.Synchronize, step: Step.SynchronizeMode }));
onClickTrack({
Expand Down Expand Up @@ -74,6 +87,6 @@ const WalletSyncActivation = () => {
{getStep()}
</Flex>
);
};

});
WalletSyncActivation.displayName = "WalletSyncActivation";
export default WalletSyncActivation;
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,40 @@ import { useTranslation } from "react-i18next";
import { Flex } from "@ledgerhq/react-ui";
import { Error } from "../../components/Error";
import { BackupDeletedProps } from "./types";
import { AnalyticsPage, useWalletSyncAnalytics } from "../../hooks/useWalletSyncAnalytics";
import { useDispatch } from "react-redux";
import { setDrawerVisibility } from "~/renderer/actions/walletSync";

export default function BackupDeleted({ isSuccessful }: BackupDeletedProps) {
const { t } = useTranslation();

const { onClickTrack } = useWalletSyncAnalytics();

const dispatch = useDispatch();

const onClose = () => {
dispatch(setDrawerVisibility(false));
onClickTrack({
button: "Close",
page: AnalyticsPage.BackupDeleted,
flow: "Wallet Sync",
});
};

return (
<Flex flexDirection="column" alignItems="center" justifyContent="center" height="100%">
{isSuccessful ? (
<Success title={t("walletSync.manageBackup.deleteBackupSuccess.title")} />
<Success
title={t("walletSync.manageBackup.deleteBackupSuccess.title")}
withClose
onClose={onClose}
analyticsPage={AnalyticsPage.BackupDeleted}
/>
) : (
<Error title={t("walletSync.manageBackup.deleteBackupError.title")} />
<Error
title={t("walletSync.manageBackup.deleteBackupError.title")}
analyticsPage={AnalyticsPage.BackupDeletionError}
/>
)}
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const WalletSyncManageBackup = forwardRef<BackRef, BackProps>((_props, ref) => {

const goBack = () => {
if (currentStep === FlowOptions[Flow.ManageBackup].steps[1]) {
goToWelcomeScreenWalletSync(true);
goToWelcomeScreenWalletSync();
} else {
goToPreviousScene();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,33 @@ import React from "react";
import { Success } from "../../components/Success";
import { useTranslation } from "react-i18next";
import { FinalStepProps } from "./04-DeletionFinalErrorStep";
import { AnalyticsPage } from "../../hooks/useWalletSyncAnalytics";
import { AnalyticsPage, useWalletSyncAnalytics } from "../../hooks/useWalletSyncAnalytics";
import { setDrawerVisibility } from "~/renderer/actions/walletSync";
import { useDispatch } from "react-redux";

export default function DeletionFinalStep({ instance }: FinalStepProps) {
const { t } = useTranslation();
const title = "walletSync.manageInstances.deleteInstanceSuccess";
const { onClickTrack } = useWalletSyncAnalytics();

const dispatch = useDispatch();

const onClose = () => {
dispatch(setDrawerVisibility(false));
onClickTrack({
button: "Close",
page: AnalyticsPage.InstanceRemovalSuccess,
flow: "Wallet Sync",
});
};
return (
<Success
title={t(title, {
instanceName: instance?.name,
})}
analyticsPage={AnalyticsPage.InstanceRemovalSuccess}
withClose
onClose={onClose}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const WalletSyncManageInstances = forwardRef<BackRef, BackProps>((_props, ref) =

const goBack = () => {
if (currentStep === FlowOptions[Flow.ManageInstances].steps[1]) {
goToWelcomeScreenWalletSync(true);
goToWelcomeScreenWalletSync();
} else {
goToPreviousScene();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,47 @@
import React from "react";
import { Success } from "../../components/Success";
import { useTranslation } from "react-i18next";
import { AnalyticsPage } from "../../hooks/useWalletSyncAnalytics";
import { AnalyticsPage, useWalletSyncAnalytics } from "../../hooks/useWalletSyncAnalytics";
import { useDispatch } from "react-redux";
import { setDrawerVisibility, setFlow } from "~/renderer/actions/walletSync";
import { Flow, Step } from "~/renderer/reducers/walletSync";

export default function SyncFinalStep() {
const { t } = useTranslation();
const dispatch = useDispatch();

const { onClickTrack } = useWalletSyncAnalytics();

const title = "walletSync.success.synch.title";
const desc = "walletSync.success.synch.desc";

const onClose = () => {
dispatch(setDrawerVisibility(false));
onClickTrack({
button: "Close",
page: AnalyticsPage.KeyUpdated,
flow: "Wallet Sync",
});
};

const goToSync = () => {
dispatch(setFlow({ flow: Flow.Synchronize, step: Step.SynchronizeWithQRCode }));
onClickTrack({
button: "Sync with another Ledger Live",
page: AnalyticsPage.KeyUpdated,
flow: "Wallet Sync",
});
};

return (
<Success title={t(title)} description={t(desc)} analyticsPage={AnalyticsPage.KeyUpdated} />
<Success
title={t(title)}
description={t(desc)}
analyticsPage={AnalyticsPage.KeyUpdated}
withClose
onClose={onClose}
withCta
onClick={goToSync}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import { Flex } from "@ledgerhq/react-ui";
import React from "react";
import React, { forwardRef, useImperativeHandle } from "react";
import { useDispatch } from "react-redux";
import { setFlow } from "~/renderer/actions/walletSync";
import { Flow, Step } from "~/renderer/reducers/walletSync";
import { useFlows } from "../../hooks/useFlows";
import { FlowOptions, useFlows } from "../../hooks/useFlows";
import SynchronizeModeStep from "./01-SyncModeStep";
import SynchWithQRCodeStep from "./02-QRCodeStep";
import PinCodeStep from "./03-PinCodeStep";
import SyncFinalStep from "./04-SyncFinalStep";
import { AnalyticsPage, useWalletSyncAnalytics } from "../../hooks/useWalletSyncAnalytics";
import PinCodeErrorStep from "./05-PinCodeError";
import { BackProps, BackRef } from "../router";

const SynchronizeWallet = () => {
const SynchronizeWallet = forwardRef<BackRef, BackProps>((_props, ref) => {
const dispatch = useDispatch();

const { currentStep, goToNextScene } = useFlows();
useImperativeHandle(ref, () => ({
goBack,
}));

const { currentStep, goToNextScene, goToPreviousScene, goToWelcomeScreenWalletSync } = useFlows();
const { onClickTrack } = useWalletSyncAnalytics();

const goBack = () => {
if (currentStep === FlowOptions[Flow.Synchronize].steps[1]) {
goToWelcomeScreenWalletSync();
} else {
goToPreviousScene();
}
};

const startSyncWithDevice = () => {
dispatch(setFlow({ flow: Flow.Activation, step: Step.DeviceAction }));
onClickTrack({
Expand Down Expand Up @@ -74,6 +87,8 @@ const SynchronizeWallet = () => {
{getStep()}
</Flex>
);
};
});

SynchronizeWallet.displayName = "SynchronizeWallet";

export default SynchronizeWallet;
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export const WalletSyncRouter = forwardRef<BackRef, BackProps>((_props, ref) =>
switch (walletSyncFlow) {
default:
case Flow.Activation:
return <WalletSyncActivation />;
return <WalletSyncActivation ref={ref} />;
case Flow.WalletSyncActivated:
return <WalletSyncManage />;
case Flow.Synchronize:
return <SynchronizeWallet />;
return <SynchronizeWallet ref={ref} />;
case Flow.ManageBackup:
return <WalletSyncManageBackup ref={ref} />;
case Flow.ManageInstances:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
walletSyncStepSelector,
} from "~/renderer/reducers/walletSync";
import { resetWalletSync, setDrawerVisibility } from "~/renderer/actions/walletSync";
import { trustchainSelector } from "@ledgerhq/trustchain/store";

import {
useWalletSyncAnalytics,
AnalyticsPage,
Expand Down Expand Up @@ -37,7 +37,6 @@ const WalletSyncRow = () => {
const currentStep = useSelector(walletSyncStepSelector);
const hasBeenFaked = useSelector(walletSyncFakedSelector);
const hasBack = useMemo(() => STEPS_WITH_BACK.includes(currentStep), [currentStep]);
const trustchain = useSelector(trustchainSelector);

const { onClickTrack, onActionTrack } = useWalletSyncAnalytics();

Expand All @@ -59,7 +58,7 @@ const WalletSyncRow = () => {

const openDrawer = () => {
if (!hasBeenFaked) {
goToWelcomeScreenWalletSync(!!trustchain?.rootId);
goToWelcomeScreenWalletSync();
onClickTrack({ button: "Wallet Sync", page: AnalyticsPage.SettingsGeneral });
}
dispatch(setDrawerVisibility(true));
Expand Down

0 comments on commit a442d80

Please sign in to comment.