66import 'vs/css!./media/progressService' ;
77
88import { localize } from 'vs/nls' ;
9- import { IDisposable , dispose , DisposableStore , MutableDisposable } from 'vs/base/common/lifecycle' ;
10- import { IProgressService , IProgressOptions , IProgressStep , ProgressLocation , IProgress , emptyProgress , Progress , IProgressCompositeOptions , IProgressNotificationOptions } from 'vs/platform/progress/common/progress' ;
9+ import { IDisposable , dispose , DisposableStore , MutableDisposable , Disposable } from 'vs/base/common/lifecycle' ;
10+ import { IProgressService , IProgressOptions , IProgressStep , ProgressLocation , IProgress , Progress , IProgressCompositeOptions , IProgressNotificationOptions , IProgressRunner , ILocalProgressService } from 'vs/platform/progress/common/progress' ;
1111import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet' ;
1212import { StatusbarAlignment , IStatusbarService } from 'vs/platform/statusbar/common/statusbar' ;
1313import { timeout } from 'vs/base/common/async' ;
@@ -26,90 +26,88 @@ import { EventHelper } from 'vs/base/browser/dom';
2626import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation' ;
2727import { IPanelService } from 'vs/workbench/services/panel/common/panelService' ;
2828
29- export class ProgressService implements IProgressService , IDisposable {
29+ export class ProgressService extends Disposable implements IProgressService {
3030
3131 _serviceBrand : ServiceIdentifier < IProgressService > ;
3232
33- private readonly _stack : [ IProgressOptions , Progress < IProgressStep > ] [ ] = [ ] ;
34- private readonly _globalStatusEntry = new MutableDisposable ( ) ;
33+ private readonly stack : [ IProgressOptions , Progress < IProgressStep > ] [ ] = [ ] ;
34+ private readonly globalStatusEntry = this . _register ( new MutableDisposable ( ) ) ;
3535
3636 constructor (
37- @IActivityService private readonly _activityBar : IActivityService ,
38- @IViewletService private readonly _viewletService : IViewletService ,
39- @IPanelService private readonly _panelService : IPanelService ,
40- @INotificationService private readonly _notificationService : INotificationService ,
41- @IStatusbarService private readonly _statusbarService : IStatusbarService ,
42- @ILayoutService private readonly _layoutService : ILayoutService ,
43- @IThemeService private readonly _themeService : IThemeService ,
44- @IKeybindingService private readonly _keybindingService : IKeybindingService
45- ) { }
46-
47- dispose ( ) {
48- this . _globalStatusEntry . dispose ( ) ;
37+ @IActivityService private readonly activityService : IActivityService ,
38+ @IViewletService private readonly viewletService : IViewletService ,
39+ @IPanelService private readonly panelService : IPanelService ,
40+ @INotificationService private readonly notificationService : INotificationService ,
41+ @IStatusbarService private readonly statusbarService : IStatusbarService ,
42+ @ILayoutService private readonly layoutService : ILayoutService ,
43+ @IThemeService private readonly themeService : IThemeService ,
44+ @IKeybindingService private readonly keybindingService : IKeybindingService
45+ ) {
46+ super ( ) ;
4947 }
5048
5149 withProgress < R = unknown > ( options : IProgressOptions , task : ( progress : IProgress < IProgressStep > ) => Promise < R > , onDidCancel ?: ( ) => void ) : Promise < R > {
5250 const { location } = options ;
5351 if ( typeof location === 'string' ) {
54- if ( this . _viewletService . getProgressIndicator ( location ) ) {
55- return this . _withViewletProgress ( location , task , { ...options , location } ) ;
52+ if ( this . viewletService . getProgressIndicator ( location ) ) {
53+ return this . withViewletProgress ( location , task , { ...options , location } ) ;
5654 }
5755
58- if ( this . _panelService . getProgressIndicator ( location ) ) {
59- return this . _withPanelProgress ( location , task , { ...options , location } ) ;
56+ if ( this . panelService . getProgressIndicator ( location ) ) {
57+ return this . withPanelProgress ( location , task , { ...options , location } ) ;
6058 }
6159
6260 return Promise . reject ( new Error ( `Bad progress location: ${ location } ` ) ) ;
6361 }
6462
6563 switch ( location ) {
6664 case ProgressLocation . Notification :
67- return this . _withNotificationProgress ( { ...options , location } , task , onDidCancel ) ;
65+ return this . withNotificationProgress ( { ...options , location } , task , onDidCancel ) ;
6866 case ProgressLocation . Window :
69- return this . _withWindowProgress ( options , task ) ;
67+ return this . withWindowProgress ( options , task ) ;
7068 case ProgressLocation . Explorer :
71- return this . _withViewletProgress ( 'workbench.view.explorer' , task , { ...options , location } ) ;
69+ return this . withViewletProgress ( 'workbench.view.explorer' , task , { ...options , location } ) ;
7270 case ProgressLocation . Scm :
73- return this . _withViewletProgress ( 'workbench.view.scm' , task , { ...options , location } ) ;
71+ return this . withViewletProgress ( 'workbench.view.scm' , task , { ...options , location } ) ;
7472 case ProgressLocation . Extensions :
75- return this . _withViewletProgress ( 'workbench.view.extensions' , task , { ...options , location } ) ;
73+ return this . withViewletProgress ( 'workbench.view.extensions' , task , { ...options , location } ) ;
7674 case ProgressLocation . Dialog :
77- return this . _withDialogProgress ( options , task , onDidCancel ) ;
75+ return this . withDialogProgress ( options , task , onDidCancel ) ;
7876 default :
7977 return Promise . reject ( new Error ( `Bad progress location: ${ location } ` ) ) ;
8078 }
8179 }
8280
83- private _withWindowProgress < R = unknown > ( options : IProgressOptions , callback : ( progress : IProgress < { message ?: string } > ) => Promise < R > ) : Promise < R > {
84- const task : [ IProgressOptions , Progress < IProgressStep > ] = [ options , new Progress < IProgressStep > ( ( ) => this . _updateWindowProgress ( ) ) ] ;
81+ private withWindowProgress < R = unknown > ( options : IProgressOptions , callback : ( progress : IProgress < { message ?: string } > ) => Promise < R > ) : Promise < R > {
82+ const task : [ IProgressOptions , Progress < IProgressStep > ] = [ options , new Progress < IProgressStep > ( ( ) => this . updateWindowProgress ( ) ) ] ;
8583
8684 const promise = callback ( task [ 1 ] ) ;
8785
8886 let delayHandle : any = setTimeout ( ( ) => {
8987 delayHandle = undefined ;
90- this . _stack . unshift ( task ) ;
91- this . _updateWindowProgress ( ) ;
88+ this . stack . unshift ( task ) ;
89+ this . updateWindowProgress ( ) ;
9290
9391 // show progress for at least 150ms
9492 Promise . all ( [
9593 timeout ( 150 ) ,
9694 promise
9795 ] ) . finally ( ( ) => {
98- const idx = this . _stack . indexOf ( task ) ;
99- this . _stack . splice ( idx , 1 ) ;
100- this . _updateWindowProgress ( ) ;
96+ const idx = this . stack . indexOf ( task ) ;
97+ this . stack . splice ( idx , 1 ) ;
98+ this . updateWindowProgress ( ) ;
10199 } ) ;
102100 } , 150 ) ;
103101
104102 // cancel delay if promise finishes below 150ms
105103 return promise . finally ( ( ) => clearTimeout ( delayHandle ) ) ;
106104 }
107105
108- private _updateWindowProgress ( idx : number = 0 ) {
109- this . _globalStatusEntry . clear ( ) ;
106+ private updateWindowProgress ( idx : number = 0 ) {
107+ this . globalStatusEntry . clear ( ) ;
110108
111- if ( idx < this . _stack . length ) {
112- const [ options , progress ] = this . _stack [ idx ] ;
109+ if ( idx < this . stack . length ) {
110+ const [ options , progress ] = this . stack [ idx ] ;
113111
114112 let progressTitle = options . title ;
115113 let progressMessage = progress . value && progress . value . message ;
@@ -133,18 +131,18 @@ export class ProgressService implements IProgressService, IDisposable {
133131
134132 } else {
135133 // no title, no message -> no progress. try with next on stack
136- this . _updateWindowProgress ( idx + 1 ) ;
134+ this . updateWindowProgress ( idx + 1 ) ;
137135 return ;
138136 }
139137
140- this . _globalStatusEntry . value = this . _statusbarService . addEntry ( {
138+ this . globalStatusEntry . value = this . statusbarService . addEntry ( {
141139 text : `$(sync~spin) ${ text } ` ,
142140 tooltip : title
143141 } , 'status.progress' , localize ( 'status.progress' , "Progress Message" ) , StatusbarAlignment . LEFT ) ;
144142 }
145143 }
146144
147- private _withNotificationProgress < P extends Promise < R > , R = unknown > ( options : IProgressNotificationOptions , callback : ( progress : IProgress < { message ?: string , increment ?: number } > ) => P , onDidCancel ?: ( ) => void ) : P {
145+ private withNotificationProgress < P extends Promise < R > , R = unknown > ( options : IProgressNotificationOptions , callback : ( progress : IProgress < { message ?: string , increment ?: number } > ) => P , onDidCancel ?: ( ) => void ) : P {
148146 const toDispose = new DisposableStore ( ) ;
149147
150148 const createNotification = ( message : string | undefined , increment ?: number ) : INotificationHandle | undefined => {
@@ -174,7 +172,7 @@ export class ProgressService implements IProgressService, IDisposable {
174172 }
175173
176174 const actions : INotificationActions = { primary : primaryActions , secondary : secondaryActions } ;
177- const handle = this . _notificationService . notify ( {
175+ const handle = this . notificationService . notify ( {
178176 severity : Severity . Info ,
179177 message,
180178 source : options . source ,
@@ -241,21 +239,17 @@ export class ProgressService implements IProgressService, IDisposable {
241239 return promise ;
242240 }
243241
244- private _withViewletProgress < P extends Promise < R > , R = unknown > ( viewletId : string , task : ( progress : IProgress < { message ?: string } > ) => P , options : IProgressCompositeOptions ) : P {
245- const promise = task ( emptyProgress ) ;
242+ private withViewletProgress < P extends Promise < R > , R = unknown > ( viewletId : string , task : ( progress : IProgress < IProgressStep > ) => P , options : IProgressCompositeOptions ) : P {
246243
247244 // show in viewlet
248- const viewletProgress = this . _viewletService . getProgressIndicator ( viewletId ) ;
249- if ( viewletProgress ) {
250- viewletProgress . showWhile ( promise , options . delay ) ;
251- }
245+ const promise = this . withCompositeProgress ( this . viewletService . getProgressIndicator ( viewletId ) , task , options ) ;
252246
253247 // show activity bar
254248 let activityProgress : IDisposable ;
255249 let delayHandle : any = setTimeout ( ( ) => {
256250 delayHandle = undefined ;
257251
258- const handle = this . _activityBar . showActivity (
252+ const handle = this . activityService . showActivity (
259253 viewletId ,
260254 new ProgressBadge ( ( ) => '' ) ,
261255 'progress-badge' ,
@@ -286,19 +280,39 @@ export class ProgressService implements IProgressService, IDisposable {
286280 return promise ;
287281 }
288282
289- private _withPanelProgress < P extends Promise < R > , R = unknown > ( panelid : string , task : ( progress : IProgress < { message ?: string } > ) => P , options : IProgressCompositeOptions ) : P {
290- const promise = task ( emptyProgress ) ;
283+ private withPanelProgress < P extends Promise < R > , R = unknown > ( panelid : string , task : ( progress : IProgress < IProgressStep > ) => P , options : IProgressCompositeOptions ) : P {
291284
292285 // show in panel
293- const panelProgress = this . _panelService . getProgressIndicator ( panelid ) ;
294- if ( panelProgress ) {
295- panelProgress . showWhile ( promise , options . delay ) ;
286+ return this . withCompositeProgress ( this . panelService . getProgressIndicator ( panelid ) , task , options ) ;
287+ }
288+
289+ private withCompositeProgress < P extends Promise < R > , R = unknown > ( compositeProgressService : ILocalProgressService | null , task : ( progress : IProgress < IProgressStep > ) => P , options : IProgressCompositeOptions ) : P {
290+ let progressRunner : IProgressRunner | undefined = undefined ;
291+
292+ const promise = task ( {
293+ report : progress => {
294+ if ( ! progressRunner ) {
295+ return ;
296+ }
297+
298+ if ( typeof progress . increment === 'number' ) {
299+ progressRunner . worked ( progress . increment ) ;
300+ }
301+ }
302+ } ) ;
303+
304+ if ( compositeProgressService ) {
305+ if ( typeof options . total === 'number' ) {
306+ progressRunner = compositeProgressService . show ( options . total , options . delay ) ;
307+ } else {
308+ compositeProgressService . showWhile ( promise , options . delay ) ;
309+ }
296310 }
297311
298312 return promise ;
299313 }
300314
301- private _withDialogProgress < P extends Promise < R > , R = unknown > ( options : IProgressOptions , task : ( progress : IProgress < { message ?: string , increment ?: number } > ) => P , onDidCancel ?: ( ) => void ) : P {
315+ private withDialogProgress < P extends Promise < R > , R = unknown > ( options : IProgressOptions , task : ( progress : IProgress < IProgressStep > ) => P , onDidCancel ?: ( ) => void ) : P {
302316 const disposables = new DisposableStore ( ) ;
303317 const allowableCommands = [
304318 'workbench.action.quit' ,
@@ -309,13 +323,13 @@ export class ProgressService implements IProgressService, IDisposable {
309323
310324 const createDialog = ( message : string ) => {
311325 dialog = new Dialog (
312- this . _layoutService . container ,
326+ this . layoutService . container ,
313327 message ,
314328 [ options . cancellable ? localize ( 'cancel' , "Cancel" ) : localize ( 'dismiss' , "Dismiss" ) ] ,
315329 {
316330 type : 'pending' ,
317331 keyEventProcessor : ( event : StandardKeyboardEvent ) => {
318- const resolved = this . _keybindingService . softDispatch ( event , this . _layoutService . container ) ;
332+ const resolved = this . keybindingService . softDispatch ( event , this . layoutService . container ) ;
319333 if ( resolved && resolved . commandId ) {
320334 if ( allowableCommands . indexOf ( resolved . commandId ) === - 1 ) {
321335 EventHelper . stop ( event , true ) ;
@@ -326,7 +340,7 @@ export class ProgressService implements IProgressService, IDisposable {
326340 ) ;
327341
328342 disposables . add ( dialog ) ;
329- disposables . add ( attachDialogStyler ( dialog , this . _themeService ) ) ;
343+ disposables . add ( attachDialogStyler ( dialog , this . themeService ) ) ;
330344
331345 dialog . show ( ) . then ( ( ) => {
332346 if ( typeof onDidCancel === 'function' ) {
0 commit comments