@@ -13,7 +13,7 @@ import {
13
13
import { ipcRenderer } from 'electron' ;
14
14
import { defaults , isEqual } from 'lodash' ;
15
15
import { enqueueSnackbar } from 'notistack' ;
16
- import React , { FC , useEffect } from 'react' ;
16
+ import React , { FC , useEffect , useState } from 'react' ;
17
17
import { useLocalStorage } from 'usehooks-ts' ;
18
18
19
19
import {
@@ -26,6 +26,7 @@ import {
26
26
TOAST_LENGTH ,
27
27
VIEW_CONNECTION_LIST ,
28
28
} from '../../shared/constants' ;
29
+ import { fetchRoutes , getAllRecords , saveRecord } from '../../shared/ipc' ;
29
30
import {
30
31
Connection ,
31
32
FetchRoutesRequest ,
@@ -64,52 +65,47 @@ function portalRouteToRecord(
64
65
) ;
65
66
}
66
67
67
- function reconcileConnections ( baseRecord : Record , portalRoutes : PortalRoute [ ] ) {
68
- ipcRenderer . once ( GET_ALL_RECORDS , ( _ , args ) => {
69
- const { err, res } : GetRecordsResponseArgs = args ;
70
- if ( err ) {
71
- enqueueSnackbar ( err . message , {
72
- variant : 'error' ,
73
- autoHideDuration : TOAST_LENGTH ,
74
- } ) ;
75
- return ;
76
- }
68
+ async function reconcileConnections (
69
+ baseRecord : Record ,
70
+ portalRoutes : PortalRoute [ ] ,
71
+ ) {
72
+ const res = await getAllRecords ( ) ;
77
73
78
- const currentRecords = new Map < string , Record > (
79
- res ?. records
80
- ?. filter ( ( r ) => r . source ?. startsWith ( 'portal-route-' ) )
81
- ?. map ( ( r ) => [ r . source || '' , r ] ) || [ ] ,
82
- ) ;
83
- const newRecords = new Map < string , Record > (
84
- portalRoutes
85
- ?. filter ( ( pr ) => pr . type === 'tcp' || pr . type === 'udp' )
86
- ?. map ( ( pr ) => portalRouteToRecord ( baseRecord , pr ) )
87
- ?. map ( ( r ) => [ r . source || '' , r ] ) || [ ] ,
88
- ) ;
74
+ const currentRecords = new Map < string , Record > (
75
+ res ?. records
76
+ ?. filter ( ( r ) => r . source ?. startsWith ( 'portal-route-' ) )
77
+ ?. map ( ( r ) => [ r . source || '' , r ] ) || [ ] ,
78
+ ) ;
79
+ const newRecords = new Map < string , Record > (
80
+ portalRoutes
81
+ ?. filter ( ( pr ) => pr . type === 'tcp' || pr . type === 'udp' )
82
+ ?. map ( ( pr ) => portalRouteToRecord ( baseRecord , pr ) )
83
+ ?. map ( ( r ) => [ r . source || '' , r ] ) || [ ] ,
84
+ ) ;
89
85
90
- // remove current records which have been deleted
91
- for ( const [ k , r ] of currentRecords ) {
92
- if ( ! newRecords . has ( k ) ) {
93
- ipcRenderer . send ( DELETE , {
94
- ids : [ r . id ] ,
95
- } ) ;
96
- }
86
+ // remove current records which have been deleted
87
+ for ( const [ k , r ] of currentRecords ) {
88
+ if ( ! newRecords . has ( k ) ) {
89
+ ipcRenderer . send ( DELETE , {
90
+ ids : [ r . id ] ,
91
+ } ) ;
97
92
}
93
+ }
98
94
99
- // add or update new records which have changed
100
- for ( const [ k , r ] of newRecords ) {
101
- const cr = currentRecords . get ( k ) ;
102
- if ( ! cr ) {
103
- ipcRenderer . send ( SAVE_RECORD , r ) ;
104
- return ;
105
- }
106
- const nr = defaults ( r , cr ) ;
107
- if ( ! isEqual ( nr , cr ) ) {
108
- ipcRenderer . send ( SAVE_RECORD , nr ) ;
109
- }
95
+ // add or update new records which have changed
96
+ for ( const [ k , r ] of newRecords ) {
97
+ const cr = currentRecords . get ( k ) ;
98
+ if ( ! cr ) {
99
+ await saveRecord ( r ) ;
100
+ return ;
101
+ }
102
+ const nr = defaults ( r , cr ) ;
103
+ if ( ! isEqual ( nr , cr ) ) {
104
+ await saveRecord ( nr ) ;
110
105
}
111
- } ) ;
112
- ipcRenderer . send ( GET_ALL_RECORDS ) ;
106
+ }
107
+
108
+ await getAllRecords ( ) ;
113
109
}
114
110
115
111
export type LoadFormProps = { } ;
@@ -125,6 +121,7 @@ const LoadForm: FC<LoadFormProps> = ({}) => {
125
121
} ,
126
122
) ;
127
123
const [ tags , setTags ] = useLocalStorage ( 'LoadForm/tags' , ( ) : string [ ] => [ ] ) ;
124
+ const [ loading , setLoading ] = useState ( false ) ;
128
125
129
126
const onChangeUrl = ( evt : React . ChangeEvent < HTMLInputElement > ) => {
130
127
setServerUrl ( evt . target . value ) ;
@@ -136,33 +133,34 @@ const LoadForm: FC<LoadFormProps> = ({}) => {
136
133
const onClickLoad = ( evt : React . MouseEvent ) => {
137
134
evt . preventDefault ( ) ;
138
135
139
- if ( serverUrl ) {
140
- const req : FetchRoutesRequest = {
141
- serverUrl,
142
- disableTlsVerification : connection . disableTlsVerification ,
143
- caCert : connection . caCert ,
144
- clientCert : connection . clientCert ,
145
- clientCertFromStore : connection . clientCertFromStore ,
146
- } ;
147
- ipcRenderer . once ( FETCH_ROUTES , ( _ , args ) => {
148
- const { err, res } : FetchRoutesResponseArgs = args ;
149
- if ( err ) {
150
- enqueueSnackbar ( err . message , {
151
- variant : 'error' ,
152
- autoHideDuration : TOAST_LENGTH ,
136
+ ( async ( ) => {
137
+ try {
138
+ setLoading ( true ) ;
139
+ if ( serverUrl ) {
140
+ const res = await fetchRoutes ( {
141
+ serverUrl,
142
+ disableTlsVerification : connection . disableTlsVerification ,
143
+ caCert : connection . caCert ,
144
+ clientCert : connection . clientCert ,
145
+ clientCertFromStore : connection . clientCertFromStore ,
153
146
} ) ;
154
- return ;
147
+ await reconcileConnections (
148
+ {
149
+ tags,
150
+ conn : connection ,
151
+ } ,
152
+ res ?. routes || [ ] ,
153
+ ) ;
155
154
}
156
- reconcileConnections (
157
- {
158
- tags,
159
- conn : connection ,
160
- } ,
161
- res ?. routes || [ ] ,
162
- ) ;
163
- } ) ;
164
- ipcRenderer . send ( FETCH_ROUTES , req ) ;
165
- }
155
+ } catch ( e ) {
156
+ enqueueSnackbar ( `${ ( e as any ) ?. message || e } ` , {
157
+ variant : 'error' ,
158
+ autoHideDuration : TOAST_LENGTH ,
159
+ } ) ;
160
+ } finally {
161
+ setLoading ( false ) ;
162
+ }
163
+ } ) ( ) ;
166
164
} ;
167
165
const onSubmit = ( evt : React . FormEvent ) => {
168
166
evt . preventDefault ( ) ;
@@ -241,7 +239,7 @@ const LoadForm: FC<LoadFormProps> = ({}) => {
241
239
type = "button"
242
240
variant = "contained"
243
241
color = "primary"
244
- disabled = { ! serverUrl }
242
+ disabled = { ! serverUrl || loading }
245
243
onClick = { onClickLoad }
246
244
>
247
245
Load
0 commit comments