Skip to content

Commit

Permalink
Move progress status bar item to core
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Tugarev <alex.tugarev@typefox.io>
  • Loading branch information
AlexTugarev committed Aug 17, 2019
1 parent 0bad057 commit 0eebcf3
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 2 deletions.
6 changes: 5 additions & 1 deletion packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ import { DialogOverlayService } from './dialogs';
import { ProgressLocationService } from './progress-location-service';
import { ProgressClient } from '../common/progress-service-protocol';
import { ProgressService } from '../common/progress-service';
import { DispatchingProgressClient } from './progress-client';
import { ProgressStatusBarItem } from './progress-status-bar-item';

export const frontendApplicationModule = new ContainerModule((bind, unbind, isBound, rebind) => {
const themeService = ThemeService.get();
Expand Down Expand Up @@ -261,8 +263,10 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
bind(DialogOverlayService).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(DialogOverlayService);

bind(DispatchingProgressClient).toSelf().inSingletonScope();
bind(ProgressLocationService).toSelf().inSingletonScope();
bind(ProgressClient).toService(ProgressLocationService);
bind(ProgressStatusBarItem).toSelf().inSingletonScope();
bind(ProgressClient).toService(DispatchingProgressClient);
bind(ProgressService).toSelf().inSingletonScope();
});

Expand Down
53 changes: 53 additions & 0 deletions packages/core/src/browser/progress-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable, inject } from 'inversify';
import { CancellationToken } from '../common/cancellation';
import { ProgressClient } from '../common/progress-service-protocol';
import { ProgressMessage, ProgressUpdate } from '../common/message-service-protocol';
import { ProgressStatusBarItem } from './progress-status-bar-item';
import { ProgressLocationService } from './progress-location-service';

@injectable()
export class DispatchingProgressClient implements ProgressClient {

@inject(ProgressStatusBarItem)
protected statusBarItem: ProgressStatusBarItem;

@inject(ProgressLocationService)
protected locationService: ProgressLocationService;

showProgress(progressId: string, message: ProgressMessage, cancellationToken: CancellationToken): Promise<string | undefined> {
const locationId = this.getLocationId(message);
if (locationId === 'window') {
return this.statusBarItem.showProgress(progressId, message, cancellationToken);
}
return this.locationService.showProgress(progressId, message, cancellationToken);
}

reportProgress(progressId: string, update: ProgressUpdate, message: ProgressMessage, cancellationToken: CancellationToken): Promise<void> {
const locationId = this.getLocationId(message);
if (locationId === 'window') {
return this.statusBarItem.reportProgress(progressId, update, message, cancellationToken);
}
return this.locationService.reportProgress(progressId, update, message, cancellationToken);
}

protected getLocationId(message: ProgressMessage): string {
return message.options && message.options.location || 'unknownLocation';
}

}
78 changes: 78 additions & 0 deletions packages/core/src/browser/progress-status-bar-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable, inject } from 'inversify';
import { CancellationToken } from 'vscode-jsonrpc';
import { ProgressClient } from '../common';
import { ProgressMessage, ProgressUpdate } from '../common';
import { StatusBar, StatusBarAlignment } from './status-bar';
import { Deferred } from '../common/promise-util';
import throttle = require('lodash.throttle');

@injectable()
export class ProgressStatusBarItem implements ProgressClient {

protected readonly id = 'theia-progress-status-bar-item';

@inject(StatusBar)
protected readonly statusBar: StatusBar;

showProgress(progressId: string, message: ProgressMessage, cancellationToken: CancellationToken): Promise<string | undefined> {
const result = new Deferred<string | undefined>();
cancellationToken.onCancellationRequested(() => {
this.processEvent(progressId, 'done');
result.resolve(ProgressMessage.Cancel);
});
this.processEvent(progressId, 'start', message.text);
return result.promise;
}
protected messagesByProgress = new Map<string, string | undefined>();
protected incomingQueue = new Array<string>();
protected processEvent(progressId: string, event: 'start' | 'done', message?: string): void {
if (event === 'start') {
this.incomingQueue.push(progressId);
this.messagesByProgress.set(progressId, message);
} else {
this.incomingQueue = this.incomingQueue.filter(id => id !== progressId);
}
this.triggerUpdate();
}
protected readonly triggerUpdate = throttle(() => {
const pick: string | undefined = this.incomingQueue.slice(-1)[0];
this.update(pick);
}, 250, { leading: true, trailing: true });

async reportProgress(progressId: string, update: ProgressUpdate, originalMessage: ProgressMessage, _cancellationToken: CancellationToken): Promise<void> {
const newMessage = update.message ? `${originalMessage.text}: ${update.message}` : originalMessage.text;
this.messagesByProgress.set(progressId, newMessage);
this.triggerUpdate();
}

protected update(progressId: string | undefined): void {
const message = progressId && this.messagesByProgress.get(progressId);
if (!progressId || !message) {
this.statusBar.removeElement(this.id);
return;
}
const text = `$(refresh~spin) ${message}`;
this.statusBar.setElement(this.id, {
text,
alignment: StatusBarAlignment.LEFT,
priority: 1
});
}

}
2 changes: 1 addition & 1 deletion packages/core/src/browser/style/progress-bar.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

.theia-progress-bar {
background-color: var(--theia-accent-color1);
background-color: var(--theia-brand-color0);
height: 2px;
width: 3%;
animation: progress-animation 1.3s 0s infinite cubic-bezier(0.645, 0.045, 0.355, 1);
Expand Down

0 comments on commit 0eebcf3

Please sign in to comment.