From 87d5a499eb4281e0ffd8f2c7ca4f31f3d346a8a9 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 11 Mar 2022 16:29:56 +0100 Subject: [PATCH 1/4] fix active sketchbook behavior in sidebar --- .../local-cache/local-cache-fs-provider.ts | 6 ++- .../src/browser/utils/constants.ts | 2 + .../cloud-sketchbook-composite-widget.tsx | 14 ++++++ .../cloud-sketchbook-widget.ts | 44 ++++++++++++++----- 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 arduino-ide-extension/src/browser/utils/constants.ts diff --git a/arduino-ide-extension/src/browser/local-cache/local-cache-fs-provider.ts b/arduino-ide-extension/src/browser/local-cache/local-cache-fs-provider.ts index a0aa3733e..c385abfae 100644 --- a/arduino-ide-extension/src/browser/local-cache/local-cache-fs-provider.ts +++ b/arduino-ide-extension/src/browser/local-cache/local-cache-fs-provider.ts @@ -16,6 +16,10 @@ import { import { AuthenticationClientService } from '../auth/authentication-client-service'; import { AuthenticationSession } from '../../common/protocol/authentication-service'; import { ConfigService } from '../../common/protocol'; +import { + ARDUINO_CLOUD_FOLDER, + REMOTE_SKETCHBOOK_FOLDER, +} from '../utils/constants'; export namespace LocalCacheUri { export const scheme = 'arduino-local-cache'; @@ -91,7 +95,7 @@ export class LocalCacheFsProvider protected async init(fileService: FileService): Promise { const config = await this.configService.getConfiguration(); this._localCacheRoot = new URI(config.dataDirUri); - for (const segment of ['RemoteSketchbook', 'ArduinoCloud']) { + for (const segment of [REMOTE_SKETCHBOOK_FOLDER, ARDUINO_CLOUD_FOLDER]) { this._localCacheRoot = this._localCacheRoot.resolve(segment); await fileService.createFolder(this._localCacheRoot); } diff --git a/arduino-ide-extension/src/browser/utils/constants.ts b/arduino-ide-extension/src/browser/utils/constants.ts new file mode 100644 index 000000000..570929d35 --- /dev/null +++ b/arduino-ide-extension/src/browser/utils/constants.ts @@ -0,0 +1,2 @@ +export const REMOTE_SKETCHBOOK_FOLDER = 'RemoteSketchbook'; +export const ARDUINO_CLOUD_FOLDER = 'ArduinoCloud'; diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-composite-widget.tsx b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-composite-widget.tsx index 958e16857..7b52eae6d 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-composite-widget.tsx +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-composite-widget.tsx @@ -58,6 +58,20 @@ export class CloudSketchbookCompositeWidget extends BaseWidget { ); } + protected onActivateRequest(msg: Message): void { + super.onActivateRequest(msg); + this.cloudSketchbookTreeWidget.activate(); + + /* + Sending a resize message is needed because otherwise the cloudSketchbookTreeWidget + would render empty + */ + MessageLoop.sendMessage( + this.cloudSketchbookTreeWidget, + Widget.ResizeMessage.UnknownSize + ); + } + protected onResize(message: Widget.ResizeMessage): void { super.onResize(message); MessageLoop.sendMessage( diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts index 42b3177be..43f6b4573 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts @@ -2,6 +2,11 @@ import { inject, injectable, postConstruct } from 'inversify'; import { CloudSketchbookCompositeWidget } from './cloud-sketchbook-composite-widget'; import { SketchbookWidget } from '../sketchbook/sketchbook-widget'; import { ArduinoPreferences } from '../../arduino-preferences'; +import { Message } from '@theia/core/shared/@phosphor/messaging'; +import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; +import { SketchControl } from '../../contributions/sketch-control'; +import { LocalCacheFsProvider } from '../../local-cache/local-cache-fs-provider'; +import { REMOTE_SKETCHBOOK_FOLDER } from '../../utils/constants'; @injectable() export class CloudSketchbookWidget extends SketchbookWidget { @@ -11,6 +16,15 @@ export class CloudSketchbookWidget extends SketchbookWidget { @inject(ArduinoPreferences) protected readonly arduinoPreferences: ArduinoPreferences; + @inject(SketchControl) + protected readonly sketchControl: SketchControl; + + @inject(SketchesServiceClientImpl) + protected readonly sketchesServiceClient: SketchesServiceClientImpl; + + @inject(LocalCacheFsProvider) + protected readonly localCacheFsProvider: LocalCacheFsProvider; + @postConstruct() protected init(): void { super.init(); @@ -25,33 +39,41 @@ export class CloudSketchbookWidget extends SketchbookWidget { return widget; } - checkCloudEnabled() { - if (this.arduinoPreferences['arduino.cloud.enabled']) { - this.sketchbookTreesContainer.activateWidget(this.widget); - } else { - this.sketchbookTreesContainer.activateWidget( - this.localSketchbookTreeWidget - ); - } - this.setDocumentMode(); + protected onAfterShow(msg: Message): void { + this.checkCloudEnabled(); + super.onAfterShow(msg); } - setDocumentMode() { + async checkCloudEnabled(): Promise { + const currentSketch = await this.sketchesServiceClient.currentSketch(); + const isCloudSketch = + currentSketch && currentSketch.uri.includes(REMOTE_SKETCHBOOK_FOLDER); + if (this.arduinoPreferences['arduino.cloud.enabled']) { this.sketchbookTreesContainer.mode = 'multiple-document'; + if (isCloudSketch) { + this.sketchbookTreesContainer.activateWidget(this.widget); + } } else { this.sketchbookTreesContainer.mode = 'single-document'; } + + if (!isCloudSketch || !this.arduinoPreferences['arduino.cloud.enabled']) { + this.sketchbookTreesContainer.activateWidget( + this.localSketchbookTreeWidget + ); + } } protected onAfterAttach(msg: any) { this.sketchbookTreesContainer.addWidget(this.widget); - this.setDocumentMode(); + this.sketchbookTreesContainer.mode = 'single-document'; this.arduinoPreferences.onPreferenceChanged((event) => { if (event.preferenceName === 'arduino.cloud.enabled') { this.checkCloudEnabled(); } }); + this.checkCloudEnabled(); super.onAfterAttach(msg); } } From c8ac75126ec03bb87a8657420e36203bfa86db61 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Wed, 16 Mar 2022 14:50:42 +0100 Subject: [PATCH 2/4] always show the correct sketchbook at ide start-up --- .../browser/arduino-ide-frontend-module.ts | 28 +++++++++---------- .../browser/theia/core/application-shell.ts | 13 +++++++++ .../theia/core/shell-layout-restorer.ts | 14 ++++++---- .../widgets/sketchbook/sketchbook-commands.ts | 4 +++ .../sketchbook-widget-contribution.ts | 6 ++-- .../widgets/sketchbook/sketchbook-widget.tsx | 3 +- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts index 5ceae9179..1eb40997a 100644 --- a/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts @@ -420,9 +420,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(SerialService) .toDynamicValue((context) => { const connection = context.container.get(WebSocketConnectionProvider); - const client = context.container.get( - SerialServiceClient - ); + const client = + context.container.get(SerialServiceClient); return connection.createProxy(SerialServicePath, client); }) .inSingletonScope(); @@ -486,11 +485,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { .inSingletonScope(); rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope(); rebind(TabBarToolbarFactory).toFactory( - ({ container: parentContainer }) => () => { - const container = parentContainer.createChild(); - container.bind(TabBarToolbar).toSelf().inSingletonScope(); - return container.get(TabBarToolbar); - } + ({ container: parentContainer }) => + () => { + const container = parentContainer.createChild(); + container.bind(TabBarToolbar).toSelf().inSingletonScope(); + return container.get(TabBarToolbar); + } ); bind(OutputWidget).toSelf().inSingletonScope(); rebind(TheiaOutputWidget).toService(OutputWidget); @@ -655,15 +655,13 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { // Enable the dirty indicator on uncloseable widgets. rebind(TabBarRendererFactory).toFactory((context) => () => { - const contextMenuRenderer = context.container.get( - ContextMenuRenderer - ); + const contextMenuRenderer = + context.container.get(ContextMenuRenderer); const decoratorService = context.container.get( TabBarDecoratorService ); - const iconThemeService = context.container.get( - IconThemeService - ); + const iconThemeService = + context.container.get(IconThemeService); return new TabBarRenderer( contextMenuRenderer, decoratorService, @@ -723,7 +721,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bindViewContribution(bind, SketchbookWidgetContribution); bind(FrontendApplicationContribution).toService(SketchbookWidgetContribution); bind(WidgetFactory).toDynamicValue(({ container }) => ({ - id: 'arduino-sketchbook-widget', + id: SketchbookWidget.ID, createWidget: () => container.get(SketchbookWidget), })); diff --git a/arduino-ide-extension/src/browser/theia/core/application-shell.ts b/arduino-ide-extension/src/browser/theia/core/application-shell.ts index 2ed449065..22f28e317 100644 --- a/arduino-ide-extension/src/browser/theia/core/application-shell.ts +++ b/arduino-ide-extension/src/browser/theia/core/application-shell.ts @@ -16,6 +16,7 @@ import { Sketch } from '../../../common/protocol'; import { SaveAsSketch } from '../../contributions/save-as-sketch'; import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import { nls } from '@theia/core/lib/common'; +import { SketchbookWidget } from '../../widgets/sketchbook/sketchbook-widget'; @injectable() export class ApplicationShell extends TheiaApplicationShell { @@ -31,6 +32,18 @@ export class ApplicationShell extends TheiaApplicationShell { @inject(ConnectionStatusService) protected readonly connectionStatusService: ConnectionStatusService; + async setLayoutData( + layoutData: TheiaApplicationShell.LayoutData + ): Promise { + layoutData.activeWidgetId = SketchbookWidget.ID; + layoutData.leftPanel?.items?.forEach((item) => { + if (item?.widget?.id === SketchbookWidget.ID) item.expanded = true; + else item.expanded = false; + }); + + super.setLayoutData(layoutData); + } + protected track(widget: Widget): void { super.track(widget); if (widget instanceof OutputWidget) { diff --git a/arduino-ide-extension/src/browser/theia/core/shell-layout-restorer.ts b/arduino-ide-extension/src/browser/theia/core/shell-layout-restorer.ts index a72c89bf1..4b08a42fd 100644 --- a/arduino-ide-extension/src/browser/theia/core/shell-layout-restorer.ts +++ b/arduino-ide-extension/src/browser/theia/core/shell-layout-restorer.ts @@ -1,15 +1,19 @@ import { injectable } from 'inversify'; -import { FrontendApplication } from '@theia/core/lib/browser/frontend-application'; import { ShellLayoutRestorer as TheiaShellLayoutRestorer } from '@theia/core/lib/browser/shell/shell-layout-restorer'; +import { inject } from '@theia/core/shared/inversify'; +import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell'; @injectable() export class ShellLayoutRestorer extends TheiaShellLayoutRestorer { + @inject(ApplicationShell) + protected readonly shell: ApplicationShell; + // Workaround for https://github.com/eclipse-theia/theia/issues/6579. - async storeLayoutAsync(app: FrontendApplication): Promise { + async storeLayoutAsync(): Promise { if (this.shouldStoreLayout) { try { this.logger.info('>>> Storing the layout...'); - const layoutData = app.shell.getLayoutData(); + const layoutData = this.shell.getLayoutData(); const serializedLayoutData = this.deflate(layoutData); await this.storageService.setData( this.storageKey, @@ -23,7 +27,7 @@ export class ShellLayoutRestorer extends TheiaShellLayoutRestorer { } } - async restoreLayout(app: FrontendApplication): Promise { + async restoreLayout(): Promise { this.logger.info('>>> Restoring the layout state...'); const serializedLayoutData = await this.storageService.getData( this.storageKey @@ -49,7 +53,7 @@ export class ShellLayoutRestorer extends TheiaShellLayoutRestorer { }); } - await app.shell.setLayoutData(layoutData); + await this.shell.setLayoutData(layoutData); this.logger.info('<<< The layout has been successfully restored.'); return true; } diff --git a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts index f8e360650..34abfacb7 100644 --- a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts +++ b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts @@ -32,4 +32,8 @@ export namespace SketchbookCommands { id: 'arduino-sketchbook--show-files', label: 'Contextual menu', }; + + export const SKETCHBOOK_TOGGLE_VIEW: Command = { + id: 'arduino-sketchbook-widget:toggle', + }; } diff --git a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts index a60be2bfa..571dd49fa 100644 --- a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts +++ b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts @@ -68,13 +68,13 @@ export class SketchbookWidgetContribution constructor() { super({ - widgetId: 'arduino-sketchbook-widget', + widgetId: SketchbookWidget.ID, widgetName: SketchbookWidget.LABEL, defaultWidgetOptions: { area: 'left', rank: 1, }, - toggleCommandId: 'arduino-sketchbook-widget:toggle', + toggleCommandId: SketchbookCommands.SKETCHBOOK_TOGGLE_VIEW.id, toggleKeybinding: 'CtrlCmd+Shift+B', }); } @@ -191,7 +191,7 @@ export class SketchbookWidgetContribution // unregister main menu action registry.unregisterMenuAction({ - commandId: 'arduino-sketchbook-widget:toggle', + commandId: SketchbookCommands.SKETCHBOOK_TOGGLE_VIEW.id, }); registry.registerMenuAction(SKETCHBOOK__CONTEXT__MAIN_GROUP, { diff --git a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget.tsx b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget.tsx index 1d78aa4ec..930804fc0 100644 --- a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget.tsx +++ b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget.tsx @@ -11,6 +11,7 @@ import { nls } from '@theia/core/lib/common'; @injectable() export class SketchbookWidget extends BaseWidget { static LABEL = nls.localize('arduino/sketch/titleSketchbook', 'Sketchbook'); + static ID = 'arduino-sketchbook-widget'; @inject(SketchbookTreeWidget) protected readonly localSketchbookTreeWidget: SketchbookTreeWidget; @@ -19,7 +20,7 @@ export class SketchbookWidget extends BaseWidget { constructor() { super(); - this.id = 'arduino-sketchbook-widget'; + this.id = SketchbookWidget.ID; this.title.caption = SketchbookWidget.LABEL; this.title.label = SketchbookWidget.LABEL; this.title.iconClass = 'fa fa-arduino-folder'; From b701a0abe02215e0148ff0ba728d58ebfbe6be6f Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Thu, 17 Mar 2022 09:12:04 +0100 Subject: [PATCH 3/4] improve condition to recognise cloud sketch --- .../cloud-sketchbook/cloud-sketchbook-widget.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts index 43f6b4573..7a1446445 100644 --- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts +++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-widget.ts @@ -6,8 +6,11 @@ import { Message } from '@theia/core/shared/@phosphor/messaging'; import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import { SketchControl } from '../../contributions/sketch-control'; import { LocalCacheFsProvider } from '../../local-cache/local-cache-fs-provider'; -import { REMOTE_SKETCHBOOK_FOLDER } from '../../utils/constants'; - +import { + ARDUINO_CLOUD_FOLDER, + REMOTE_SKETCHBOOK_FOLDER, +} from '../../utils/constants'; +import * as path from 'path'; @injectable() export class CloudSketchbookWidget extends SketchbookWidget { @inject(CloudSketchbookCompositeWidget) @@ -47,7 +50,10 @@ export class CloudSketchbookWidget extends SketchbookWidget { async checkCloudEnabled(): Promise { const currentSketch = await this.sketchesServiceClient.currentSketch(); const isCloudSketch = - currentSketch && currentSketch.uri.includes(REMOTE_SKETCHBOOK_FOLDER); + currentSketch && + currentSketch.uri.includes( + path.join(REMOTE_SKETCHBOOK_FOLDER, ARDUINO_CLOUD_FOLDER) + ); if (this.arduinoPreferences['arduino.cloud.enabled']) { this.sketchbookTreesContainer.mode = 'multiple-document'; From 5bd55fa523ef31fbbcf9d20fd14741ca564931bb Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 17 Jun 2022 17:13:00 +0200 Subject: [PATCH 4/4] open the sketchbook sidebar only when it was previously open --- .../src/browser/theia/core/application-shell.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arduino-ide-extension/src/browser/theia/core/application-shell.ts b/arduino-ide-extension/src/browser/theia/core/application-shell.ts index 5afdafad2..bfba5dff2 100644 --- a/arduino-ide-extension/src/browser/theia/core/application-shell.ts +++ b/arduino-ide-extension/src/browser/theia/core/application-shell.ts @@ -40,12 +40,13 @@ export class ApplicationShell extends TheiaApplicationShell { override async setLayoutData( layoutData: TheiaApplicationShell.LayoutData ): Promise { - layoutData.activeWidgetId = SketchbookWidget.ID; - layoutData.leftPanel?.items?.forEach((item) => { - if (item?.widget?.id === SketchbookWidget.ID) item.expanded = true; - else item.expanded = false; - }); - + if (typeof layoutData.activeWidgetId !== 'undefined') { + layoutData.activeWidgetId = SketchbookWidget.ID; + layoutData.leftPanel?.items?.forEach((item) => { + if (item?.widget?.id === SketchbookWidget.ID) item.expanded = true; + else item.expanded = false; + }); + } super.setLayoutData(layoutData); }