Skip to content

Commit 5085754

Browse files
author
Akos Kitta
committed
Refresh menus when opening example/recent fails.
Closes #53 Signed-off-by: Akos Kitta <[email protected]>
1 parent 671d2ea commit 5085754

13 files changed

+294
-343
lines changed

Diff for: arduino-ide-extension/src/browser/contributions/examples.ts

+71-19
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,33 @@ import {
2121
MenuModelRegistry,
2222
} from './contribution';
2323
import { 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';
2532
import { nls } from '@theia/core/lib/common';
2633

2734
@injectable()
2835
export 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()
163210
export 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()
198245
export 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.

Diff for: arduino-ide-extension/src/browser/contributions/new-sketch.ts

-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { nls } from '@theia/core/lib/common';
22
import { injectable } from '@theia/core/shared/inversify';
33
import { ArduinoMenus } from '../menu/arduino-menus';
4-
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
54
import {
65
SketchContribution,
76
URI,
@@ -17,11 +16,6 @@ export class NewSketch extends SketchContribution {
1716
registry.registerCommand(NewSketch.Commands.NEW_SKETCH, {
1817
execute: () => this.newSketch(),
1918
});
20-
registry.registerCommand(NewSketch.Commands.NEW_SKETCH__TOOLBAR, {
21-
isVisible: (widget) =>
22-
ArduinoToolbar.is(widget) && widget.side === 'left',
23-
execute: () => registry.executeCommand(NewSketch.Commands.NEW_SKETCH.id),
24-
});
2519
}
2620

2721
override registerMenus(registry: MenuModelRegistry): void {
@@ -54,8 +48,5 @@ export namespace NewSketch {
5448
export const NEW_SKETCH: Command = {
5549
id: 'arduino-new-sketch',
5650
};
57-
export const NEW_SKETCH__TOOLBAR: Command = {
58-
id: 'arduino-new-sketch--toolbar',
59-
};
6051
}
6152
}

Diff for: arduino-ide-extension/src/browser/contributions/open-recent-sketch.ts

+25-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { MainMenuManager } from '../../common/main-menu-manager';
1515
import { OpenSketch } from './open-sketch';
1616
import { NotificationCenter } from '../notification-center';
1717
import { nls } from '@theia/core/lib/common';
18+
import { SketchesError } from '../../common/protocol';
1819

1920
@injectable()
2021
export class OpenRecentSketch extends SketchContribution {
@@ -33,7 +34,7 @@ export class OpenRecentSketch extends SketchContribution {
3334
@inject(NotificationCenter)
3435
protected readonly notificationCenter: NotificationCenter;
3536

36-
protected toDisposeBeforeRegister = new Map<string, DisposableCollection>();
37+
protected toDispose = new DisposableCollection();
3738

3839
override onStart(): void {
3940
this.notificationCenter.onRecentSketchesDidChange(({ sketches }) =>
@@ -42,8 +43,12 @@ export class OpenRecentSketch extends SketchContribution {
4243
}
4344

4445
override async onReady(): Promise<void> {
46+
this.update();
47+
}
48+
49+
private update(forceUpdate?: boolean): void {
4550
this.sketchService
46-
.recentlyOpenedSketches()
51+
.recentlyOpenedSketches(forceUpdate)
4752
.then((sketches) => this.refreshMenu(sketches));
4853
}
4954

@@ -62,19 +67,25 @@ export class OpenRecentSketch extends SketchContribution {
6267

6368
protected register(sketches: Sketch[]): void {
6469
const order = 0;
70+
this.toDispose.dispose();
6571
for (const sketch of sketches) {
6672
const { uri } = sketch;
67-
const toDispose = this.toDisposeBeforeRegister.get(uri);
68-
if (toDispose) {
69-
toDispose.dispose();
70-
}
7173
const command = { id: `arduino-open-recent--${uri}` };
7274
const handler = {
73-
execute: () =>
74-
this.commandRegistry.executeCommand(
75-
OpenSketch.Commands.OPEN_SKETCH.id,
76-
sketch
77-
),
75+
execute: async () => {
76+
try {
77+
await this.commandRegistry.executeCommand(
78+
OpenSketch.Commands.OPEN_SKETCH.id,
79+
sketch
80+
);
81+
} catch (err) {
82+
if (SketchesError.NotFound.is(err)) {
83+
this.update(true);
84+
} else {
85+
throw err;
86+
}
87+
}
88+
},
7889
};
7990
this.commandRegistry.registerCommand(command, handler);
8091
this.menuRegistry.registerMenuAction(
@@ -85,17 +96,16 @@ export class OpenRecentSketch extends SketchContribution {
8596
order: String(order),
8697
}
8798
);
88-
this.toDisposeBeforeRegister.set(
89-
sketch.uri,
99+
this.toDispose.pushAll([
90100
new DisposableCollection(
91101
Disposable.create(() =>
92102
this.commandRegistry.unregisterCommand(command)
93103
),
94104
Disposable.create(() =>
95105
this.menuRegistry.unregisterMenuAction(command)
96106
)
97-
)
98-
);
107+
),
108+
]);
99109
}
100110
}
101111
}

0 commit comments

Comments
 (0)