@@ -21,17 +21,17 @@ 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+ } from '../../common/protocol' ;
2531import { nls } from '@theia/core/lib/common' ;
2632
2733@injectable ( )
2834export abstract class Examples extends SketchContribution {
29- @inject ( CommandRegistry )
30- protected readonly commandRegistry : CommandRegistry ;
31- 32- @inject ( MenuModelRegistry )
33- protected readonly menuRegistry : MenuModelRegistry ;
34- 3535 @inject ( MainMenuManager )
3636 protected readonly menuManager : MainMenuManager ;
3737
@@ -41,6 +41,12 @@ export abstract class Examples extends SketchContribution {
4141 @inject ( BoardsServiceProvider )
4242 protected readonly boardsServiceClient : BoardsServiceProvider ;
4343
44+ @inject ( CommandRegistry )
45+ private readonly commandRegistry : CommandRegistry ;
46+ 47+ @inject ( MenuModelRegistry )
48+ private readonly menuRegistry : MenuModelRegistry ;
49+ 4450 protected readonly toDispose = new DisposableCollection ( ) ;
4551
4652 protected override init ( ) : void {
@@ -50,10 +56,16 @@ export abstract class Examples extends SketchContribution {
5056 ) ;
5157 }
5258
59+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
5360 protected handleBoardChanged ( board : Board | undefined ) : void {
5461 // NOOP
5562 }
5663
64+ protected abstract update ( options ?: {
65+ board ?: Board | undefined ;
66+ forceRefresh ?: boolean ;
67+ } ) : void ;
68+ 5769 override registerMenus ( registry : MenuModelRegistry ) : void {
5870 try {
5971 // 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 +161,54 @@ export abstract class Examples extends SketchContribution {
149161 protected createHandler ( uri : string ) : CommandHandler {
150162 return {
151163 execute : async ( ) => {
152- const sketch = await this . sketchService . cloneExample ( uri ) ;
153- return this . commandService . executeCommand (
154- OpenSketch . Commands . OPEN_SKETCH . id ,
155- sketch
156- ) ;
164+ const sketch = await this . clone ( uri ) ;
165+ if ( sketch ) {
166+ try {
167+ return this . commandService . executeCommand (
168+ OpenSketch . Commands . OPEN_SKETCH . id ,
169+ sketch
170+ ) ;
171+ } catch ( err ) {
172+ if ( SketchesError . NotFound . is ( err ) ) {
173+ // Do not toast the error message. It's handled by the `Open Sketch` command.
174+ this . update ( {
175+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
176+ forceRefresh : true ,
177+ } ) ;
178+ } else {
179+ throw err ;
180+ }
181+ }
182+ }
157183 } ,
158184 } ;
159185 }
186+ 187+ private async clone ( uri : string ) : Promise < Sketch | undefined > {
188+ try {
189+ const sketch = await this . sketchService . cloneExample ( uri ) ;
190+ return sketch ;
191+ } catch ( err ) {
192+ if ( SketchesError . NotFound . is ( err ) ) {
193+ this . messageService . error ( err . message ) ;
194+ this . update ( {
195+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
196+ forceRefresh : true ,
197+ } ) ;
198+ } else {
199+ throw err ;
200+ }
201+ }
202+ }
160203}
161204
162205@injectable ( )
163206export class BuiltInExamples extends Examples {
164207 override async onReady ( ) : Promise < void > {
165- this . register ( ) ; // no `await`
208+ this . update ( ) ; // no `await`
166209 }
167210
168- protected async register ( ) : Promise < void > {
211+ protected override async update ( ) : Promise < void > {
169212 let sketchContainers : SketchContainer [ ] | undefined ;
170213 try {
171214 sketchContainers = await this . examplesService . builtIns ( ) ;
@@ -197,34 +240,37 @@ export class BuiltInExamples extends Examples {
197240@injectable ( )
198241export class LibraryExamples extends Examples {
199242 @inject ( NotificationCenter )
200- protected readonly notificationCenter : NotificationCenter ;
243+ private readonly notificationCenter : NotificationCenter ;
201244
202- protected readonly queue = new PQueue ( { autoStart : true , concurrency : 1 } ) ;
245+ private readonly queue = new PQueue ( { autoStart : true , concurrency : 1 } ) ;
203246
204247 override onStart ( ) : void {
205- this . notificationCenter . onLibraryDidInstall ( ( ) => this . register ( ) ) ;
206- this . notificationCenter . onLibraryDidUninstall ( ( ) => this . register ( ) ) ;
248+ this . notificationCenter . onLibraryDidInstall ( ( ) => this . update ( ) ) ;
249+ this . notificationCenter . onLibraryDidUninstall ( ( ) => this . update ( ) ) ;
207250 }
208251
209252 override async onReady ( ) : Promise < void > {
210- this . register ( ) ; // no `await`
253+ this . update ( ) ; // no `await`
211254 }
212255
213256 protected override handleBoardChanged ( board : Board | undefined ) : void {
214- this . register ( board ) ;
257+ this . update ( { board} ) ;
215258 }
216259
217- protected async register (
218- board : Board | undefined = this . boardsServiceClient . boardsConfig
219- . selectedBoard
260+ protected override async update (
261+ options : { board ?: Board ; forceRefresh ?: boolean } = {
262+ board : this . boardsServiceClient . boardsConfig . selectedBoard ,
263+ }
220264 ) : Promise < void > {
265+ const { board, forceRefresh } = options ;
221266 return this . queue . add ( async ( ) => {
222267 this . toDispose . dispose ( ) ;
223268 const fqbn = board ?. fqbn ;
224269 const name = board ?. name ;
225270 // Shows all examples when no board is selected, or the platform of the currently selected board is not installed.
226271 const { user, current, any } = await this . examplesService . installed ( {
227272 fqbn,
273+ forceRefresh,
228274 } ) ;
229275 if ( user . length ) {
230276 ( user as any ) . unshift (
0 commit comments