@@ -268,11 +268,26 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
268
268
}
269
269
270
270
async onInstanceUpdate ( workspaceInstance : WorkspaceInstance ) {
271
- const startedInstanceId = this . state ?. startedInstanceId ;
272
- if ( workspaceInstance . workspaceId !== this . props . workspaceId || startedInstanceId !== workspaceInstance . id ) {
271
+ if ( workspaceInstance . workspaceId !== this . props . workspaceId ) {
273
272
return ;
274
273
}
275
274
275
+ // Here we filter out updates to instances we haven't started to avoid issues with updates coming in out-of-order
276
+ // (e.g., multiple "stopped" events from the older instance, where we already started a fresh one after the first)
277
+ // Only exception is when we do the switch from the "old" to the "new" one.
278
+ const startedInstanceId = this . state ?. startedInstanceId ;
279
+ if ( startedInstanceId !== workspaceInstance . id ) {
280
+ // do we want to switch to "new" instance we just received an update for?
281
+ const switchToNewInstance = this . state . workspaceInstance ?. status . phase === "stopped" && workspaceInstance . status . phase !== "stopped" ;
282
+ if ( ! switchToNewInstance ) {
283
+ return ;
284
+ }
285
+ this . setState ( {
286
+ startedInstanceId : workspaceInstance . id ,
287
+ workspaceInstance,
288
+ } ) ;
289
+ }
290
+
276
291
await this . ensureWorkspaceAuth ( workspaceInstance . id ) ;
277
292
278
293
// Redirect to workspaceURL if we are not yet running in an iframe.
@@ -337,7 +352,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
337
352
const { error } = this . state ;
338
353
const isHeadless = this . state . workspace ?. type !== 'regular' ;
339
354
const isPrebuilt = WithPrebuild . is ( this . state . workspace ?. context ) ;
340
- let phase = StartPhase . Preparing ;
355
+ let phase : StartPhase | undefined = StartPhase . Preparing ;
341
356
let title = undefined ;
342
357
let statusMessage = ! ! error ? undefined : < p className = "text-base text-gray-400" > Preparing workspace …</ p > ;
343
358
const contextURL = ContextURL . getNormalizedURL ( this . state . workspace ) ?. toString ( ) ;
@@ -384,7 +399,27 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
384
399
}
385
400
if ( ! this . state . desktopIde ) {
386
401
phase = StartPhase . Running ;
387
- statusMessage = < p className = "text-base text-gray-400" > Opening Workspace …</ p > ;
402
+
403
+ if ( this . state . dontAutostart ) {
404
+ title = 'Running'
405
+ phase = undefined ; // hide the progress bar, as we're already running
406
+ // in case we dontAutostart the IDE we have to provide controls to do so
407
+ statusMessage = < div >
408
+ < div className = "flex space-x-3 items-center text-left rounded-xl m-auto px-4 h-16 w-72 mt-4 mb-2 bg-gray-100 dark:bg-gray-800" >
409
+ < div className = "rounded-full w-3 h-3 text-sm bg-green-500" > </ div >
410
+ < div >
411
+ < p className = "text-gray-700 dark:text-gray-200 font-semibold w-56 truncate" > { this . state . workspaceInstance . workspaceId } </ p >
412
+ < a target = "_parent" href = { contextURL } > < p className = "w-56 truncate hover:text-blue-600 dark:hover:text-blue-400" > { contextURL } </ p > </ a >
413
+ </ div >
414
+ </ div >
415
+ < div className = "mt-10 justify-center flex space-x-2" >
416
+ < a target = "_parent" href = { gitpodHostUrl . asDashboard ( ) . toString ( ) } > < button className = "secondary" > Go to Dashboard</ button > </ a >
417
+ < a target = "_parent" href = { gitpodHostUrl . asStart ( this . props . workspaceId ) . toString ( ) /** move over 'start' here to fetch fresh credentials in case this is an older tab */ } > < button > Open Workspace</ button > </ a >
418
+ </ div >
419
+ </ div > ;
420
+ } else {
421
+ statusMessage = < p className = "text-base text-gray-400" > Opening Workspace …</ p > ;
422
+ }
388
423
} else {
389
424
phase = StartPhase . IdeReady ;
390
425
const openLink = this . state . desktopIde . link ;
0 commit comments