提交 a16f6591 编写于 作者: J Joao Moreno

fixes #29729

上级 f00d4f73
......@@ -8,8 +8,6 @@
import * as nls from 'vs/nls';
import 'vs/css!./media/update.contribution';
import { Registry } from 'vs/platform/registry/common/platform';
import { isMacintosh } from 'vs/base/common/platform';
import product from 'vs/platform/node/product';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ReleaseNotesEditor } from 'vs/workbench/parts/update/electron-browser/releaseNotesEditor';
import { ReleaseNotesInput } from 'vs/workbench/parts/update/electron-browser/releaseNotesInput';
......@@ -20,18 +18,13 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { ShowCurrentReleaseNotesAction, ProductContribution, UpdateContribution, LightUpdateContribution } from './update';
import { ShowCurrentReleaseNotesAction, ProductContribution, UpdateContribution } from './update';
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(ProductContribution);
if (isMacintosh || product.quality !== 'stable') {
Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions)
.registerActivity(LightUpdateContribution);
} else {
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(UpdateContribution);
}
Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions)
.registerActivity(UpdateContribution);
// Editor
const editorDescriptor = new EditorDescriptor(
......
......@@ -9,6 +9,8 @@ import nls = require('vs/nls');
import severity from 'vs/base/common/severity';
import { TPromise } from 'vs/base/common/winjs.base';
import { IAction, Action } from 'vs/base/common/actions';
import { mapEvent } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IMessageService, CloseAction, Severity } from 'vs/platform/message/common/message';
import pkg from 'vs/platform/node/package';
......@@ -236,48 +238,18 @@ export class ProductContribution implements IWorkbenchContribution {
}
}
export class UpdateContribution implements IWorkbenchContribution {
getId() { return 'vs.update'; }
class CommandAction extends Action {
constructor(
@IInstantiationService instantiationService: IInstantiationService,
@IMessageService messageService: IMessageService,
@IUpdateService updateService: IUpdateService
commandId: string,
label: string,
@ICommandService private commandService: ICommandService
) {
updateService.onUpdateReady(update => {
const applyUpdateAction = instantiationService.createInstance(ApplyUpdateAction);
const releaseNotesAction = instantiationService.createInstance(ShowReleaseNotesAction, false, update.version);
messageService.show(severity.Info, {
message: nls.localize('updateAvailable', "{0} will be updated after it restarts.", product.nameLong),
actions: [applyUpdateAction, NotNowAction, releaseNotesAction]
});
});
updateService.onUpdateAvailable(update => {
const downloadAction = instantiationService.createInstance(DownloadAction, update.version);
const releaseNotesAction = instantiationService.createInstance(ShowReleaseNotesAction, false, update.version);
messageService.show(severity.Info, {
message: nls.localize('thereIsUpdateAvailable', "There is an available update."),
actions: [downloadAction, NotNowAction, releaseNotesAction]
});
});
updateService.onUpdateNotAvailable(explicit => {
if (!explicit) {
return;
}
messageService.show(severity.Info, nls.localize('noUpdatesAvailable', "There are no updates currently available."));
});
updateService.onError(err => messageService.show(severity.Error, err));
super(`command-action:${commandId}`, label, undefined, true, () => commandService.executeCommand(commandId));
}
}
export class LightUpdateContribution implements IGlobalActivity {
export class UpdateContribution implements IGlobalActivity {
private static readonly showCommandsId = 'workbench.action.showCommands';
private static readonly openSettingsId = 'workbench.action.openGlobalSettings';
......@@ -288,48 +260,111 @@ export class LightUpdateContribution implements IGlobalActivity {
get id() { return 'vs.update'; }
get name() { return ''; }
get cssClass() { return 'update-activity'; }
private disposables: IDisposable[] = [];
constructor(
@IStorageService storageService: IStorageService,
@IStorageService private storageService: IStorageService,
@ICommandService private commandService: ICommandService,
@IInstantiationService instantiationService: IInstantiationService,
@IMessageService messageService: IMessageService,
@IInstantiationService private instantiationService: IInstantiationService,
@IMessageService private messageService: IMessageService,
@IUpdateService private updateService: IUpdateService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IActivityBarService activityBarService: IActivityBarService
@IActivityBarService private activityBarService: IActivityBarService
) {
const addBadge = () => {
const badge = new NumberBadge(1, () => nls.localize('updateIsReady', "New update available."));
activityBarService.showGlobalActivity(this.id, badge);
};
const onUpdateAvailable = isLinux
? mapEvent(updateService.onUpdateAvailable, e => e.version)
: mapEvent(updateService.onUpdateReady, e => e.version);
onUpdateAvailable(this.onUpdateAvailable, this, this.disposables);
updateService.onError(this.onError, this, this.disposables);
updateService.onUpdateNotAvailable(this.onUpdateNotAvailable, this, this.disposables);
/*
The `update/lastKnownVersion` and `update/updateNotificationTime` storage keys are used in
combination to figure out when to show a message to the user that he should update.
This message should appear if the user has received an update notification but hasn't
updated since 5 days.
*/
const currentVersion = product.commit;
const lastKnownVersion = this.storageService.get('update/lastKnownVersion', StorageScope.GLOBAL);
// if current version != stored version, clear both fields
if (currentVersion !== lastKnownVersion) {
this.storageService.remove('update/lastKnownVersion', StorageScope.GLOBAL);
this.storageService.remove('update/updateNotificationTime', StorageScope.GLOBAL);
}
}
private onUpdateAvailable(version: string): void {
const badge = new NumberBadge(1, () => nls.localize('updateIsReady', "New update available."));
this.activityBarService.showGlobalActivity(this.id, badge);
const currentVersion = product.commit;
const currentMillis = new Date().getTime();
const lastKnownVersion = this.storageService.get('update/lastKnownVersion', StorageScope.GLOBAL);
// if version != stored version, save version and date
if (currentVersion !== lastKnownVersion) {
this.storageService.store('update/lastKnownVersion', currentVersion, StorageScope.GLOBAL);
this.storageService.store('update/updateNotificationTime', currentMillis, StorageScope.GLOBAL);
}
const updateNotificationMillis = this.storageService.getInteger('update/updateNotificationTime', StorageScope.GLOBAL, currentMillis);
const diffDays = (currentMillis - updateNotificationMillis) / (1000 * 60 * 60 * 24);
// if 5 days have passed from stored date, show message service
if (diffDays > 5) {
this.showUpdateNotification(version);
}
}
private showUpdateNotification(version: string): void {
const releaseNotesAction = this.instantiationService.createInstance(ShowReleaseNotesAction, false, version);
if (isLinux) {
this.updateService.onUpdateAvailable(() => addBadge());
const downloadAction = this.instantiationService.createInstance(DownloadAction, version);
this.messageService.show(severity.Info, {
message: nls.localize('thereIsUpdateAvailable', "There is an available update."),
actions: [downloadAction, NotNowAction, releaseNotesAction]
});
} else {
this.updateService.onUpdateReady(() => addBadge());
const applyUpdateAction = this.instantiationService.createInstance(ApplyUpdateAction);
this.messageService.show(severity.Info, {
message: nls.localize('updateAvailable', "{0} will be updated after it restarts.", product.nameLong),
actions: [applyUpdateAction, NotNowAction, releaseNotesAction]
});
}
}
this.updateService.onError(err => messageService.show(severity.Error, err));
private onUpdateNotAvailable(explicit: boolean): void {
if (!explicit) {
return;
}
this.updateService.onUpdateNotAvailable(explicit => {
if (!explicit) {
return;
}
this.messageService.show(severity.Info, nls.localize('noUpdatesAvailable', "There are no updates currently available."));
}
messageService.show(severity.Info, nls.localize('noUpdatesAvailable', "There are no updates currently available."));
});
private onError(err: any): void {
this.messageService.show(severity.Error, err);
}
getActions(): IAction[] {
const updateAction = this.getUpdateAction();
return [
new Action(LightUpdateContribution.showCommandsId, nls.localize('commandPalette', "Command Palette..."), undefined, true, () => this.commandService.executeCommand(LightUpdateContribution.showCommandsId)),
new CommandAction(UpdateContribution.showCommandsId, nls.localize('commandPalette', "Command Palette..."), this.commandService),
new Separator(),
new Action(LightUpdateContribution.openSettingsId, nls.localize('settings', "Settings"), null, true, () => this.commandService.executeCommand(LightUpdateContribution.openSettingsId)),
new Action(LightUpdateContribution.openKeybindingsId, nls.localize('keyboardShortcuts', "Keyboard Shortcuts"), null, true, () => this.commandService.executeCommand(LightUpdateContribution.openKeybindingsId)),
new CommandAction(UpdateContribution.openSettingsId, nls.localize('settings', "Settings"), this.commandService),
new CommandAction(UpdateContribution.openKeybindingsId, nls.localize('keyboardShortcuts', "Keyboard Shortcuts"), this.commandService),
new Separator(),
new Action(LightUpdateContribution.selectColorThemeId, nls.localize('selectTheme.label', "Color Theme"), null, true, () => this.commandService.executeCommand(LightUpdateContribution.selectColorThemeId)),
new Action(LightUpdateContribution.selectIconThemeId, nls.localize('themes.selectIconTheme.label', "File Icon Theme"), null, true, () => this.commandService.executeCommand(LightUpdateContribution.selectIconThemeId)),
new CommandAction(UpdateContribution.selectColorThemeId, nls.localize('selectTheme.label', "Color Theme"), this.commandService),
new CommandAction(UpdateContribution.selectIconThemeId, nls.localize('themes.selectIconTheme.label', "File Icon Theme"), this.commandService),
new Separator(),
this.getUpdateAction()
updateAction
];
}
......@@ -362,4 +397,8 @@ export class LightUpdateContribution implements IGlobalActivity {
this.updateService.checkForUpdates(true));
}
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册