mirror of
https://github.com/coder/code-server.git
synced 2026-05-10 14:27:26 +02:00
Merge commit 'be3e8236086165e5e45a5a10783823874b3f3ebd' as 'lib/vscode'
This commit is contained in:
183
lib/vscode/src/vs/platform/progress/common/progress.ts
Normal file
183
lib/vscode/src/vs/platform/progress/common/progress.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
|
||||
export const IProgressService = createDecorator<IProgressService>('progressService');
|
||||
|
||||
/**
|
||||
* A progress service that can be used to report progress to various locations of the UI.
|
||||
*/
|
||||
export interface IProgressService {
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
withProgress<R>(
|
||||
options: IProgressOptions | IProgressNotificationOptions | IProgressWindowOptions | IProgressCompositeOptions,
|
||||
task: (progress: IProgress<IProgressStep>) => Promise<R>,
|
||||
onDidCancel?: (choice?: number) => void
|
||||
): Promise<R>;
|
||||
}
|
||||
|
||||
export interface IProgressIndicator {
|
||||
|
||||
/**
|
||||
* Show progress customized with the provided flags.
|
||||
*/
|
||||
show(infinite: true, delay?: number): IProgressRunner;
|
||||
show(total: number, delay?: number): IProgressRunner;
|
||||
|
||||
/**
|
||||
* Indicate progress for the duration of the provided promise. Progress will stop in
|
||||
* any case of promise completion, error or cancellation.
|
||||
*/
|
||||
showWhile(promise: Promise<unknown>, delay?: number): Promise<void>;
|
||||
}
|
||||
|
||||
export const enum ProgressLocation {
|
||||
Explorer = 1,
|
||||
Scm = 3,
|
||||
Extensions = 5,
|
||||
Window = 10,
|
||||
Notification = 15,
|
||||
Dialog = 20
|
||||
}
|
||||
|
||||
export interface IProgressOptions {
|
||||
readonly location: ProgressLocation | string;
|
||||
readonly title?: string;
|
||||
readonly source?: string;
|
||||
readonly total?: number;
|
||||
readonly cancellable?: boolean;
|
||||
readonly buttons?: string[];
|
||||
}
|
||||
|
||||
export interface IProgressNotificationOptions extends IProgressOptions {
|
||||
readonly location: ProgressLocation.Notification;
|
||||
readonly primaryActions?: ReadonlyArray<IAction>;
|
||||
readonly secondaryActions?: ReadonlyArray<IAction>;
|
||||
readonly delay?: number;
|
||||
readonly silent?: boolean;
|
||||
}
|
||||
|
||||
export interface IProgressWindowOptions extends IProgressOptions {
|
||||
readonly location: ProgressLocation.Window;
|
||||
readonly command?: string;
|
||||
}
|
||||
|
||||
export interface IProgressCompositeOptions extends IProgressOptions {
|
||||
readonly location: ProgressLocation.Explorer | ProgressLocation.Extensions | ProgressLocation.Scm | string;
|
||||
readonly delay?: number;
|
||||
}
|
||||
|
||||
export interface IProgressStep {
|
||||
message?: string;
|
||||
increment?: number;
|
||||
total?: number;
|
||||
}
|
||||
|
||||
export interface IProgressRunner {
|
||||
total(value: number): void;
|
||||
worked(value: number): void;
|
||||
done(): void;
|
||||
}
|
||||
|
||||
export const emptyProgressRunner: IProgressRunner = Object.freeze({
|
||||
total() { },
|
||||
worked() { },
|
||||
done() { }
|
||||
});
|
||||
|
||||
export interface IProgress<T> {
|
||||
report(item: T): void;
|
||||
}
|
||||
|
||||
export class Progress<T> implements IProgress<T> {
|
||||
|
||||
static readonly None: IProgress<unknown> = Object.freeze({ report() { } });
|
||||
|
||||
private _value?: T;
|
||||
get value(): T | undefined { return this._value; }
|
||||
|
||||
constructor(private callback: (data: T) => void) { }
|
||||
|
||||
report(item: T) {
|
||||
this._value = item;
|
||||
this.callback(this._value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to show progress during a long running operation. If the operation
|
||||
* is started multiple times, only the last invocation will drive the progress.
|
||||
*/
|
||||
export interface IOperation {
|
||||
id: number;
|
||||
isCurrent: () => boolean;
|
||||
token: CancellationToken;
|
||||
stop(): void;
|
||||
}
|
||||
|
||||
export class LongRunningOperation extends Disposable {
|
||||
private currentOperationId = 0;
|
||||
private readonly currentOperationDisposables = this._register(new DisposableStore());
|
||||
private currentProgressRunner: IProgressRunner | undefined;
|
||||
private currentProgressTimeout: any;
|
||||
|
||||
constructor(
|
||||
private progressIndicator: IProgressIndicator
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
start(progressDelay: number): IOperation {
|
||||
|
||||
// Stop any previous operation
|
||||
this.stop();
|
||||
|
||||
// Start new
|
||||
const newOperationId = ++this.currentOperationId;
|
||||
const newOperationToken = new CancellationTokenSource();
|
||||
this.currentProgressTimeout = setTimeout(() => {
|
||||
if (newOperationId === this.currentOperationId) {
|
||||
this.currentProgressRunner = this.progressIndicator.show(true);
|
||||
}
|
||||
}, progressDelay);
|
||||
|
||||
this.currentOperationDisposables.add(toDisposable(() => clearTimeout(this.currentProgressTimeout)));
|
||||
this.currentOperationDisposables.add(toDisposable(() => newOperationToken.cancel()));
|
||||
this.currentOperationDisposables.add(toDisposable(() => this.currentProgressRunner ? this.currentProgressRunner.done() : undefined));
|
||||
|
||||
return {
|
||||
id: newOperationId,
|
||||
token: newOperationToken.token,
|
||||
stop: () => this.doStop(newOperationId),
|
||||
isCurrent: () => this.currentOperationId === newOperationId
|
||||
};
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
this.doStop(this.currentOperationId);
|
||||
}
|
||||
|
||||
private doStop(operationId: number): void {
|
||||
if (this.currentOperationId === operationId) {
|
||||
this.currentOperationDisposables.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const IEditorProgressService = createDecorator<IEditorProgressService>('editorProgressService');
|
||||
|
||||
/**
|
||||
* A progress service that will report progress local to the editor triggered from.
|
||||
*/
|
||||
export interface IEditorProgressService extends IProgressIndicator {
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user