diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index f996bfa7c48..9f651b6eee2 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -15,7 +15,7 @@ import { disposeIfDisposable } from 'vs/base/common/lifecycle'; import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, IExtensionContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID, SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID, THEME_ACTIONS_GROUP, INSTALL_ACTIONS_GROUP } from 'vs/workbench/contrib/extensions/common/extensions'; import { ExtensionsConfigurationInitialContent } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate'; import { IGalleryExtension, IExtensionGalleryService, ILocalExtension, InstallOptions, InstallOperation, TargetPlatformToString, ExtensionManagementErrorCode } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionRecommendationReason, IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; import { areSameExtensions, getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension, getWorkspaceSupportTypeMessage, TargetPlatform } from 'vs/platform/extensions/common/extensions'; @@ -51,7 +51,7 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/ import { IActionViewItemOptions, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { EXTENSIONS_CONFIG, IExtensionsConfigContent } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig'; import { getErrorMessage, isCancellationError } from 'vs/base/common/errors'; -import { IUserDataSyncEnablementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; import { ActionWithDropdownActionViewItem, IActionWithDropdownActionViewItemOptions } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem'; import { IContextMenuProvider } from 'vs/base/browser/contextmenu'; import { ILogService } from 'vs/platform/log/common/log'; @@ -128,7 +128,7 @@ export class PromptExtensionInstallFailureAction extends Action { buttons: [{ label: localize('install anyway', "Install Anyway"), run: () => { - const installAction = this.installOptions?.isMachineScoped ? this.instantiationService.createInstance(InstallAction, { donotVerifySignature: true }) : this.instantiationService.createInstance(InstallAndSyncAction, { donotVerifySignature: true }); + const installAction = this.instantiationService.createInstance(InstallAction, { donotVerifySignature: true }); installAction.extension = this.extension; return installAction.run(); } @@ -149,7 +149,7 @@ export class PromptExtensionInstallFailureAction extends Action { promptChoices.push({ label: localize('install release version', "Install Release Version"), run: () => { - const installAction = this.installOptions?.isMachineScoped ? this.instantiationService.createInstance(InstallAction, { installPreReleaseVersion: !!this.installOptions.installPreReleaseVersion }) : this.instantiationService.createInstance(InstallAndSyncAction, { installPreReleaseVersion: !!this.installOptions?.installPreReleaseVersion }); + const installAction = this.instantiationService.createInstance(InstallAction, { installPreReleaseVersion: !!this.installOptions?.installPreReleaseVersion }); installAction.extension = this.extension; return installAction.run(); } @@ -295,7 +295,7 @@ export class ActionWithDropDownAction extends ExtensionAction { } } -export abstract class AbstractInstallAction extends ExtensionAction { +export class InstallAction extends ExtensionAction { static readonly Class = `${ExtensionAction.LABEL_ACTION_CLASS} prominent install`; @@ -306,9 +306,10 @@ export abstract class AbstractInstallAction extends ExtensionAction { } private readonly updateThrottler = new Throttler(); + public readonly options: InstallOptions; constructor( - id: string, readonly options: InstallOptions, cssClass: string, + options: InstallOptions, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IExtensionService private readonly runtimeExtensionService: IExtensionService, @@ -318,7 +319,8 @@ export abstract class AbstractInstallAction extends ExtensionAction { @IPreferencesService private readonly preferencesService: IPreferencesService, @ITelemetryService private readonly telemetryService: ITelemetryService, ) { - super(id, localize('install', "Install"), cssClass, false); + super('extensions.install', localize('install', "Install"), InstallAction.Class, false); + this.options = { ...options, isMachineScoped: false }; this.update(); this._register(this.labelService.onDidChangeFormatters(() => this.updateLabel(), this)); } @@ -464,11 +466,10 @@ export abstract class AbstractInstallAction extends ExtensionAction { } private async install(extension: IExtension): Promise { - const installOptions = this.getInstallOptions(); try { - return await this.extensionsWorkbenchService.install(extension, installOptions); + return await this.extensionsWorkbenchService.install(extension, this.options); } catch (error) { - await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, installOptions, error).run(); + await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, this.options, error).run(); return undefined; } } @@ -508,117 +509,12 @@ export abstract class AbstractInstallAction extends ExtensionAction { return localize('install', "Install"); } - protected getInstallOptions(): InstallOptions { - return this.options; - } -} - -export class InstallAction extends AbstractInstallAction { - - constructor( - options: InstallOptions, - @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, - @IInstantiationService instantiationService: IInstantiationService, - @IExtensionService runtimeExtensionService: IExtensionService, - @IWorkbenchThemeService workbenchThemeService: IWorkbenchThemeService, - @ILabelService labelService: ILabelService, - @IDialogService dialogService: IDialogService, - @IPreferencesService preferencesService: IPreferencesService, - @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, - @IWorkbenchExtensionManagementService private readonly workbenchExtensionManagementService: IWorkbenchExtensionManagementService, - @IUserDataSyncEnablementService protected readonly userDataSyncEnablementService: IUserDataSyncEnablementService, - @ITelemetryService telemetryService: ITelemetryService, - ) { - super(`extensions.install`, options, InstallAction.Class, - extensionsWorkbenchService, instantiationService, runtimeExtensionService, workbenchThemeService, labelService, dialogService, preferencesService, telemetryService); - this.updateLabel(); - this._register(labelService.onDidChangeFormatters(() => this.updateLabel(), this)); - this._register(Event.any(userDataSyncEnablementService.onDidChangeEnablement, - Event.filter(userDataSyncEnablementService.onDidChangeResourceEnablement, e => e[0] === SyncResource.Extensions))(() => this.update())); - } - - override getLabel(primary?: boolean): string { - const baseLabel = super.getLabel(primary); - - const donotSyncLabel = localize('do no sync', "Do not sync"); - const isMachineScoped = this.getInstallOptions().isMachineScoped; - - // When remote connection exists - if (this._manifest && this.extensionManagementServerService.remoteExtensionManagementServer) { - - const server = this.workbenchExtensionManagementService.getExtensionManagementServerToInstall(this._manifest); - - if (server === this.extensionManagementServerService.remoteExtensionManagementServer) { - const host = this.extensionManagementServerService.remoteExtensionManagementServer.label; - return isMachineScoped - ? localize({ - key: 'install extension in remote and do not sync', - comment: [ - 'First placeholder is install action label.', - 'Second placeholder is the name of the action to install an extension in remote server and do not sync it. Placeholder is for the name of remote server.', - 'Third placeholder is do not sync label.', - ] - }, "{0} in {1} ({2})", baseLabel, host, donotSyncLabel) - : localize({ - key: 'install extension in remote', - comment: [ - 'First placeholder is install action label.', - 'Second placeholder is the name of the action to install an extension in remote server and do not sync it. Placeholder is for the name of remote server.', - ] - }, "{0} in {1}", baseLabel, host); - } - - return isMachineScoped ? - localize('install extension locally and do not sync', "{0} Locally ({1})", baseLabel, donotSyncLabel) : localize('install extension locally', "{0} Locally", baseLabel); - } - - return isMachineScoped ? `${baseLabel} (${donotSyncLabel})` : baseLabel; - } - - protected override getInstallOptions(): InstallOptions { - return { ...super.getInstallOptions(), isMachineScoped: this.userDataSyncEnablementService.isEnabled() && this.userDataSyncEnablementService.isResourceEnabled(SyncResource.Extensions) }; - } - -} - -export class InstallAndSyncAction extends AbstractInstallAction { - - constructor( - options: InstallOptions, - @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, - @IInstantiationService instantiationService: IInstantiationService, - @IExtensionService runtimeExtensionService: IExtensionService, - @IWorkbenchThemeService workbenchThemeService: IWorkbenchThemeService, - @ILabelService labelService: ILabelService, - @IDialogService dialogService: IDialogService, - @IPreferencesService preferencesService: IPreferencesService, - @IProductService productService: IProductService, - @IUserDataSyncEnablementService private readonly userDataSyncEnablementService: IUserDataSyncEnablementService, - @ITelemetryService telemetryService: ITelemetryService, - ) { - super('extensions.installAndSync', options, AbstractInstallAction.Class, - extensionsWorkbenchService, instantiationService, runtimeExtensionService, workbenchThemeService, labelService, dialogService, preferencesService, telemetryService); - this.tooltip = localize({ key: 'install everywhere tooltip', comment: ['Placeholder is the name of the product. Eg: Visual Studio Code or Visual Studio Code - Insiders'] }, "Install this extension in all your synced {0} instances", productService.nameLong); - this._register(Event.any(userDataSyncEnablementService.onDidChangeEnablement, - Event.filter(userDataSyncEnablementService.onDidChangeResourceEnablement, e => e[0] === SyncResource.Extensions))(() => this.update())); - } - - protected override async computeAndUpdateEnablement(): Promise { - await super.computeAndUpdateEnablement(); - if (this.enabled) { - this.enabled = this.userDataSyncEnablementService.isEnabled() && this.userDataSyncEnablementService.isResourceEnabled(SyncResource.Extensions); - } - } - - protected override getInstallOptions(): InstallOptions { - return { ...super.getInstallOptions(), isMachineScoped: false }; - } } export class InstallDropdownAction extends ActionWithDropDownAction { set manifest(manifest: IExtensionManifest | null) { - this.extensionActions.forEach(a => (a).manifest = manifest); + this.extensionActions.forEach(a => (a).manifest = manifest); this.update(); } @@ -627,10 +523,6 @@ export class InstallDropdownAction extends ActionWithDropDownAction { @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, ) { super(`extensions.installActions`, '', [ - [ - instantiationService.createInstance(InstallAndSyncAction, { installPreReleaseVersion: extensionsWorkbenchService.preferPreReleases }), - instantiationService.createInstance(InstallAndSyncAction, { installPreReleaseVersion: !extensionsWorkbenchService.preferPreReleases }), - ], [ instantiationService.createInstance(InstallAction, { installPreReleaseVersion: extensionsWorkbenchService.preferPreReleases }), instantiationService.createInstance(InstallAction, { installPreReleaseVersion: !extensionsWorkbenchService.preferPreReleases }), @@ -638,7 +530,7 @@ export class InstallDropdownAction extends ActionWithDropDownAction { ]); } - protected override getLabel(action: AbstractInstallAction): string { + protected override getLabel(action: InstallAction): string { return action.getLabel(true); }