@@ -65,6 +65,13 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
65
65
protected _availablePorts : Port [ ] = [ ] ;
66
66
protected _availableBoards : AvailableBoard [ ] = [ ] ;
67
67
68
+ private uploadInProgress = false ;
69
+
70
+ private lastItemRemovedForUpload : { board : Board ; port : Port } | undefined ;
71
+ // "lastPersistingUploadPort", is a port created during an upload, that persisted after
72
+ // the upload finished, it's "substituting" the port selected when the user invoked the upload
73
+ private lastPersistingUploadPort : Port | undefined ;
74
+
68
75
/**
69
76
* Unlike `onAttachedBoardsChanged` this even fires when the user modifies the selected board in the IDE.\
70
77
* This even also fires, when the boards package was not available for the currently selected board,
@@ -80,6 +87,9 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
80
87
private readonly _reconciled = new Deferred < void > ( ) ;
81
88
82
89
onStart ( ) : void {
90
+ this . notificationCenter . onUploadInProgress (
91
+ this . onUploadNotificationReceived . bind ( this )
92
+ ) ;
83
93
this . notificationCenter . onAttachedBoardsDidChange (
84
94
this . notifyAttachedBoardsChanged . bind ( this )
85
95
) ;
@@ -111,6 +121,68 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
111
121
return this . _reconciled . promise ;
112
122
}
113
123
124
+ private onUploadNotificationReceived ( uploadInProgress : boolean ) : void {
125
+ this . uploadInProgress = uploadInProgress ;
126
+ }
127
+
128
+ private checkForItemRemoved ( event : AttachedBoardsChangeEvent ) : void {
129
+ if ( ! this . lastItemRemovedForUpload ) {
130
+ const {
131
+ oldState : { ports : oldPorts , boards : oldBoards } ,
132
+ newState : { ports : newPorts } ,
133
+ } = event ;
134
+
135
+ const disappearedPorts = oldPorts . filter ( ( oldPort : Port ) =>
136
+ newPorts . every ( ( newPort : Port ) => ! Port . sameAs ( oldPort , newPort ) )
137
+ ) ;
138
+
139
+ if ( disappearedPorts . length > 0 ) {
140
+ this . lastItemRemovedForUpload = {
141
+ board : oldBoards . find ( ( board : Board ) =>
142
+ Port . sameAs ( board . port , disappearedPorts [ 0 ] )
143
+ ) as Board ,
144
+ port : disappearedPorts [ 0 ] ,
145
+ } ;
146
+ }
147
+
148
+ return ;
149
+ }
150
+ }
151
+
152
+ private checkForPersistingPort ( event : AttachedBoardsChangeEvent ) : void {
153
+ if ( this . lastItemRemovedForUpload ) {
154
+ const {
155
+ oldState : { ports : oldPorts } ,
156
+ newState : { ports : newPorts , boards : newBoards } ,
157
+ } = event ;
158
+
159
+ const disappearedItem = this . lastItemRemovedForUpload ;
160
+ this . lastItemRemovedForUpload = undefined ;
161
+
162
+ const appearedPorts = newPorts . filter ( ( newPort : Port ) =>
163
+ oldPorts . every ( ( oldPort : Port ) => ! Port . sameAs ( newPort , oldPort ) )
164
+ ) ;
165
+
166
+ if ( appearedPorts . length > 0 ) {
167
+ const boardOnAppearedPort = newBoards . find ( ( board : Board ) =>
168
+ Port . sameAs ( board . port , appearedPorts [ 0 ] )
169
+ ) ;
170
+
171
+ if (
172
+ boardOnAppearedPort &&
173
+ Board . sameAs ( boardOnAppearedPort , disappearedItem . board )
174
+ ) {
175
+ this . lastPersistingUploadPort = appearedPorts [ 0 ] ;
176
+ return ;
177
+ }
178
+ }
179
+
180
+ return ;
181
+ }
182
+
183
+ this . lastPersistingUploadPort = undefined ;
184
+ }
185
+
114
186
protected notifyAttachedBoardsChanged (
115
187
event : AttachedBoardsChangeEvent
116
188
) : void {
@@ -119,10 +191,21 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
119
191
this . logger . info ( AttachedBoardsChangeEvent . toString ( event ) ) ;
120
192
this . logger . info ( '------------------------------------------' ) ;
121
193
}
194
+
195
+ if ( this . uploadInProgress ) {
196
+ this . checkForItemRemoved ( event ) ;
197
+ } else {
198
+ this . checkForPersistingPort ( event ) ;
199
+ }
200
+
122
201
this . _attachedBoards = event . newState . boards ;
123
202
this . _availablePorts = event . newState . ports ;
124
203
this . onAvailablePortsChangedEmitter . fire ( this . _availablePorts ) ;
125
- this . reconcileAvailableBoards ( ) . then ( ( ) => this . tryReconnect ( ) ) ;
204
+ this . reconcileAvailableBoards ( ) . then ( ( ) => {
205
+ if ( ! this . uploadInProgress ) {
206
+ this . tryReconnect ( ) ;
207
+ }
208
+ } ) ;
126
209
}
127
210
128
211
protected notifyPlatformInstalled ( event : { item : BoardsPackage } ) : void {
@@ -240,6 +323,21 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
240
323
}
241
324
// If we could not find an exact match, we compare the board FQBN-name pairs and ignore the port, as it might have changed.
242
325
// See documentation on `latestValidBoardsConfig`.
326
+
327
+ if ( ! this . lastPersistingUploadPort ) return false ;
328
+
329
+ const lastPersistingUploadPort = this . lastPersistingUploadPort ;
330
+ this . lastPersistingUploadPort = undefined ;
331
+
332
+ if (
333
+ ! Port . sameAs (
334
+ lastPersistingUploadPort ,
335
+ this . latestValidBoardsConfig . selectedPort
336
+ )
337
+ ) {
338
+ return false ;
339
+ }
340
+
243
341
for ( const board of this . availableBoards . filter (
244
342
( { state } ) => state !== AvailableBoard . State . incomplete
245
343
) ) {
@@ -458,6 +556,11 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
458
556
const board = attachedBoards . find ( ( { port } ) =>
459
557
Port . sameAs ( boardPort , port )
460
558
) ;
559
+ // "board" will always be falsey for
560
+ // port that was originally mapped
561
+ // to unknown board and then selected
562
+ // manually by user
563
+
461
564
const lastSelectedBoard = await this . getLastSelectedBoardOnPort (
462
565
boardPort
463
566
) ;
@@ -476,7 +579,9 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
476
579
availableBoard = {
477
580
...lastSelectedBoard ,
478
581
state : AvailableBoard . State . guessed ,
479
- selected : BoardsConfig . Config . sameAs ( boardsConfig , lastSelectedBoard ) ,
582
+ selected :
583
+ BoardsConfig . Config . sameAs ( boardsConfig , lastSelectedBoard ) &&
584
+ Port . sameAs ( boardPort , boardsConfig . selectedPort ) , // to avoid double selection
480
585
port : boardPort ,
481
586
} ;
482
587
} else {
@@ -491,7 +596,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
491
596
492
597
if (
493
598
boardsConfig . selectedBoard &&
494
- ! availableBoards . some ( ( { selected } ) => selected )
599
+ availableBoards . every ( ( { selected } ) => ! selected )
495
600
) {
496
601
// If the selected board has the same port of an unknown board
497
602
// that is already in availableBoards we might get a duplicate port.
0 commit comments