@@ -25,6 +25,7 @@ export class UploadSketch extends CoreServiceContribution {
2525 private readonly userFieldsDialog : UserFieldsDialog ;
2626
2727 private boardRequiresUserFields = false ;
28+ private userFieldsSet = false ;
2829 private readonly cachedUserFields : Map < string , BoardUserField [ ] > = new Map ( ) ;
2930 private readonly menuActionsDisposables = new DisposableCollection ( ) ;
3031
@@ -61,20 +62,22 @@ export class UploadSketch extends CoreServiceContribution {
6162 registry . registerCommand ( UploadSketch . Commands . UPLOAD_SKETCH , {
6263 execute : async ( ) => {
6364 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+ */
6470 if (
6571 this . boardRequiresUserFields &&
6672 key &&
67- ! this . cachedUserFields . has ( key )
73+ ( ! this . cachedUserFields . has ( key ) || ! this . userFieldsSet )
6874 ) {
69- // Deep clone the array of board fields to avoid editing the cached ones
70- this . userFieldsDialog . value = (
71- await this . boardsServiceProvider . selectedBoardUserFields ( )
72- ) . map ( ( f ) => ( { ...f } ) ) ;
73- const result = await this . userFieldsDialog . open ( ) ;
74- if ( ! result ) {
75+ const userFieldsFilledIn = Boolean (
76+ await this . showUserFieldsDialog ( key )
77+ ) ;
78+ if ( ! userFieldsFilledIn ) {
7579 return ;
7680 }
77- this . cachedUserFields . set ( key , result ) ;
7881 }
7982 this . uploadSketch ( ) ;
8083 } ,
@@ -86,18 +89,12 @@ export class UploadSketch extends CoreServiceContribution {
8689 if ( ! key ) {
8790 return ;
8891 }
89-
90- const cached = this . cachedUserFields . get ( key ) ;
91- // Deep clone the array of board fields to avoid editing the cached ones
92- this . userFieldsDialog . value = (
93- cached ?? ( await this . boardsServiceProvider . selectedBoardUserFields ( ) )
94- ) . map ( ( f ) => ( { ...f } ) ) ;
95-
96- const result = await this . userFieldsDialog . open ( ) ;
97- if ( ! result ) {
92+ const userFieldsFilledIn = Boolean (
93+ await this . showUserFieldsDialog ( key )
94+ ) ;
95+ if ( ! userFieldsFilledIn ) {
9896 return ;
9997 }
100- this . cachedUserFields . set ( key , result ) ;
10198 this . uploadSketch ( ) ;
10299 } ,
103100 isEnabled : ( ) => ! this . uploadInProgress && this . boardRequiresUserFields ,
@@ -215,19 +212,20 @@ export class UploadSketch extends CoreServiceContribution {
215212 return ;
216213 }
217214
218- // TODO: This does not belong here.
219- // IDE2 should not do any preliminary checks but let the CLI fail and then toast a user consumable error message.
220- if (
221- uploadOptions . userFields . length === 0 &&
222- this . boardRequiresUserFields
223- ) {
224- this . messageService . error (
225- nls . localize (
226- 'arduino/sketch/userFieldsNotFoundError' ,
227- "Can't find user fields for connected board"
228- )
229- ) ;
230- return ;
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 ;
231229 }
232230
233231 await this . doWithProgress ( {
@@ -242,6 +240,13 @@ export class UploadSketch extends CoreServiceContribution {
242240 { timeout : 3000 }
243241 ) ;
244242 } catch ( e ) {
243+ if (
244+ this . boardRequiresUserFields &&
245+ typeof e . message === 'string' &&
246+ e . message . startsWith ( 'Upload error:' )
247+ ) {
248+ this . userFieldsSet = false ;
249+ }
245250 this . handleError ( e ) ;
246251 } finally {
247252 this . uploadInProgress = false ;
@@ -317,6 +322,23 @@ export class UploadSketch extends CoreServiceContribution {
317322 const [ vendor , arch , id ] = fqbn . split ( ':' ) ;
318323 return `${ vendor } :${ arch } :${ id } ` ;
319324 }
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+ }
320342}
321343
322344export namespace UploadSketch {
0 commit comments