diff --git a/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts b/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts index 2da1e20d..2ad15078 100644 --- a/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts +++ b/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts @@ -29,6 +29,7 @@ export class BurnBootloader extends CoreServiceContribution { } private async burnBootloader(): Promise { + this.clearVisibleNotification(); const options = await this.options(); try { await this.doWithProgress({ diff --git a/arduino-ide-extension/src/browser/contributions/contribution.ts b/arduino-ide-extension/src/browser/contributions/contribution.ts index d3ae285f..309a72db 100644 --- a/arduino-ide-extension/src/browser/contributions/contribution.ts +++ b/arduino-ide-extension/src/browser/contributions/contribution.ts @@ -59,6 +59,8 @@ import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; import { ExecuteWithProgress } from '../../common/protocol/progressible'; import { BoardsServiceProvider } from '../boards/boards-service-provider'; import { BoardsDataStore } from '../boards/boards-data-store'; +import { NotificationManager } from '../theia/messages/notifications-manager'; +import { MessageType } from '@theia/core/lib/common/message-service-protocol'; export { Command, @@ -186,6 +188,22 @@ export abstract class CoreServiceContribution extends SketchContribution { @inject(ResponseServiceClient) private readonly responseService: ResponseServiceClient; + @inject(NotificationManager) + private readonly notificationManager: NotificationManager; + + /** + * This is the internal (Theia) ID of the notification that is currently visible. + * It's stored here as a field to be able to close it before executing any new core command (such as verify, upload, etc.) + */ + private visibleNotificationId: string | undefined; + + protected clearVisibleNotification(): void { + if (this.visibleNotificationId) { + this.notificationManager.clear(this.visibleNotificationId); + this.visibleNotificationId = undefined; + } + } + protected handleError(error: unknown): void { this.tryToastErrorMessage(error); } @@ -208,6 +226,7 @@ export abstract class CoreServiceContribution extends SketchContribution { 'arduino/coreContribution/copyError', 'Copy error messages' ); + this.visibleNotificationId = this.notificationId(message, copyAction); this.messageService.error(message, copyAction).then(async (action) => { if (action === copyAction) { const content = await this.outputChannelManager.contentOfChannel( @@ -241,6 +260,14 @@ export abstract class CoreServiceContribution extends SketchContribution { }); return result; } + + private notificationId(message: string, ...actions: string[]): string { + return this.notificationManager.getMessageId({ + text: message, + actions, + type: MessageType.Error, + }); + } } export namespace Contribution { diff --git a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts index e15e612a..d4bad139 100644 --- a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts +++ b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts @@ -191,6 +191,7 @@ export class UploadSketch extends CoreServiceContribution { // uploadInProgress will be set to false whether the upload fails or not this.uploadInProgress = true; this.onDidChangeEmitter.fire(); + this.clearVisibleNotification(); const verifyOptions = await this.commandService.executeCommand( diff --git a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts index 3fc2d53a..fe4de6f6 100644 --- a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts +++ b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts @@ -108,6 +108,7 @@ export class VerifySketch extends CoreServiceContribution { this.verifyInProgress = true; this.onDidChangeEmitter.fire(); } + this.clearVisibleNotification(); this.coreErrorHandler.reset(); const options = await this.options(params?.exportBinaries); diff --git a/arduino-ide-extension/src/browser/theia/messages/notifications-manager.ts b/arduino-ide-extension/src/browser/theia/messages/notifications-manager.ts index c3842750..bdc1ed35 100644 --- a/arduino-ide-extension/src/browser/theia/messages/notifications-manager.ts +++ b/arduino-ide-extension/src/browser/theia/messages/notifications-manager.ts @@ -1,9 +1,10 @@ -import { injectable } from '@theia/core/shared/inversify'; import { CancellationToken } from '@theia/core/lib/common/cancellation'; -import { +import type { + Message, ProgressMessage, ProgressUpdate, } from '@theia/core/lib/common/message-service-protocol'; +import { injectable } from '@theia/core/shared/inversify'; import { NotificationManager as TheiaNotificationManager } from '@theia/messages/lib/browser/notifications-manager'; @injectable() @@ -34,7 +35,9 @@ export class NotificationManager extends TheiaNotificationManager { this.fireUpdatedEvent(); } - protected override toPlainProgress(update: ProgressUpdate): number | undefined { + protected override toPlainProgress( + update: ProgressUpdate + ): number | undefined { if (!update.work) { return undefined; } @@ -43,4 +46,11 @@ export class NotificationManager extends TheiaNotificationManager { } return Math.min((update.work.done / update.work.total) * 100, 100); } + + /** + * For `public` visibility. + */ + override getMessageId(message: Message): string { + return super.getMessageId(message); + } }