提交 82ac9be2 编写于 作者: S Sandeep Somavarapu

Extensions: Introduce Reload action

上级 5a396424
......@@ -36,7 +36,7 @@ import { EditorOptions } from 'vs/workbench/common/editor';
import { shell } from 'electron';
import product from 'vs/platform/product';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction } from './extensionsActions';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, BuiltinStatusLabelAction } from './extensionsActions';
import WebView from 'vs/workbench/parts/html/browser/webview';
import { Keybinding } from 'vs/base/common/keybinding';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
......@@ -256,16 +256,18 @@ export class ExtensionEditor extends BaseEditor {
const updateAction = this.instantiationService.createInstance(UpdateAction);
const enableAction = this.instantiationService.createInstance(EnableAction);
const disableAction = this.instantiationService.createInstance(DisableAction);
const reloadAction = this.instantiationService.createInstance(ReloadAction);
installAction.extension = extension;
builtinStatusAction.extension = extension;
updateAction.extension = extension;
enableAction.extension = extension;
disableAction.extension = extension;
reloadAction.extension = extension;
this.extensionActionBar.clear();
this.extensionActionBar.push([enableAction, updateAction, disableAction, installAction, builtinStatusAction], { icon: true, label: true });
this.transientDisposables.push(enableAction, updateAction, disableAction, installAction, builtinStatusAction);
this.extensionActionBar.push([enableAction, updateAction, reloadAction, disableAction, installAction, builtinStatusAction], { icon: true, label: true });
this.transientDisposables.push(enableAction, updateAction, reloadAction, disableAction, installAction, builtinStatusAction);
this.navbar.clear();
this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables);
......
......@@ -20,7 +20,8 @@ export enum ExtensionState {
Installing,
Installed,
Uninstalled,
Disabled
Disabled,
NeedsReload
}
export interface IExtension {
......
......@@ -26,6 +26,7 @@ import { ExtensionsConfigurationInitialContent } from 'vs/workbench/parts/extens
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
import { IExtensionsRuntimeService } from 'vs/platform/extensions/common/extensions';
const dialog = remote.dialog;
......@@ -109,7 +110,7 @@ export class UninstallAction extends Action {
return;
}
this.enabled = this.extension.state === ExtensionState.Installed || this.extension.state === ExtensionState.Disabled;
this.enabled = this.extension.state === ExtensionState.Installed || this.extension.state === ExtensionState.Disabled || this.extension.state === ExtensionState.NeedsReload;
}
run(): TPromise<any> {
......@@ -318,6 +319,61 @@ export class DisableAction extends Action {
}
}
export class ReloadAction extends Action {
private static EnabledClass = 'extension-action reload';
private static DisabledClass = `${ReloadAction.EnabledClass} disabled`;
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IMessageService private messageService: IMessageService,
@IInstantiationService private instantiationService: IInstantiationService,
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService
) {
super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
if (!this.extension) {
this.enabled = false;
this.class = ReloadAction.DisabledClass;
return;
}
this.enabled = this.extension.state === ExtensionState.NeedsReload;
this.class = this.enabled ? ReloadAction.EnabledClass : ReloadAction.DisabledClass;
}
run(): TPromise<any> {
return this.getReloadMessage().then(message => {
if (window.confirm(message)) {
this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('reloadNow', "Reload Now")).run();
}
return null;
});
}
private getReloadMessage(): TPromise<string> {
return this.extensionsRuntimeService.getExtensions(true).then(extensionDescriptions => {
const disabled = this.extensionsRuntimeService.getDisabledExtensions().indexOf(this.extension.identifier) !== -1;
const installed = !extensionDescriptions.every(e => e.id !== this.extension.identifier);
if (disabled || !installed) {
return localize('postEnableMessage', "In order to enable '{0}' extension, this window of VS Code needs to be restarted.", this.extension.displayName);
}
return localize('postDisableMessage', "In order to disable '{0}' extension, this window of VS Code needs to be restarted.", this.extension.displayName);
});
}
}
export class UpdateAllAction extends Action {
static ID = 'workbench.extensions.action.updateAllExtensions';
......
......@@ -15,7 +15,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IExtension } from './extensions';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction } from './extensionsActions';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction, ReloadAction } from './extensionsActions';
import { Label, RatingsWidget, InstallWidget, StatusWidget } from './extensionsWidgets';
import { EventType } from 'vs/base/common/events';
......@@ -77,9 +77,10 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const updateAction = this.instantiationService.createInstance(UpdateAction);
const enableAction = this.instantiationService.createInstance(EnableAction);
const disableAction = this.instantiationService.createInstance(DisableAction);
const reloadAction = this.instantiationService.createInstance(ReloadAction);
actionbar.push([enableAction, updateAction, disableAction, combinedInstallAction, builtinStatusAction], actionOptions);
const disposables = [versionWidget, installCountWidget, ratingsWidget, combinedInstallAction, builtinStatusAction, updateAction, enableAction, disableAction, actionbar];
actionbar.push([enableAction, updateAction, disableAction, reloadAction, combinedInstallAction, builtinStatusAction], actionOptions);
const disposables = [versionWidget, installCountWidget, ratingsWidget, combinedInstallAction, builtinStatusAction, updateAction, enableAction, disableAction, reloadAction, actionbar];
return {
element, icon, name, installCount, ratings, status, author, description, disposables,
......@@ -94,6 +95,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
enableAction.extension = extension;
disableAction.extension = extension;
statusWidget.extension = extension;
reloadAction.extension = extension;
}
};
}
......
......@@ -25,7 +25,7 @@ import {
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IMessageService, LaterAction } from 'vs/platform/message/common/message';
import { IMessageService } from 'vs/platform/message/common/message';
import Severity from 'vs/base/common/severity';
import * as semver from 'semver';
import * as path from 'path';
......@@ -168,6 +168,10 @@ class Extension implements IExtension {
return this.type === LocalExtensionType.User && semver.gt(this.latestVersion, this.version);
}
get reload(): boolean {
return this.needsRestart;
}
get telemetryData(): any {
const { local, gallery } = this;
......@@ -471,27 +475,15 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
return TPromise.wrapError<void>(new Error('Missing gallery'));
}
return this.extensionService.installFromGallery(gallery, promptToInstallDependencies)
.then(() => {
this.promptToRestart(ext, true);
});
return this.extensionService.installFromGallery(gallery, promptToInstallDependencies);
}
setEnablement(extension: IExtension, enable: boolean): TPromise<any> {
return this.extensionsRuntimeService.setEnablement(extension.identifier, enable, extension.displayName).then(restart => {
if (restart) {
this.promptToRestart(extension, enable);
this.telemetryService.publicLog(enable ? 'extension:enable' : 'extension:disable', extension.telemetryData);
}
});
}
private promptToRestart(extension: IExtension, enable: boolean): void {
const message = enable ? localize('postEnableMessage', "In order to enable '{0}' extension, this window of VS Code needs to be restarted.", extension.displayName)
: localize('postDisableMessage', "In order to disable '{0}' extension, this window of VS Code needs to be restarted.", extension.displayName);
this.messageService.show(Severity.Info, {
message,
actions: [this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('restartNow', "Restart Now")), LaterAction]
// this.promptToRestart(extension, enable);
(<Extension>extension).needsRestart = restart;
this.telemetryService.publicLog(enable ? 'extension:enable' : 'extension:disable', extension.telemetryData);
this._onChange.fire();
});
}
......@@ -597,7 +589,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
if (!uninstalling) {
return;
}
uninstalling.extension.needsRestart = true;
this.reportTelemetry(uninstalling, true);
}
......@@ -611,10 +603,9 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
if (local) {
if (local.needsRestart) {
return ExtensionState.Disabled;
} else {
return disabledExtensions.indexOf(`${local.publisher}.${local.name}`) === -1 ? ExtensionState.Installed : ExtensionState.Disabled;
return ExtensionState.NeedsReload;
}
return disabledExtensions.indexOf(`${local.publisher}.${local.name}`) === -1 ? ExtensionState.Installed : ExtensionState.Disabled;
}
return ExtensionState.Uninstalled;
......
......@@ -34,6 +34,7 @@
}
.monaco-action-bar .action-item .action-label.extension-action.install,
.monaco-action-bar .action-item .action-label.extension-action.enable,
.monaco-action-bar .action-item .action-label.extension-action.update {
color: white;
background-color: #327e36;
......@@ -41,26 +42,35 @@
}
.monaco-action-bar .action-item:not(.disabled):hover .action-label.extension-action.install,
.monaco-action-bar .action-item:not(.disabled):hover .action-label.extension-action.enable,
.monaco-action-bar .action-item:not(.disabled):hover .action-label.extension-action.update {
background-color: #478E4B;
}
.monaco-action-bar .action-item:not(.disabled):active .action-label.extension-action.install,
.monaco-action-bar .action-item:not(.disabled):active .action-label.extension-action.enable,
.monaco-action-bar .action-item:not(.disabled):active .action-label.extension-action.update {
background-color: #6DA770;
}
.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.install,
.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.enable,
.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.update {
outline: 1px solid rgb(14, 99, 156) !important;
}
.monaco-action-bar .action-item .action-label.extension-action.enable {
.monaco-action-bar .action-item .action-label.extension-action.reload {
color: white;
background-color: #007ACC;
border-color: #3F8BCE;
}
.monaco-action-bar .action-item:not(.disabled):hover .action-label.extension-action.reload {
background-color: #2584C4;
}
.monaco-action-bar .action-item:not(.disabled):active .action-label.extension-action.reload {
background-color: #4294CC
}
.monaco-action-bar .action-item .action-label.clear-extensions {
......@@ -72,18 +82,12 @@
background: url('clear-inverse.svg') center center no-repeat;
}
.monaco-action-bar .action-item:not(.disabled):hover .action-label.extension-action.enable {
background-color: #2584C4;
}
.monaco-action-bar .action-item:not(.disabled):active .action-label.extension-action.enable {
background-color: #4294CC
}
.monaco-action-bar .action-item.disabled .action-label.extension-action.install:not(.installing),
.monaco-action-bar .action-item.disabled .action-label.extension-action.update,
.monaco-action-bar .action-item.disabled .action-label.extension-action.enable,
.monaco-action-bar .action-item.disabled .action-label.extension-action.disable,
.monaco-action-bar .action-item.disabled .action-label.extension-action.reload,
.monaco-action-bar .action-item.disabled .action-label.extension-action.built-in-status.user {
display: none;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册