import { BehaviorSubject , interval , Observable , Subscription , timer } from 'rxjs' ; import { delay } from 'rxjs/operators' ; export class ProgressBarInstance { public static readonly INIT_VALUE : number = 0 ; public static readonly MIN_VALUE : number = ProgressBarInstance . INIT_VALUE ; public static readonly MAX_VALUE : number = 100 ; private worker : Subscription = Subscription . EMPTY ; private _state : BehaviorSubject < ProgressBarState > ; constructor ( ) { this . _state = new BehaviorSubject < ProgressBarState > ( { value : 0 } ) ; this . worker = Subscription . EMPTY ; } public get state ( ) : Observable < ProgressBarState > { return this . _state . asObservable ( ) ; } param startDelay public start ( startDelay = 100 ) { this . _state . next ( { value : ProgressBarInstance . INIT_VALUE } ) ; this . worker = interval ( 10 ) . pipe ( delay ( startDelay ) ) . subscribe ( ( val ) => { this . _state . next ( { value : this . increment ( ) } ) ; } ) ; } /**
     * Finish the bar increment.
     */ public complete ( ) { this . worker . unsubscribe ( ) ; if ( this . _state . value . value > 0 ) { this . _state . next ( { value : 100 } ) ; } const completeTimeout = timer ( 350 ) . subscribe ( ( ) => { this . _state . next ( { value : 0 } ) ; } ) . add ( ( ) => completeTimeout . unsubscribe ( ) ) ; } param rnd private private increment ( rnd = ProgressBarInstance . INIT_VALUE ) { const stat = this . _state . value . value ; if ( stat >= ProgressBarInstance . MAX_VALUE ) { rnd = 0 ; } if ( rnd === ProgressBarInstance . MIN_VALUE ) { if ( stat >= 0 && stat < 25 ) { rnd = Math . random ( ) * ( 5 - 3 + 1 ) + 3 ; } else if ( stat >= 25 && stat < 65 ) { rnd = Math . random ( ) * 3 ; } else if ( stat >= 65 && stat < 90 ) { rnd = Math . random ( ) * 2 ; } else if ( stat >= 90 && stat < 99 ) { rnd = 0.5 ; } else { rnd = 0 ; } } return rnd + stat ; } } export interface ProgressBarState { value : number ; }