1- import React , { useCallback , useMemo , useState , useEffect , FC } from "react" ;
1+ import React , { FC } from "react" ;
22import { useTranslation } from "react-i18next" ;
3- import Modal , { ModalBody } from "~/renderer/components/Modal " ;
3+ import BigSpinner from "~/renderer/components/BigSpinner " ;
44import Box from "~/renderer/components/Box" ;
55import DeviceAction from "~/renderer/components/DeviceAction" ;
6- import SuccessDisplay from "~/renderer/components/SuccessDisplay" ;
76import 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" ;
99import Text from "~/renderer/components/Text" ;
10- import useConnectAppAction from "~/renderer/hooks/useConnectAppAction" ;
11- import { CONNECTION_TYPES } from "~/renderer/analytics/hooks/variables" ;
1210import type { TransferProposalAction } from "./types" ;
11+ import {
12+ useDeviceAppModalViewModel ,
13+ type DeviceAppModalViewModel ,
14+ } from "./useDeviceAppModalViewModel" ;
1315
1416type Props = {
1517 isOpen : boolean ;
@@ -19,63 +21,37 @@ type Props = {
1921 onClose ?: ( ) => void ;
2022} ;
2123
22- type ConfirmationState = "pending" | "confirming" | "completed" | "error" ;
23-
2424const 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
153123export default DeviceAppModal ;
0 commit comments