Skip to content

Commit 0157b3c

Browse files
author
Benjamin Pasero
committed
1 parent f89390f commit 0157b3c

5 files changed

Lines changed: 39 additions & 9 deletions

File tree

src/vs/platform/progress/common/progress.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
77
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
88
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
9+
import { IAction } from 'vs/base/common/actions';
910

1011
export const IProgressService = createDecorator<IProgressService>('progressService');
1112

@@ -42,6 +43,12 @@ export interface IProgressOptions {
4243
cancellable?: boolean;
4344
}
4445

46+
export interface IProgressNotificationOptions extends IProgressOptions {
47+
location: ProgressLocation.Notification;
48+
primaryActions?: IAction[];
49+
secondaryActions?: IAction[];
50+
}
51+
4552
export interface IProgressStep {
4653
message?: string;
4754
increment?: number;

src/vs/workbench/api/browser/mainThreadProgress.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,21 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { IProgress, IProgressService2, IProgressStep, IProgressOptions } from 'vs/platform/progress/common/progress';
6+
import { IProgress, IProgressService2, IProgressStep, ProgressLocation, IProgressOptions, IProgressNotificationOptions } from 'vs/platform/progress/common/progress';
77
import { MainThreadProgressShape, MainContext, IExtHostContext, ExtHostProgressShape, ExtHostContext } from '../common/extHost.protocol';
88
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
9+
import { Action } from 'vs/base/common/actions';
10+
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
11+
import { ICommandService } from 'vs/platform/commands/common/commands';
12+
import { localize } from 'vs/nls';
13+
14+
class ManageExtensionAction extends Action {
15+
constructor(id: ExtensionIdentifier, label: string, commandService: ICommandService) {
16+
super(id.value, label, undefined, true, () => {
17+
return commandService.executeCommand('_extensions.manage', id.value);
18+
});
19+
}
20+
}
921

1022
@extHostNamedCustomer(MainContext.MainThreadProgress)
1123
export class MainThreadProgress implements MainThreadProgressShape {
@@ -16,7 +28,8 @@ export class MainThreadProgress implements MainThreadProgressShape {
1628

1729
constructor(
1830
extHostContext: IExtHostContext,
19-
@IProgressService2 progressService: IProgressService2
31+
@IProgressService2 progressService: IProgressService2,
32+
@ICommandService private readonly _commandService: ICommandService
2033
) {
2134
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostProgress);
2235
this._progressService = progressService;
@@ -27,9 +40,19 @@ export class MainThreadProgress implements MainThreadProgressShape {
2740
this._progress.clear();
2841
}
2942

30-
$startProgress(handle: number, options: IProgressOptions): void {
43+
$startProgress(handle: number, options: IProgressOptions, extension?: IExtensionDescription): void {
3144
const task = this._createTask(handle);
3245

46+
if (options.location === ProgressLocation.Notification && extension && !extension.isUnderDevelopment) {
47+
const notificationOptions: IProgressNotificationOptions = {
48+
...options,
49+
location: ProgressLocation.Notification,
50+
secondaryActions: [new ManageExtensionAction(extension.identifier, localize('manageExtension', "Manage Extension"), this._commandService)]
51+
};
52+
53+
options = notificationOptions;
54+
}
55+
3356
this._progressService.withProgress(options, task, () => this._proxy.$acceptProgressCanceled(handle));
3457
}
3558

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ export interface MainThreadOutputServiceShape extends IDisposable {
376376

377377
export interface MainThreadProgressShape extends IDisposable {
378378

379-
$startProgress(handle: number, options: IProgressOptions): void;
379+
$startProgress(handle: number, options: IProgressOptions, extension?: IExtensionDescription): void;
380380
$progressReport(handle: number, message: IProgressStep): void;
381381
$progressEnd(handle: number): void;
382382
}

src/vs/workbench/api/common/extHostProgress.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class ExtHostProgress implements ExtHostProgressShape {
2626
const handle = this._handles++;
2727
const { title, location, cancellable } = options;
2828
const source = localize('extensionSource', "{0} (Extension)", extension.displayName || extension.name);
29-
this._proxy.$startProgress(handle, { location: ProgressLocation.from(location), title, source, cancellable });
29+
this._proxy.$startProgress(handle, { location: ProgressLocation.from(location), title, source, cancellable }, extension);
3030
return this._withProgress(handle, task, !!cancellable);
3131
}
3232

src/vs/workbench/services/progress/browser/progressService2.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'vs/css!./media/progressService2';
77

88
import { localize } from 'vs/nls';
99
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
10-
import { IProgressService2, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress } from 'vs/platform/progress/common/progress';
10+
import { IProgressService2, IProgressOptions, IProgressStep, ProgressLocation, IProgress, emptyProgress, Progress, IProgressNotificationOptions } from 'vs/platform/progress/common/progress';
1111
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
1212
import { StatusbarAlignment, IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
1313
import { timeout } from 'vs/base/common/async';
@@ -54,7 +54,7 @@ export class ProgressService2 implements IProgressService2 {
5454

5555
switch (location) {
5656
case ProgressLocation.Notification:
57-
return this._withNotificationProgress(options, task, onDidCancel);
57+
return this._withNotificationProgress({ ...options, location: ProgressLocation.Notification }, task, onDidCancel);
5858
case ProgressLocation.Window:
5959
return this._withWindowProgress(options, task);
6060
case ProgressLocation.Explorer:
@@ -138,15 +138,15 @@ export class ProgressService2 implements IProgressService2 {
138138
}
139139
}
140140

141-
private _withNotificationProgress<P extends Promise<R>, R = unknown>(options: IProgressOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
141+
private _withNotificationProgress<P extends Promise<R>, R = unknown>(options: IProgressNotificationOptions, callback: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
142142
const toDispose: IDisposable[] = [];
143143

144144
const createNotification = (message: string | undefined, increment?: number): INotificationHandle | undefined => {
145145
if (!message) {
146146
return undefined; // we need a message at least
147147
}
148148

149-
const actions: INotificationActions = { primary: [] };
149+
const actions: INotificationActions = { primary: options.primaryActions || [], secondary: options.secondaryActions || [] };
150150
if (options.cancellable) {
151151
const cancelAction = new class extends Action {
152152
constructor() {

0 commit comments

Comments
 (0)