From 7077303a36e04a508d39b6dcd4671f8f9c90aad0 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Thu, 14 Nov 2019 10:23:57 +0100 Subject: [PATCH] Hid the Explorer. Disabled new folder in workspace when not in `pro-mode`. Closes arduino/arduino-pro-ide#84. Signed-off-by: Akos Kitta --- .../browser/arduino-frontend-contribution.tsx | 42 ++++++++++++------- .../src/browser/arduino-frontend-module.ts | 6 +-- .../src/browser/arduino-workspace-service.ts | 9 ++-- .../arduino-frontend-application.ts | 4 +- .../silent-navigator-contribution.ts | 9 +++- .../src/common/protocol/sketches-service.ts | 7 ++-- 6 files changed, 48 insertions(+), 29 deletions(-) diff --git a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx index 93d8df0e..7db3661f 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx +++ b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx @@ -53,6 +53,7 @@ import { OutlineViewContribution } from '@theia/outline-view/lib/browser/outline import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution'; import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution'; import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution'; +import { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution'; export namespace ArduinoMenus { export const SKETCH = [...MAIN_MENU_BAR, '3_sketch']; @@ -66,11 +67,11 @@ export namespace ArduinoToolbarContextMenu { export const EXAMPLE_SKETCHES_GROUP: MenuPath = [...OPEN_SKETCH_PATH, '3_examples']; } -export namespace ArduinoAdvancedMode { - export const LS_ID = 'arduino-advanced-mode'; - export const TOGGLED: boolean = (() => { - const advancedModeStr = window.localStorage.getItem(LS_ID); - return advancedModeStr === 'true'; +export namespace EditorMode { + export const PRO_MODE_KEY = 'arduino-advanced-mode'; + export const IN_PRO_MODE: boolean = (() => { + const value = window.localStorage.getItem(PRO_MODE_KEY); + return value === 'true'; })(); } @@ -135,7 +136,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut protected readonly menuRegistry: MenuModelRegistry; @inject(CommandRegistry) - protected readonly commands: CommandRegistry; + protected readonly commandRegistry: CommandRegistry; @inject(StatusBar) protected readonly statusBar: StatusBar; @@ -181,6 +182,13 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut // This is a hack. Otherwise, the backend services won't bind. await this.workspaceServiceExt.roots(); + if (!EditorMode.IN_PRO_MODE) { + const { ADD_FOLDER, REMOVE_FOLDER, SAVE_WORKSPACE_AS } = WorkspaceCommands; + for (const command of [ADD_FOLDER, REMOVE_FOLDER, SAVE_WORKSPACE_AS]) { + this.commandRegistry.unregisterCommand(command); + } + } + const updateStatusBar = (config: BoardsConfig.Config) => { this.statusBar.setElement('arduino-selected-board', { alignment: StatusBarAlignment.RIGHT, @@ -239,7 +247,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut id: BoardsToolBarItem.TOOLBAR_ID, render: () => , isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left' @@ -255,7 +263,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut id: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, command: ArduinoCommands.TOGGLE_ADVANCED_MODE.id, tooltip: 'Toggle Advanced Mode', - text: (ArduinoAdvancedMode.TOGGLED ? '$(toggle-on)' : '$(toggle-off)'), + text: (EditorMode.IN_PRO_MODE ? '$(toggle-on)' : '$(toggle-off)'), isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right' }); } @@ -338,7 +346,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }); } } else { - this.commands.executeCommand(ArduinoCommands.OPEN_FILE_NAVIGATOR.id); + this.commandRegistry.executeCommand(ArduinoCommands.OPEN_FILE_NAVIGATOR.id); } } }); @@ -385,9 +393,9 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut }) registry.registerCommand(ArduinoCommands.TOGGLE_ADVANCED_MODE, { execute: async () => { - const oldState = ArduinoAdvancedMode.TOGGLED; + const oldState = EditorMode.IN_PRO_MODE; const inAdvancedMode = !oldState; - window.localStorage.setItem(ArduinoAdvancedMode.LS_ID, String(inAdvancedMode)); + window.localStorage.setItem(EditorMode.PRO_MODE_KEY, String(inAdvancedMode)); if (!inAdvancedMode) { // Close all widget that is neither editor nor `Output`. for (const area of ['left', 'right', 'bottom', 'main'] as Array) { @@ -401,12 +409,12 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut window.location.reload(true); }, isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'right', - isToggled: () => ArduinoAdvancedMode.TOGGLED + isToggled: () => EditorMode.IN_PRO_MODE }) } registerMenus(registry: MenuModelRegistry) { - if (!ArduinoAdvancedMode.TOGGLED) { + if (!EditorMode.IN_PRO_MODE) { // If are not in pro-mode, we have to disable the context menu for the tabs. // Such as `Close`, `Close All`, etc. for (const command of [ @@ -415,7 +423,9 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut CommonCommands.CLOSE_RIGHT_TABS, CommonCommands.CLOSE_ALL_TABS, CommonCommands.COLLAPSE_PANEL, - CommonCommands.TOGGLE_MAXIMIZED + CommonCommands.TOGGLE_MAXIMIZED, + FileNavigatorCommands.REVEAL_IN_NAVIGATOR + ]) { registry.unregisterMenuAction(command); } @@ -478,8 +488,8 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut const command: Command = { id: 'openSketch' + sketch.name } - this.commands.registerCommand(command, { - execute: () => this.commands.executeCommand(ArduinoCommands.OPEN_SKETCH.id, sketch) + this.commandRegistry.registerCommand(command, { + execute: () => this.commandRegistry.executeCommand(ArduinoCommands.OPEN_SKETCH.id, sketch) }); registry.registerMenuAction(ArduinoToolbarContextMenu.WS_SKETCHES_GROUP, { diff --git a/arduino-ide-extension/src/browser/arduino-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-frontend-module.ts index 08ac088f..e4b01449 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-frontend-module.ts @@ -10,7 +10,7 @@ import { LanguageGrammarDefinitionContribution } from '@theia/monaco/lib/browser import { LanguageClientContribution } from '@theia/languages/lib/browser'; import { ArduinoLanguageClientContribution } from './language/arduino-language-client-contribution'; import { LibraryListWidget } from './library/library-list-widget'; -import { ArduinoFrontendContribution, ArduinoAdvancedMode } from './arduino-frontend-contribution'; +import { ArduinoFrontendContribution, EditorMode } from './arduino-frontend-contribution'; import { ArduinoLanguageGrammarContribution } from './language/arduino-language-grammar-contribution'; import { LibraryService, LibraryServicePath } from '../common/protocol/library-service'; import { BoardsService, BoardsServicePath, BoardsServiceClient } from '../common/protocol/boards-service'; @@ -199,7 +199,7 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un themeService.register(...ArduinoTheme.themes); // Customizing default Theia layout - if (!ArduinoAdvancedMode.TOGGLED) { + if (!EditorMode.IN_PRO_MODE) { unbind(OutlineViewContribution); bind(OutlineViewContribution).to(SilentOutlineViewContribution).inSingletonScope(); unbind(ProblemContribution); @@ -220,7 +220,7 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un bind(SearchInWorkspaceFrontendContribution).to(SilentSearchInWorkspaceContribution).inSingletonScope(); } else { // We use this CSS class on the body to modify the visibility of the close button for the editors and views. - document.body.classList.add(ArduinoAdvancedMode.LS_ID); + document.body.classList.add(EditorMode.PRO_MODE_KEY); } unbind(FrontendApplication); bind(FrontendApplication).to(ArduinoFrontendApplication).inSingletonScope(); diff --git a/arduino-ide-extension/src/browser/arduino-workspace-service.ts b/arduino-ide-extension/src/browser/arduino-workspace-service.ts index 9b3a6f8d..e2823cc7 100644 --- a/arduino-ide-extension/src/browser/arduino-workspace-service.ts +++ b/arduino-ide-extension/src/browser/arduino-workspace-service.ts @@ -4,7 +4,7 @@ import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service import { ConfigService } from '../common/protocol/config-service'; import { SketchesService } from '../common/protocol/sketches-service'; import { ArduinoWorkspaceRootResolver } from './arduino-workspace-resolver'; -import { ArduinoAdvancedMode } from './arduino-frontend-contribution'; +import { EditorMode as EditorMode } from './arduino-frontend-contribution'; @injectable() export class ArduinoWorkspaceService extends WorkspaceService { @@ -18,7 +18,7 @@ export class ArduinoWorkspaceService extends WorkspaceService { @inject(LabelProvider) protected readonly labelProvider: LabelProvider; - async getDefaultWorkspacePath(): Promise { + async getDefaultWorkspaceUri(): Promise { const [hash, recentWorkspaces, recentSketches] = await Promise.all([ window.location.hash, this.sketchService.getSketches().then(sketches => sketches.map(({ uri }) => uri)), @@ -36,7 +36,8 @@ export class ArduinoWorkspaceService extends WorkspaceService { await this.server.setMostRecentlyUsedWorkspace(uri); return toOpen.uri; } - return (await this.sketchService.createNewSketch()).uri; + const { sketchDirUri } = (await this.configService.getConfiguration()); + return (await this.sketchService.createNewSketch(sketchDirUri)).uri; } private async isValid(uri: string): Promise { @@ -46,7 +47,7 @@ export class ArduinoWorkspaceService extends WorkspaceService { } // The workspace root location must exist. However, when opening a workspace root in pro-mode, // the workspace root must not be a sketch folder. It can be the default sketch directory, or any other directories, for instance. - if (!ArduinoAdvancedMode.TOGGLED) { + if (EditorMode.IN_PRO_MODE) { return true; } const sketchFolder = await this.sketchService.isSketchFolder(uri); diff --git a/arduino-ide-extension/src/browser/customization/arduino-frontend-application.ts b/arduino-ide-extension/src/browser/customization/arduino-frontend-application.ts index 600b4943..362e1e78 100644 --- a/arduino-ide-extension/src/browser/customization/arduino-frontend-application.ts +++ b/arduino-ide-extension/src/browser/customization/arduino-frontend-application.ts @@ -2,7 +2,7 @@ import { injectable, inject } from 'inversify'; import { FileSystem } from '@theia/filesystem/lib/common/filesystem'; import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service'; import { FrontendApplication } from '@theia/core/lib/browser/frontend-application'; -import { ArduinoFrontendContribution, ArduinoAdvancedMode } from '../arduino-frontend-contribution'; +import { ArduinoFrontendContribution, EditorMode } from '../arduino-frontend-contribution'; @injectable() export class ArduinoFrontendApplication extends FrontendApplication { @@ -21,7 +21,7 @@ export class ArduinoFrontendApplication extends FrontendApplication { // If not in PRO mode, we open the sketch file with all the related files. // Otherwise, we reuse the workbench's restore functionality and we do not open anything at all. // TODO: check `otherwise`. Also, what if we check for opened editors, instead of blindly opening them? - if (!ArduinoAdvancedMode.TOGGLED) { + if (!EditorMode.IN_PRO_MODE) { this.workspaceService.roots.then(roots => { for (const root of roots) { this.fileSystem.exists(root.uri).then(exists => { diff --git a/arduino-ide-extension/src/browser/customization/silent-navigator-contribution.ts b/arduino-ide-extension/src/browser/customization/silent-navigator-contribution.ts index 3b219691..24ca3bdf 100644 --- a/arduino-ide-extension/src/browser/customization/silent-navigator-contribution.ts +++ b/arduino-ide-extension/src/browser/customization/silent-navigator-contribution.ts @@ -1,10 +1,17 @@ -import { injectable } from 'inversify'; +import { injectable, postConstruct } from 'inversify'; import { FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution'; import { FrontendApplication } from '@theia/core/lib/browser'; @injectable() export class SilentNavigatorContribution extends FileNavigatorContribution { + @postConstruct() + protected async init(): Promise { + // @ts-ignore + delete this.toggleCommand; // The `Explorer` should not be accessible via command or keybinding. + return super.init(); + } + async initializeLayout(app: FrontendApplication): Promise { } diff --git a/arduino-ide-extension/src/common/protocol/sketches-service.ts b/arduino-ide-extension/src/common/protocol/sketches-service.ts index eeba1683..8c883abf 100644 --- a/arduino-ide-extension/src/common/protocol/sketches-service.ts +++ b/arduino-ide-extension/src/common/protocol/sketches-service.ts @@ -8,10 +8,11 @@ export interface SketchesService { getSketches(uri?: string): Promise getSketchFiles(uri: string): Promise /** - * Creates a new sketch folder in the `parentUri` location. If `parentUri` is not specified, - * it falls back to the default `sketchDirUri` from the CLI. + * Creates a new sketch folder in the `parentUri` location. + * Normally, `parentUri` is the client's workspace root, or the default `sketchDirUri` from the CLI. + * Note, `parentUri` and `sketchDirUri` can be the same. */ - createNewSketch(parentUri?: string): Promise + createNewSketch(parentUri: string): Promise isSketchFolder(uri: string): Promise }