@@ -21,23 +21,33 @@ import {
2121 MenuModelRegistry ,
2222} from './contribution' ;
2323import { NotificationCenter } from '../notification-center' ;
24- import { Board , SketchRef , SketchContainer } from '../../common/protocol' ;
24+ import {
25+ Board ,
26+ SketchRef ,
27+ SketchContainer ,
28+ SketchesError ,
29+ Sketch ,
30+ CoreService ,
31+ } from '../../common/protocol' ;
2532import { nls } from '@theia/core/lib/common' ;
2633
2734@injectable ( )
2835export abstract class Examples extends SketchContribution {
2936 @inject ( CommandRegistry )
30- protected readonly commandRegistry : CommandRegistry ;
37+ private readonly commandRegistry : CommandRegistry ;
3138
3239 @inject ( MenuModelRegistry )
33- protected readonly menuRegistry : MenuModelRegistry ;
40+ private readonly menuRegistry : MenuModelRegistry ;
3441
3542 @inject ( MainMenuManager )
3643 protected readonly menuManager : MainMenuManager ;
3744
3845 @inject ( ExamplesService )
3946 protected readonly examplesService : ExamplesService ;
4047
48+ @inject ( CoreService )
49+ protected readonly coreService : CoreService ;
50+
4151 @inject ( BoardsServiceProvider )
4252 protected readonly boardsServiceClient : BoardsServiceProvider ;
4353
@@ -50,10 +60,16 @@ export abstract class Examples extends SketchContribution {
5060 ) ;
5161 }
5262
63+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
5364 protected handleBoardChanged ( board : Board | undefined ) : void {
5465 // NOOP
5566 }
5667
68+ protected abstract update ( options ?: {
69+ board ?: Board | undefined ;
70+ forceRefresh ?: boolean ;
71+ } ) : void ;
72+
5773 override registerMenus ( registry : MenuModelRegistry ) : void {
5874 try {
5975 // This is a hack the ensures the desired menu ordering! We cannot use https://github.com/eclipse-theia/theia/pull/8377 due to ATL-222.
@@ -149,23 +165,54 @@ export abstract class Examples extends SketchContribution {
149165 protected createHandler ( uri : string ) : CommandHandler {
150166 return {
151167 execute : async ( ) => {
152- const sketch = await this . sketchService . cloneExample ( uri ) ;
153- return this . commandService . executeCommand (
154- OpenSketch . Commands . OPEN_SKETCH . id ,
155- sketch
156- ) ;
168+ const sketch = await this . clone ( uri ) ;
169+ if ( sketch ) {
170+ try {
171+ return this . commandService . executeCommand (
172+ OpenSketch . Commands . OPEN_SKETCH . id ,
173+ sketch
174+ ) ;
175+ } catch ( err ) {
176+ if ( SketchesError . NotFound . is ( err ) ) {
177+ // Do not toast the error message. It's handled by the `Open Sketch` command.
178+ this . update ( {
179+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
180+ forceRefresh : true ,
181+ } ) ;
182+ } else {
183+ throw err ;
184+ }
185+ }
186+ }
157187 } ,
158188 } ;
159189 }
190+
191+ private async clone ( uri : string ) : Promise < Sketch | undefined > {
192+ try {
193+ const sketch = await this . sketchService . cloneExample ( uri ) ;
194+ return sketch ;
195+ } catch ( err ) {
196+ if ( SketchesError . NotFound . is ( err ) ) {
197+ this . messageService . error ( err . message ) ;
198+ this . update ( {
199+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
200+ forceRefresh : true ,
201+ } ) ;
202+ } else {
203+ throw err ;
204+ }
205+ }
206+ }
160207}
161208
162209@injectable ( )
163210export class BuiltInExamples extends Examples {
164211 override async onReady ( ) : Promise < void > {
165- this . register ( ) ; // no `await`
212+ this . update ( ) ; // no `await`
166213 }
167214
168- protected async register ( ) : Promise < void > {
215+ protected override async update ( ) : Promise < void > {
169216 let sketchContainers : SketchContainer [ ] | undefined ;
170217 try {
171218 sketchContainers = await this . examplesService . builtIns ( ) ;
@@ -197,29 +244,34 @@ export class BuiltInExamples extends Examples {
197244@injectable ( )
198245export class LibraryExamples extends Examples {
199246 @inject ( NotificationCenter )
200- protected readonly notificationCenter : NotificationCenter ;
247+ private readonly notificationCenter : NotificationCenter ;
201248
202- protected readonly queue = new PQueue ( { autoStart : true , concurrency : 1 } ) ;
249+ private readonly queue = new PQueue ( { autoStart : true , concurrency : 1 } ) ;
203250
204251 override onStart ( ) : void {
205- this . notificationCenter . onLibraryDidInstall ( ( ) => this . register ( ) ) ;
206- this . notificationCenter . onLibraryDidUninstall ( ( ) => this . register ( ) ) ;
252+ this . notificationCenter . onLibraryDidInstall ( ( ) => this . update ( ) ) ;
253+ this . notificationCenter . onLibraryDidUninstall ( ( ) => this . update ( ) ) ;
207254 }
208255
209256 override async onReady ( ) : Promise < void > {
210- this . register ( ) ; // no `await`
257+ this . update ( ) ; // no `await`
211258 }
212259
213260 protected override handleBoardChanged ( board : Board | undefined ) : void {
214- this . register ( board ) ;
261+ this . update ( { board } ) ;
215262 }
216263
217- protected async register (
218- board : Board | undefined = this . boardsServiceClient . boardsConfig
219- . selectedBoard
264+ protected override async update (
265+ options : { board ?: Board ; forceRefresh ?: boolean } = {
266+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
267+ }
220268 ) : Promise < void > {
269+ const { board, forceRefresh } = options ;
221270 return this . queue . add ( async ( ) => {
222271 this . toDispose . dispose ( ) ;
272+ if ( forceRefresh ) {
273+ await this . coreService . refresh ( ) ;
274+ }
223275 const fqbn = board ?. fqbn ;
224276 const name = board ?. name ;
225277 // Shows all examples when no board is selected, or the platform of the currently selected board is not installed.
0 commit comments