1
>
/*---------------------------------------------------------------------------------------------
progress.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { IAction } from '../../../base/common/actions.js';
7
>
import { DeferredPromise } from '../../../base/common/async.js';
8
>
import { CancellationToken, CancellationTokenSource } from '../../../base/common/cancellation.js';
9
>
import { Disposable, DisposableStore, toDisposable } from '../../../base/common/lifecycle.js';
10
>
import { createDecorator } from '../../instantiation/common/instantiation.js';
11
>
import { INotificationSource, NotificationPriority } from '../../notification/common/notification.js';
12
>
13
>
export const IProgressService = createDecorator<IProgressService>('progressService');
14
>
15
>
/**
16
>
* A progress service that can be used to report progress to various locations of the UI.
17
>
*/
18
>
export interface IProgressService {
19
>
20
>
readonly _serviceBrand: undefined;
21
>
22
>
withProgress<R>(
23
>
options: IProgressOptions | IProgressDialogOptions | IProgressNotificationOptions | IProgressWindowOptions | IProgressCompositeOptions,
24
>
task: (progress: IProgress<IProgressStep>) => Promise<R>,
25
>
onDidCancel?: (choice?: number) => void
26
>
): Promise<R>;
27
>
}
28
>
29
>
export interface IProgressIndicator {
30
>
31
>
/**
32
>
* Show progress customized with the provided flags.
33
>
*/
34
>
show(infinite: true, delay?: number): IProgressRunner;
35
>
show(total: number, delay?: number): IProgressRunner;
36
>
37
>
/**
38
>
* Indicate progress for the duration of the provided promise. Progress will stop in
39
>
* any case of promise completion, error or cancellation.
40
>
*/
41
>
showWhile(promise: Promise<unknown>, delay?: number): Promise<void>;
42
>
}
43
>
44
>
export const enum ProgressLocation {
45
>
Explorer = 1,
46
>
Scm = 3,
47
>
Extensions = 5,
48
>
Window = 10,
49
>
Notification = 15,
50
>
Dialog = 20
51
>
}
52
>
53
>
export interface IProgressOptions {
54
>
readonly location: ProgressLocation | string;
55
>
readonly title?: string;
56
>
readonly source?: string | INotificationSource;
57
>
readonly total?: number;
58
>
readonly cancellable?: boolean | string;
59
>
readonly buttons?: string[];
60
>
}
61
>
62
>
export interface IProgressNotificationOptions extends IProgressOptions {
63
>
readonly location: ProgressLocation.Notification;
64
>
readonly primaryActions?: readonly IAction[];
65
>
readonly secondaryActions?: readonly IAction[];
66
>
readonly delay?: number;
67
>
readonly priority?: NotificationPriority;
68
>
readonly type?: 'loading' | 'syncing';
69
>
}
70
>
71
>
export interface IProgressDialogOptions extends IProgressOptions {
72
>
readonly delay?: number;
73
>
readonly detail?: string;
74
>
readonly sticky?: boolean;
75
>
}
76
>
77
>
export interface IProgressWindowOptions extends IProgressOptions {
78
>
readonly location: ProgressLocation.Window;
79
>
readonly command?: string;
80
>
readonly type?: 'loading' | 'syncing';
81
>
}
82
>
83
>
export interface IProgressCompositeOptions extends IProgressOptions {
84
>
readonly location: ProgressLocation.Explorer | ProgressLocation.Extensions | ProgressLocation.Scm | string;
85
>
readonly delay?: number;
86
>
}
87
>
88
>
export interface IProgressStep {
89
>
message?: string;
90
>
increment?: number;
91
>
total?: number;
92
>
}
93
>
94
>
export interface IProgressRunner {
95
>
total(value: number): void;
96
>
worked(value: number): void;
97
>
done(): void;
98
>
}
99
>
100
>
export const emptyProgressRunner = Object.freeze<IProgressRunner>({
101
>
total() { },
102
>
worked() { },
103
>
done() { }
104
>
});
105
>
106
>
export interface IProgress<T> {
107
>
report(item: T): void;
108
>
}
109
>
110
>
export class Progress<T> implements IProgress<T> {
111
>
112
>
static readonly None = Object.freeze<IProgress<unknown>>({ report() { } });
113
>
114
>
private _value?: T;
115
>
get value(): T | undefined { return this._value; }
116
>
117
>
constructor(private callback: (data: T) => unknown) {
118
}
120
>
report(item: T) {
121
this._value = item;
122
this.callback(this._value);
123
}
125
>
126
>
/**
127
>
* A helper to show progress during a long running operation. If the operation
128
>
* is started multiple times, only the last invocation will drive the progress.
129
>
*/
130
>
export interface IOperation {
131
>
id: number;
132
>
isCurrent: () => boolean;
133
>
token: CancellationToken;
134
>
stop(): void;
135
>
}
136
>
137
>
/**
138
>
* RAII-style progress instance that allows imperative reporting and hides
139
>
* once `dispose()` is called.
140
>
*/
141
>
export class UnmanagedProgress extends Disposable {
142
>
private readonly deferred = new DeferredPromise<void>();
143
>
private reporter?: IProgress<IProgressStep>;
144
>
private lastStep?: IProgressStep;
145
>
146
>
constructor(
147
options: IProgressOptions | IProgressDialogOptions | IProgressNotificationOptions | IProgressWindowOptions | IProgressCompositeOptions,
148
@IProgressService progressService: IProgressService,