1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | import { injectable, inject } from 'inversify';
|
18 | import { CancellationToken } from '../../shared/vscode-languageserver-protocol';
|
19 | import { ProgressClient, ProgressMessage, ProgressUpdate } from '../common';
|
20 | import { StatusBar, StatusBarAlignment } from './status-bar';
|
21 | import { Deferred } from '../common/promise-util';
|
22 | import throttle = require('lodash.throttle');
|
23 |
|
24 | @injectable()
|
25 | export class ProgressStatusBarItem implements ProgressClient {
|
26 |
|
27 | protected readonly id = 'theia-progress-status-bar-item';
|
28 |
|
29 | @inject(StatusBar)
|
30 | protected readonly statusBar: StatusBar;
|
31 |
|
32 | protected messagesByProgress = new Map<string, string | undefined>();
|
33 |
|
34 | protected incomingQueue = new Array<string>();
|
35 |
|
36 | get currentProgress(): string | undefined {
|
37 | return this.incomingQueue.slice(-1)[0];
|
38 | }
|
39 |
|
40 | showProgress(progressId: string, message: ProgressMessage, cancellationToken: CancellationToken): Promise<string | undefined> {
|
41 | const result = new Deferred<string | undefined>();
|
42 | cancellationToken.onCancellationRequested(() => {
|
43 | this.processEvent(progressId, 'done');
|
44 | result.resolve(ProgressMessage.Cancel);
|
45 | });
|
46 | this.processEvent(progressId, 'start', message.text);
|
47 | return result.promise;
|
48 | }
|
49 |
|
50 | protected processEvent(progressId: string, event: 'start' | 'done', message?: string): void {
|
51 | if (event === 'start') {
|
52 | this.incomingQueue.push(progressId);
|
53 | this.messagesByProgress.set(progressId, message);
|
54 | } else {
|
55 | this.incomingQueue = this.incomingQueue.filter(id => id !== progressId);
|
56 | this.messagesByProgress.delete(progressId);
|
57 | }
|
58 | this.triggerUpdate();
|
59 | }
|
60 |
|
61 | protected readonly triggerUpdate = throttle(() => this.update(this.currentProgress), 250, { leading: true, trailing: true });
|
62 |
|
63 | async reportProgress(progressId: string, update: ProgressUpdate, originalMessage: ProgressMessage, _cancellationToken: CancellationToken): Promise<void> {
|
64 | const newMessage = update.message ? `${originalMessage.text}: ${update.message}` : originalMessage.text;
|
65 | this.messagesByProgress.set(progressId, newMessage);
|
66 | this.triggerUpdate();
|
67 | }
|
68 |
|
69 | protected update(progressId: string | undefined): void {
|
70 | const message = progressId && this.messagesByProgress.get(progressId);
|
71 | if (!progressId || !message) {
|
72 | this.statusBar.removeElement(this.id);
|
73 | return;
|
74 | }
|
75 | const text = `$(codicon-sync~spin) ${message}`;
|
76 | this.statusBar.setElement(this.id, {
|
77 | text,
|
78 | alignment: StatusBarAlignment.LEFT,
|
79 | priority: 1
|
80 | });
|
81 | }
|
82 |
|
83 | }
|