import { v4 } from "uuid" ; import { CancellationToken , CancellationTokenSource , Disposable , EventEmitter , ProgressLocation , StatusBarAlignment , StatusBarItem , window , workspace } from "vscode" ; import { IProgressProvider , IProgressReporter } from "./progressAPI" ; const STATUS_COMMAND = "java.show.server.task.status" ; class ProgressReporter implements IProgressReporter { private _id : string = v4 ( ) ; private _jobName : string ; private _progressLocation : ProgressLocation | { viewId : string ; } ; private _cancellable : boolean = false ; private _message : string ; private _increment : number | undefined ; private _isShown : boolean ; private _tokenSource = new CancellationTokenSource ( ) ; private _statusBarItem : StatusBarItem | undefined ; private _cancelProgressEventEmitter : EventEmitter < void > ; private _progressEventEmitter : EventEmitter < void > ; private _disposables : Disposable [ ] = [ ] ; constructor ( jobName , progressLocation , cancellable ) { this . _jobName = jobName ; this . _progressLocation = progressLocation || ProgressLocation . Notification ; this . _cancellable = cancellable ; const config = workspace . getConfiguration ( "java" ) ; if ( config . silentNotification && this . _progressLocation === ProgressLocation . Notification ) { this . _progressLocation = ProgressLocation . Window ; } if ( this . _progressLocation === ProgressLocation . Window ) { this . _statusBarItem = window . createStatusBarItem ( this . _id , StatusBarAlignment . Left , 1 ) ; this . _statusBarItem . name = "Progress Message for " + this . _jobName ; this . _statusBarItem . text = `$(sync~spin) ${ this . _jobName }...` ; this . _statusBarItem . command = { title : "Check Java Build Status" , command : STATUS_COMMAND , arguments : [ ] , } ; this . _statusBarItem . tooltip = "Check Java Build Status" ; this . _disposables . push ( this . _statusBarItem ) ; } this . _cancelProgressEventEmitter = new EventEmitter < any > ( ) ; this . _progressEventEmitter = new EventEmitter < any > ( ) ; this . _disposables . push ( this . _cancelProgressEventEmitter ) ; this . _disposables . push ( this . _progressEventEmitter ) ; this . _disposables . push ( this . _tokenSource ) ; } public getId ( ) { return this . _id ; } public getProgressLocation ( ) { return this . _progressLocation ; } public report ( message , increment ? ) { if ( this . _statusBarItem ) { const text = message ? `${ this . _jobName } - ${ message }` : `${ this . _jobName }...` ; this . _statusBarItem . text = `$(sync~spin) ${ text }` ; } this . _message = message ; this . _increment = increment ; this . _progressEventEmitter . fire ( ) ; this . show ( ) ; } public show ( ) { if ( this . _statusBarItem ) { this . _statusBarItem . show ( ) ; return ; } this . showNativeProgress ( ) ; } public hide ( onlyNotifications ? ) { if ( onlyNotifications && this . _progressLocation === ProgressLocation . Notification ) { this . _cancelProgressEventEmitter . fire ( ) ; this . _isShown = false ; } } public isCancelled ( ) { return this . getCancellationToken ( ) . isCancellationRequested ; } public done ( ) { this . _tokenSource . cancel ( ) ; this . _cancelProgressEventEmitter . fire ( ) ; this . _statusBarItem ?. hide ( ) ; this . _disposables . forEach ( ( disposable ) => disposable . dispose ( ) ) ; ( < ProgressProvider > progressProvider ) . remove ( this ) ; } public getCancellationToken ( ) { return this . _tokenSource . token ; } public observe ( token ? ) { token ?. onCancellationRequested ( ( ) => { this . done ( ) ; } ) ; } private showNativeProgress ( ) { if ( this . _isShown ) { return ; } this . _isShown = true ; window . withProgress < boolean > ( { location : this . _progressLocation , title : this . _jobName ? `[${ this . _jobName }](command:${ STATUS_COMMAND })` : undefined , cancellable : this . _cancellable , } , ( progress , token ) => { progress . report ( { message : this . _message , increment : this . _increment , } ) ; this . observe ( token ) ; this . _progressEventEmitter . event ( ( ) => { progress . report ( { message : this . _message , increment : this . _increment , } ) ; } ) ; return new Promise ( ( resolve ) => { this . _cancelProgressEventEmitter . event ( ( ) => { resolve ( true ) ; } ) ; } ) ; } ) ; } } class ProgressProvider implements IProgressProvider { private store : { [ key ] : IProgressReporter ; } = { } ; public createProgressReporter ( jobName , progressLocation ? , cancellable ? ) { const progressReporter = new ProgressReporter ( jobName , progressLocation || ProgressLocation . Notification , cancellable === undefined ? true : ! ! cancellable ) ; this . store [ progressReporter . getId ( ) ] = progressReporter ; return progressReporter ; } public getProgressReporter ( progressId ) { return this . store [ progressId ] ; } public remove ( progressReporter ) { delete this . store [ progressReporter . getId ( ) ] ; } } export const progressProvider = new ProgressProvider ( ) ;