1
1
import { inject , injectable } from '@theia/core/shared/inversify' ;
2
2
import { Emitter } from '@theia/core/lib/common/event' ;
3
- import { BoardUserField , CoreService , Port } from '../../common/protocol' ;
4
- import { ArduinoMenus , PlaceholderMenuNode } from '../menu/arduino-menus' ;
3
+ import { CoreService , Port } from '../../common/protocol' ;
4
+ import { ArduinoMenus } from '../menu/arduino-menus' ;
5
5
import { ArduinoToolbar } from '../toolbar/arduino-toolbar' ;
6
6
import {
7
7
Command ,
@@ -11,93 +11,36 @@ import {
11
11
TabBarToolbarRegistry ,
12
12
CoreServiceContribution ,
13
13
} from './contribution' ;
14
- import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog' ;
15
- import { deepClone , DisposableCollection , nls } from '@theia/core/lib/common' ;
14
+ import { deepClone , nls } from '@theia/core/lib/common' ;
16
15
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl' ;
17
16
import type { VerifySketchParams } from './verify-sketch' ;
17
+ import { UserFields } from './user-fields' ;
18
18
19
19
@injectable ( )
20
20
export class UploadSketch extends CoreServiceContribution {
21
- @inject ( MenuModelRegistry )
22
- private readonly menuRegistry : MenuModelRegistry ;
23
-
24
- @inject ( UserFieldsDialog )
25
- private readonly userFieldsDialog : UserFieldsDialog ;
26
-
27
- private boardRequiresUserFields = false ;
28
- private userFieldsSet = false ;
29
- private readonly cachedUserFields : Map < string , BoardUserField [ ] > = new Map ( ) ;
30
- private readonly menuActionsDisposables = new DisposableCollection ( ) ;
31
-
32
21
private readonly onDidChangeEmitter = new Emitter < void > ( ) ;
33
22
private readonly onDidChange = this . onDidChangeEmitter . event ;
34
23
private uploadInProgress = false ;
35
24
36
- protected override init ( ) : void {
37
- super . init ( ) ;
38
- this . boardsServiceProvider . onBoardsConfigChanged ( async ( ) => {
39
- const userFields =
40
- await this . boardsServiceProvider . selectedBoardUserFields ( ) ;
41
- this . boardRequiresUserFields = userFields . length > 0 ;
42
- this . registerMenus ( this . menuRegistry ) ;
43
- } ) ;
44
- }
45
-
46
- private selectedFqbnAddress ( ) : string {
47
- const { boardsConfig } = this . boardsServiceProvider ;
48
- const fqbn = boardsConfig . selectedBoard ?. fqbn ;
49
- if ( ! fqbn ) {
50
- return '' ;
51
- }
52
- const address =
53
- boardsConfig . selectedBoard ?. port ?. address ||
54
- boardsConfig . selectedPort ?. address ;
55
- if ( ! address ) {
56
- return '' ;
57
- }
58
- return fqbn + '|' + address ;
59
- }
25
+ @inject ( UserFields )
26
+ private readonly userFields : UserFields ;
60
27
61
28
override registerCommands ( registry : CommandRegistry ) : void {
62
29
registry . registerCommand ( UploadSketch . Commands . UPLOAD_SKETCH , {
63
30
execute : async ( ) => {
64
- const key = this . selectedFqbnAddress ( ) ;
65
- /*
66
- If the board requires to be configured with user fields, we want
67
- to show the user fields dialog, but if they weren't already
68
- filled in or if they were filled in, but the previous upload failed.
69
- */
70
- if (
71
- this . boardRequiresUserFields &&
72
- key &&
73
- ( ! this . cachedUserFields . has ( key ) || ! this . userFieldsSet )
74
- ) {
75
- const userFieldsFilledIn = Boolean (
76
- await this . showUserFieldsDialog ( key )
77
- ) ;
78
- if ( ! userFieldsFilledIn ) {
79
- return ;
80
- }
31
+ if ( await this . userFields . checkUserFieldsDialog ( false ) ) {
32
+ this . uploadSketch ( ) ;
81
33
}
82
- this . uploadSketch ( ) ;
83
34
} ,
84
35
isEnabled : ( ) => ! this . uploadInProgress ,
85
36
} ) ;
86
37
registry . registerCommand ( UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION , {
87
38
execute : async ( ) => {
88
- const key = this . selectedFqbnAddress ( ) ;
89
- if ( ! key ) {
90
- return ;
91
- }
92
- const userFieldsFilledIn = Boolean (
93
- await this . showUserFieldsDialog ( key )
94
- ) ;
95
- if ( ! userFieldsFilledIn ) {
96
- return ;
39
+ if ( await this . userFields . checkUserFieldsDialog ( true ) ) {
40
+ this . uploadSketch ( ) ;
97
41
}
98
- this . uploadSketch ( ) ;
99
42
} ,
100
- isEnabled : ( ) => ! this . uploadInProgress && this . boardRequiresUserFields ,
43
+ isEnabled : ( ) => ! this . uploadInProgress && this . userFields . isRequired ( ) ,
101
44
} ) ;
102
45
registry . registerCommand (
103
46
UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER ,
@@ -117,45 +60,20 @@ export class UploadSketch extends CoreServiceContribution {
117
60
}
118
61
119
62
override registerMenus ( registry : MenuModelRegistry ) : void {
120
- this . menuActionsDisposables . dispose ( ) ;
121
- this . menuActionsDisposables . push (
122
- registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
123
- commandId : UploadSketch . Commands . UPLOAD_SKETCH . id ,
124
- label : nls . localize ( 'arduino/sketch/upload' , 'Upload' ) ,
125
- order : '1' ,
126
- } )
127
- ) ;
128
- if ( this . boardRequiresUserFields ) {
129
- this . menuActionsDisposables . push (
130
- registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
131
- commandId : UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION . id ,
132
- label : UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION . label ,
133
- order : '2' ,
134
- } )
135
- ) ;
136
- } else {
137
- this . menuActionsDisposables . push (
138
- registry . registerMenuNode (
139
- ArduinoMenus . SKETCH__MAIN_GROUP ,
140
- new PlaceholderMenuNode (
141
- ArduinoMenus . SKETCH__MAIN_GROUP ,
142
- // commandId: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.id,
143
- UploadSketch . Commands . UPLOAD_WITH_CONFIGURATION . label ,
144
- { order : '2' }
145
- )
146
- )
147
- ) ;
148
- }
149
- this . menuActionsDisposables . push (
150
- registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
151
- commandId : UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER . id ,
152
- label : nls . localize (
153
- 'arduino/sketch/uploadUsingProgrammer' ,
154
- 'Upload Using Programmer'
155
- ) ,
156
- order : '3' ,
157
- } )
158
- ) ;
63
+ registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
64
+ commandId : UploadSketch . Commands . UPLOAD_SKETCH . id ,
65
+ label : nls . localize ( 'arduino/sketch/upload' , 'Upload' ) ,
66
+ order : '1' ,
67
+ } ) ;
68
+
69
+ registry . registerMenuAction ( ArduinoMenus . SKETCH__MAIN_GROUP , {
70
+ commandId : UploadSketch . Commands . UPLOAD_SKETCH_USING_PROGRAMMER . id ,
71
+ label : nls . localize (
72
+ 'arduino/sketch/uploadUsingProgrammer' ,
73
+ 'Upload Using Programmer'
74
+ ) ,
75
+ order : '3' ,
76
+ } ) ;
159
77
}
160
78
161
79
override registerKeybindings ( registry : KeybindingRegistry ) : void {
@@ -212,20 +130,8 @@ export class UploadSketch extends CoreServiceContribution {
212
130
return ;
213
131
}
214
132
215
- if ( this . boardRequiresUserFields ) {
216
- // TODO: This does not belong here.
217
- // IDE2 should not do any preliminary checks but let the CLI fail and then toast a user consumable error message.
218
- if ( uploadOptions . userFields . length === 0 ) {
219
- this . messageService . error (
220
- nls . localize (
221
- 'arduino/sketch/userFieldsNotFoundError' ,
222
- "Can't find user fields for connected board"
223
- )
224
- ) ;
225
- this . userFieldsSet = false ;
226
- return ;
227
- }
228
- this . userFieldsSet = true ;
133
+ if ( ! this . userFields . checkUserFieldsForUpload ( ) ) {
134
+ return ;
229
135
}
230
136
231
137
await this . doWithProgress ( {
@@ -240,13 +146,7 @@ export class UploadSketch extends CoreServiceContribution {
240
146
{ timeout : 3000 }
241
147
) ;
242
148
} catch ( e ) {
243
- if (
244
- this . boardRequiresUserFields &&
245
- typeof e . message === 'string' &&
246
- e . message . startsWith ( 'Upload error:' )
247
- ) {
248
- this . userFieldsSet = false ;
249
- }
149
+ this . userFields . notifyFailedWithError ( e ) ;
250
150
this . handleError ( e ) ;
251
151
} finally {
252
152
this . uploadInProgress = false ;
@@ -263,7 +163,7 @@ export class UploadSketch extends CoreServiceContribution {
263
163
if ( ! CurrentSketch . isValid ( sketch ) ) {
264
164
return undefined ;
265
165
}
266
- const userFields = this . userFields ( ) ;
166
+ const userFields = this . userFields . getUserFields ( ) ;
267
167
const { boardsConfig } = this . boardsServiceProvider ;
268
168
const [ fqbn , { selectedProgrammer : programmer } , verify , verbose ] =
269
169
await Promise . all ( [
@@ -306,10 +206,6 @@ export class UploadSketch extends CoreServiceContribution {
306
206
return port ;
307
207
}
308
208
309
- private userFields ( ) : BoardUserField [ ] {
310
- return this . cachedUserFields . get ( this . selectedFqbnAddress ( ) ) ?? [ ] ;
311
- }
312
-
313
209
/**
314
210
* Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
315
211
* `VENDOR:ARCHITECTURE:BOARD_ID` format.
@@ -322,23 +218,6 @@ export class UploadSketch extends CoreServiceContribution {
322
218
const [ vendor , arch , id ] = fqbn . split ( ':' ) ;
323
219
return `${ vendor } :${ arch } :${ id } ` ;
324
220
}
325
-
326
- private async showUserFieldsDialog (
327
- key : string
328
- ) : Promise < BoardUserField [ ] | undefined > {
329
- const cached = this . cachedUserFields . get ( key ) ;
330
- // Deep clone the array of board fields to avoid editing the cached ones
331
- this . userFieldsDialog . value = (
332
- cached ?? ( await this . boardsServiceProvider . selectedBoardUserFields ( ) )
333
- ) . map ( ( f ) => ( { ...f } ) ) ;
334
- const result = await this . userFieldsDialog . open ( ) ;
335
- if ( ! result ) {
336
- return ;
337
- }
338
- this . userFieldsSet = true ;
339
- this . cachedUserFields . set ( key , result ) ;
340
- return result ;
341
- }
342
221
}
343
222
344
223
export namespace UploadSketch {
0 commit comments