From 35359edc100815f7039f3cd4c6dee00311bb6f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 11 Aug 2020 16:46:06 +0200 Subject: [PATCH] scm: repositories visibility --- .../contrib/scm/browser/scmViewPane.ts | 44 ++++++++++++++----- .../contrib/scm/browser/scmViewService.ts | 25 +++++++++++ src/vs/workbench/contrib/scm/browser/util.ts | 27 +++++++++++- src/vs/workbench/contrib/scm/common/scm.ts | 4 ++ 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 1f46c0e6c23..1b621fc32bb 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -23,7 +23,7 @@ import { MenuItemAction, IMenuService } from 'vs/platform/actions/common/actions import { IAction, IActionViewItem, ActionRunner, Action, RadioGroup, Separator, SubmenuAction, IActionViewItemProvider } from 'vs/base/common/actions'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { IThemeService, LIGHT, registerThemingParticipant, IFileIconTheme } from 'vs/platform/theme/common/themeService'; -import { isSCMResource, isSCMResourceGroup, connectPrimaryMenuToInlineActionBar, isSCMRepository, isSCMInput, collectContextMenuActions, StatusBarAction, StatusBarActionViewItem } from './util'; +import { isSCMResource, isSCMResourceGroup, connectPrimaryMenuToInlineActionBar, isSCMRepository, isSCMInput, collectContextMenuActions, StatusBarAction, StatusBarActionViewItem, getRepositoryVisibilityActions } from './util'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; import { WorkbenchCompressibleObjectTree, IOpenEvent } from 'vs/platform/list/browser/listService'; import { IConfigurationService, ConfigurationTarget, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; @@ -750,6 +750,7 @@ class ViewModel { private inputRenderer: InputRenderer, private _mode: ViewModelMode, private _sortKey: ViewModelSortKey, + @IInstantiationService protected instantiationService: IInstantiationService, @IEditorService protected editorService: IEditorService, @IConfigurationService protected configurationService: IConfigurationService, @ISCMViewService private scmViewService: ISCMViewService @@ -1003,7 +1004,7 @@ class ViewModel { } if (!this.viewSubMenuAction) { - this.viewSubMenuAction = new SCMViewSubMenuAction(this); + this.viewSubMenuAction = this.instantiationService.createInstance(SCMViewSubMenuAction, this); this.disposables.add(this.viewSubMenuAction); } @@ -1073,25 +1074,43 @@ class ViewModel { } } -class SCMViewSubMenuAction extends SubmenuAction { +class SCMViewRepositoriesSubMenuAction extends SubmenuAction { - readonly actions!: IAction[]; + get actions(): IAction[] { + return getRepositoryVisibilityActions(this.scmService, this.scmViewService); + } - constructor(viewModel: ViewModel) { + constructor( + @ISCMService private readonly scmService: ISCMService, + @ISCMViewService private readonly scmViewService: ISCMViewService, + ) { + super('scm.repositories', localize('repositories', "Repositories"), []); + } +} + +class SCMViewSubMenuAction extends SubmenuAction { + + constructor( + viewModel: ViewModel, + @IInstantiationService instantiationService: IInstantiationService + ) { const listAction = new SCMViewModeListAction(viewModel); const treeAction = new SCMViewModeTreeAction(viewModel); const sortByNameAction = new SCMSortByNameAction(viewModel); const sortByPathAction = new SCMSortByPathAction(viewModel); const sortByStatusAction = new SCMSortByStatusAction(viewModel); + const actions = [ + instantiationService.createInstance(SCMViewRepositoriesSubMenuAction), + new Separator(), + ...new RadioGroup([listAction, treeAction]).actions, + new Separator(), + ...new RadioGroup([sortByNameAction, sortByPathAction, sortByStatusAction]).actions + ]; super( 'scm.viewsort', localize('sortAction', "View & Sort"), - [ - ...new RadioGroup([listAction, treeAction]).actions, - new Separator(), - ...new RadioGroup([sortByNameAction, sortByPathAction, sortByStatusAction]).actions - ] + actions ); this._register(combinedDisposable(listAction, treeAction, sortByNameAction, sortByPathAction, sortByStatusAction)); @@ -1771,7 +1790,10 @@ export class SCMViewPane extends ViewPane { private onListContextMenu(e: ITreeContextMenuEvent): void { if (!e.element) { - return; + return this.contextMenuService.showContextMenu({ + getAnchor: () => e.anchor, + getActions: () => getRepositoryVisibilityActions(this.scmService, this.scmViewService) + }); } const element = e.element; diff --git a/src/vs/workbench/contrib/scm/browser/scmViewService.ts b/src/vs/workbench/contrib/scm/browser/scmViewService.ts index c9a1ac2154b..1f2609eb975 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewService.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewService.ts @@ -111,6 +111,31 @@ export class SCMViewService implements ISCMViewService { } } + isVisible(repository: ISCMRepository): boolean { + return this._visibleRepositoriesSet.has(repository); + } + + toggleVisibility(repository: ISCMRepository, visible?: boolean): void { + if (typeof visible === 'undefined') { + visible = !this.isVisible(repository); + } else if (this.isVisible(repository) === visible) { + return; + } + + if (visible) { + this.visibleRepositories = [...this.visibleRepositories, repository]; + } else { + const index = this.visibleRepositories.indexOf(repository); + + if (index > -1) { + this.visibleRepositories = [ + ...this.visibleRepositories.slice(0, index), + ...this.visibleRepositories.slice(index + 1) + ]; + } + } + } + dispose(): void { this.disposables.dispose(); this._onDidChangeRepositories.dispose(); diff --git a/src/vs/workbench/contrib/scm/browser/util.ts b/src/vs/workbench/contrib/scm/browser/util.ts index 228614a12d1..d8b489c5fce 100644 --- a/src/vs/workbench/contrib/scm/browser/util.ts +++ b/src/vs/workbench/contrib/scm/browser/util.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ISCMResource, ISCMRepository, ISCMResourceGroup, ISCMInput } from 'vs/workbench/contrib/scm/common/scm'; +import { ISCMResource, ISCMRepository, ISCMResourceGroup, ISCMInput, ISCMService, ISCMViewService } from 'vs/workbench/contrib/scm/common/scm'; import { IMenu } from 'vs/platform/actions/common/actions'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { IDisposable, Disposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle'; @@ -16,6 +16,8 @@ import { renderCodicons } from 'vs/base/common/codicons'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { Command } from 'vs/editor/common/modes'; import { escape } from 'vs/base/common/strings'; +import { basename } from 'vs/base/common/resources'; +import { Iterable } from 'vs/base/common/iterator'; export function isSCMRepository(element: any): element is ISCMRepository { return !!(element as ISCMRepository).provider && typeof (element as ISCMRepository).setSelected === 'function'; @@ -107,3 +109,26 @@ export class StatusBarActionViewItem extends ActionViewItem { } } } + +export function getRepositoryVisibilityActions(scmService: ISCMService, scmViewService: ISCMViewService): IAction[] { + const visible = new Set(); + const actions = scmService.repositories.map(repository => { + const label = repository.provider.rootUri ? basename(repository.provider.rootUri) : repository.provider.label; + const action = new Action('scm.repository.toggleVisibility', label, undefined, true, async () => { + scmViewService.toggleVisibility(repository); + }); + + if (scmViewService.isVisible(repository)) { + action.checked = true; + visible.add(action); + } + + return action; + }); + + if (visible.size === 1) { + Iterable.first(visible.values())!.enabled = false; + } + + return actions; +} diff --git a/src/vs/workbench/contrib/scm/common/scm.ts b/src/vs/workbench/contrib/scm/common/scm.ts index d3ebc93d9f7..aa3f57f7849 100644 --- a/src/vs/workbench/contrib/scm/common/scm.ts +++ b/src/vs/workbench/contrib/scm/common/scm.ts @@ -148,6 +148,10 @@ export interface ISCMViewService { readonly _serviceBrand: undefined; readonly menus: ISCMMenus; + visibleRepositories: ISCMRepository[]; readonly onDidChangeVisibleRepositories: Event; + + isVisible(repository: ISCMRepository): boolean; + toggleVisibility(repository: ISCMRepository, visible?: boolean): void; } -- GitLab