From b9833bb962d9831b329323967a7b86a55c7d08fa Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 3 Nov 2020 17:47:06 +0100 Subject: [PATCH] Fix #99105 --- .../extensions/browser/extensionEditor.ts | 7 ++-- .../extensions/browser/extensionsActions.ts | 33 +++++++++++++------ .../extensions/browser/extensionsList.ts | 11 ++++--- .../extensions/browser/extensionsWidgets.ts | 28 ++++++++++++++++ .../extensions/browser/media/extension.css | 9 +++++ .../browser/media/extensionActions.css | 1 + .../browser/media/extensionsWidgets.css | 4 +++ 7 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 16dac4771f3..f9bef7343d0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -27,7 +27,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { UpdateAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction, SyncIgnoredIconAction, SetProductIconThemeAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { UpdateAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction, ToggleSyncExtensionAction, SetProductIconThemeAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener'; @@ -251,6 +251,9 @@ export class ExtensionEditor extends EditorPane { const extensionActionBar = this._register(new ActionBar(extensionActions, { animated: false, actionViewItemProvider: (action: IAction) => { + if (action instanceof ExtensionDropDownAction) { + return action.createActionViewItem(); + } if (action instanceof ActionWithDropDownAction) { return new ExtensionActionWithDropdownActionViewItem(action, { icon: true, label: true, menuActionsOrProvider: { getActions: () => action.menuActions }, menuActionClassNames: (action.class || '').split(' ') }, this.contextMenuService); } @@ -404,8 +407,8 @@ export class ExtensionEditor extends EditorPane { const combinedInstallAction = this.instantiationService.createInstance(InstallDropdownAction); const systemDisabledWarningAction = this.instantiationService.createInstance(SystemDisabledWarningAction); const actions = [ + this.instantiationService.createInstance(ToggleSyncExtensionAction), reloadAction, - this.instantiationService.createInstance(SyncIgnoredIconAction), this.instantiationService.createInstance(StatusLabelAction), this.instantiationService.createInstance(UpdateAction), this.instantiationService.createInstance(SetColorThemeAction, await this.workbenchThemeService.getColorThemes()), diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 5999f04f608..39670f542d7 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -2776,30 +2776,43 @@ export class MaliciousStatusLabelAction extends ExtensionAction { } } -export class SyncIgnoredIconAction extends ExtensionAction { +export class ToggleSyncExtensionAction extends ExtensionDropDownAction { - private static readonly ENABLE_CLASS = `${ExtensionAction.ICON_ACTION_CLASS} codicon-sync-ignored`; - private static readonly DISABLE_CLASS = `${SyncIgnoredIconAction.ENABLE_CLASS} hide`; + private static readonly IGNORED_SYNC_CLASS = `${ExtensionAction.ICON_ACTION_CLASS} extension-sync codicon-sync-ignored`; + private static readonly SYNC_CLASS = `${ToggleSyncExtensionAction.ICON_ACTION_CLASS} extension-sync codicon-sync`; constructor( @IConfigurationService private readonly configurationService: IConfigurationService, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, + @IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService, + @IInstantiationService instantiationService: IInstantiationService, ) { - super('extensions.syncignore', '', SyncIgnoredIconAction.DISABLE_CLASS, false); + super('extensions.sync', '', ToggleSyncExtensionAction.SYNC_CLASS, false, true, instantiationService); this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectedKeys.includes('settingsSync.ignoredExtensions'))(() => this.update())); + this._register(userDataAutoSyncEnablementService.onDidChangeEnablement(() => this.update())); this.update(); - this.tooltip = localize('syncingore.label', "This extension is ignored during sync."); } update(): void { - this.class = SyncIgnoredIconAction.DISABLE_CLASS; - if (this.extension && this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension)) { - this.class = SyncIgnoredIconAction.ENABLE_CLASS; + this.enabled = !!this.extension && this.userDataAutoSyncEnablementService.isEnabled(); + if (this.extension) { + const isIgnored = this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension); + this.class = isIgnored ? ToggleSyncExtensionAction.IGNORED_SYNC_CLASS : ToggleSyncExtensionAction.SYNC_CLASS; + this.tooltip = isIgnored ? localize('ignored', "This extension is ignored during sync") : localize('synced', "This extension is synced"); } } - run(): Promise { - return Promise.resolve(); + async run(): Promise { + return super.run({ + actionGroups: [ + [ + new Action( + 'extensions.syncignore', + this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension!) ? localize('sync', "Sync this extension") : localize('do not sync', "Do not sync this extension") + , undefined, true, () => this.extensionsWorkbenchService.toggleExtensionIgnoredToSync(this.extension!)) + ] + ], disposeActionsOnHide: true + }); } } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index f1aede07b33..eaed6accef3 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -14,9 +14,9 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { Event } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, SyncIgnoredIconAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; +import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -81,6 +81,7 @@ export class Renderer implements IPagedRenderer { const version = append(header, $('span.version')); const installCount = append(header, $('span.install-count')); const ratings = append(header, $('span.ratings')); + const syncIgnore = append(header, $('span.sync-ignored')); const headerRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, header, false); const description = append(details, $('.description.ellipsis')); const footer = append(details, $('.footer')); @@ -91,8 +92,8 @@ export class Renderer implements IPagedRenderer { if (action instanceof ActionWithDropDownAction) { return new ExtensionActionWithDropdownActionViewItem(action, { icon: true, label: true, menuActionsOrProvider: { getActions: () => action.menuActions }, menuActionClassNames: (action.class || '').split(' ') }, this.contextMenuService); } - if (action.id === ManageExtensionAction.ID) { - return (action).createActionViewItem(); + if (action instanceof ExtensionDropDownAction) { + return action.createActionViewItem(); } return new ExtensionActionViewItem(null, action, actionOptions); } @@ -103,7 +104,6 @@ export class Renderer implements IPagedRenderer { const reloadAction = this.instantiationService.createInstance(ReloadAction); const actions = [ this.instantiationService.createInstance(StatusLabelAction), - this.instantiationService.createInstance(SyncIgnoredIconAction), this.instantiationService.createInstance(UpdateAction), reloadAction, this.instantiationService.createInstance(InstallDropdownAction), @@ -123,6 +123,7 @@ export class Renderer implements IPagedRenderer { headerRemoteBadgeWidget, tooltipWidget, this.instantiationService.createInstance(Label, version, (e: IExtension) => e.version), + this.instantiationService.createInstance(SyncIgnoredWidget, syncIgnore), this.instantiationService.createInstance(InstallCountWidget, installCount, true), this.instantiationService.createInstance(RatingsWidget, ratings, true) ]; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts index 8718d0b9b03..27b0c366c5b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts @@ -18,6 +18,8 @@ import { EXTENSION_BADGE_REMOTE_BACKGROUND, EXTENSION_BADGE_REMOTE_FOREGROUND } import { Emitter, Event } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IUserDataAutoSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; export abstract class ExtensionWidget extends Disposable implements IExtensionContainer { private _extension: IExtension | null = null; @@ -340,3 +342,29 @@ export class ExtensionPackCountWidget extends ExtensionWidget { countBadge.setCount(this.extension.extensionPack.length); } } + +export class SyncIgnoredWidget extends ExtensionWidget { + + private element: HTMLElement; + + constructor( + container: HTMLElement, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, + @IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService, + ) { + super(); + this.element = append(container, $('span.extension-sync-ignored.codicon.codicon-sync-ignored')); + this.element.title = localize('syncingore.label', "This extension is ignored during sync."); + this.element.classList.add('codicon'); + this.element.classList.add('codicon-sync-ignored'); + this.element.classList.add('hide'); + this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectedKeys.includes('settingsSync.ignoredExtensions'))(() => this.render())); + this._register(userDataAutoSyncEnablementService.onDidChangeEnablement(() => this.update())); + this.render(); + } + + render(): void { + this.element.classList.toggle('hide', !(this.extension && this.userDataAutoSyncEnablementService.isEnabled() && this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension))); + } +} diff --git a/src/vs/workbench/contrib/extensions/browser/media/extension.css b/src/vs/workbench/contrib/extensions/browser/media/extension.css index 1911ed1d4fa..0502ce085e5 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extension.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extension.css @@ -139,6 +139,15 @@ color: currentColor; } +.extension-list-item > .details > .header-container > .header .sync-ignored { + display: flex; + margin-left: 6px; +} + +.extension-list-item > .details > .header-container > .header .sync-ignored > .codicon { + font-size: 100%; +} + .extension-list-item > .details > .description { padding-right: 11px; } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css b/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css index 2ed84ded8e9..bb1107d06f9 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css @@ -45,6 +45,7 @@ .monaco-action-bar .action-item.disabled .action-label.extension-action.uninstall:not(.uninstalling), .monaco-action-bar .action-item.disabled .action-label.extension-action.update, .monaco-action-bar .action-item.disabled .action-label.extension-action.theme, +.monaco-action-bar .action-item.disabled .action-label.extension-action.extension-sync, .monaco-action-bar .action-item.action-dropdown-item.disabled, .monaco-action-bar .action-item.action-dropdown-item .action-label.extension-action.hide, .monaco-action-bar .action-item.disabled .action-label.extension-action.reload, diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css index 91cf3cefd91..01e247b05a4 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css @@ -3,6 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +.extension-sync-ignored.hide { + display: none; +} + .extension-ratings { display: inline-block; } -- GitLab