Skip to content

Commit fdd9f36

Browse files
committed
refactor: canton offers desktop
1 parent eef536e commit fdd9f36

24 files changed

+2312
-1558
lines changed

.changeset/unlucky-pianos-smash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"ledger-live-desktop": minor
3+
---
4+
5+
refactor canton offers desktop

apps/ledger-live-desktop/src/renderer/families/canton/PendingTransferProposals/DeviceAppModal.test.tsx

Lines changed: 0 additions & 115 deletions
This file was deleted.
Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import React, { useCallback, useMemo, useState, useEffect, FC } from "react";
1+
import React, { FC } from "react";
22
import { useTranslation } from "react-i18next";
3-
import Modal, { ModalBody } from "~/renderer/components/Modal";
3+
import BigSpinner from "~/renderer/components/BigSpinner";
44
import Box from "~/renderer/components/Box";
55
import DeviceAction from "~/renderer/components/DeviceAction";
6-
import SuccessDisplay from "~/renderer/components/SuccessDisplay";
76
import ErrorDisplay from "~/renderer/components/ErrorDisplay";
8-
import BigSpinner from "~/renderer/components/BigSpinner";
7+
import Modal, { ModalBody } from "~/renderer/components/Modal";
8+
import SuccessDisplay from "~/renderer/components/SuccessDisplay";
99
import Text from "~/renderer/components/Text";
10-
import useConnectAppAction from "~/renderer/hooks/useConnectAppAction";
11-
import { CONNECTION_TYPES } from "~/renderer/analytics/hooks/variables";
1210
import type { TransferProposalAction } from "./types";
11+
import {
12+
useDeviceAppModalViewModel,
13+
type DeviceAppModalViewModel,
14+
} from "./useDeviceAppModalViewModel";
1315

1416
type Props = {
1517
isOpen: boolean;
@@ -19,63 +21,37 @@ type Props = {
1921
onClose?: () => void;
2022
};
2123

22-
type ConfirmationState = "pending" | "confirming" | "completed" | "error";
23-
2424
const translations = {
25-
title: {
25+
action: {
26+
accept: "families.canton.pendingTransactions.accept",
27+
reject: "families.canton.pendingTransactions.reject",
28+
withdraw: "families.canton.pendingTransactions.withdraw",
29+
},
30+
successTitle: {
2631
accept: "families.canton.pendingTransactions.deviceAppModal.success.accept.title",
2732
reject: "families.canton.pendingTransactions.deviceAppModal.success.reject.title",
2833
withdraw: "families.canton.pendingTransactions.deviceAppModal.success.withdraw.title",
2934
},
30-
description: {
35+
successDescription: {
3136
accept: "families.canton.pendingTransactions.deviceAppModal.success.accept.description",
3237
reject: "families.canton.pendingTransactions.deviceAppModal.success.reject.description",
3338
withdraw: "families.canton.pendingTransactions.deviceAppModal.success.withdraw.description",
3439
},
3540
};
3641

37-
const DeviceAppModal: FC<Props> = ({ isOpen, onConfirm, action, onClose, appName }) => {
42+
export function View({
43+
confirmationState,
44+
error,
45+
request,
46+
actionConnect,
47+
handleDeviceResult,
48+
handleRetry,
49+
isOpen,
50+
action,
51+
onClose,
52+
}: DeviceAppModalViewModel) {
3853
const { t } = useTranslation();
39-
const [confirmationState, setConfirmationState] = useState<ConfirmationState>("pending");
40-
const [error, setError] = useState<Error | null>(null);
41-
42-
const actionConnect = useConnectAppAction();
43-
const request = useMemo(
44-
() => ({
45-
appName,
46-
}),
47-
[appName],
48-
);
49-
50-
useEffect(() => {
51-
if (isOpen) {
52-
setConfirmationState("pending");
53-
setError(null);
54-
}
55-
}, [isOpen]);
56-
57-
const handleConfirm = useCallback(
58-
async (deviceId: string) => {
59-
try {
60-
setConfirmationState("confirming");
61-
await onConfirm(deviceId);
62-
setConfirmationState("completed");
63-
} catch (err) {
64-
setConfirmationState("error");
65-
setError(err instanceof Error ? err : new Error(String(err)));
66-
}
67-
},
68-
[onConfirm],
69-
);
70-
71-
const handleRetry = useCallback(() => {
72-
setConfirmationState("pending");
73-
setError(null);
74-
}, []);
75-
76-
const actionTitle = useMemo(() => {
77-
return action.toUpperCase().slice(0, 1) + action.slice(1);
78-
}, [action]);
54+
const actionTitle = t(translations.action[action]);
7955

8056
return (
8157
<Modal
@@ -102,8 +78,8 @@ const DeviceAppModal: FC<Props> = ({ isOpen, onConfirm, action, onClose, appName
10278
{confirmationState === "completed" ? (
10379
<Box alignItems="center" py={4}>
10480
<SuccessDisplay
105-
title={t(translations.title[action])}
106-
description={t(translations.description[action])}
81+
title={t(translations.successTitle[action])}
82+
description={t(translations.successDescription[action])}
10783
/>
10884
</Box>
10985
) : confirmationState === "error" && error ? (
@@ -129,17 +105,7 @@ const DeviceAppModal: FC<Props> = ({ isOpen, onConfirm, action, onClose, appName
129105
<DeviceAction
130106
action={actionConnect}
131107
request={request}
132-
onResult={async result => {
133-
if (result) {
134-
let deviceId = result?.device?.deviceId;
135-
136-
if (!deviceId || deviceId === "") {
137-
deviceId = result.device?.wired ? CONNECTION_TYPES.USB : CONNECTION_TYPES.BLE;
138-
}
139-
140-
await handleConfirm(deviceId);
141-
}
142-
}}
108+
onResult={handleDeviceResult}
143109
analyticsPropertyFlow="canton-pending"
144110
/>
145111
)}
@@ -148,6 +114,10 @@ const DeviceAppModal: FC<Props> = ({ isOpen, onConfirm, action, onClose, appName
148114
/>
149115
</Modal>
150116
);
117+
}
118+
119+
const DeviceAppModal: FC<Props> = ({ isOpen, onConfirm, action, onClose, appName }) => {
120+
return <View {...useDeviceAppModalViewModel({ isOpen, onConfirm, action, appName, onClose })} />;
151121
};
152122

153123
export default DeviceAppModal;

0 commit comments

Comments
 (0)