import { Injectable , ComponentRef } from '@angular/core' ; import { InjectionService } from '../../services/injection/injection.service' ; import { LoadingComponent } from './loading.component' ; @ Injectable ( { providedIn : 'root' } ) export class LoadingService { threshold = 250 ; set progress ( val ) { if ( this . instance ) { this . instance . progress = val ; } this . _progress = val ; } get progress ( ) : number { return this . _progress ; } get count ( ) : number { return this . _count ; } private get instance ( ) { if ( this . component ) return this . component . instance ; } private _count = 0 ; private timeout : any ; private component : ComponentRef < LoadingComponent > ; private _progress = 0 ; constructor ( private readonly injectionService ) { } start ( autoIncrement = true ) { this . create ( ) ; this . _count ++ ; if ( autoIncrement ) { clearTimeout ( this . timeout ) ; const fn = ( ) => { this . increment ( ) ; if ( this . progress < 100 ) { this . timeout = setTimeout ( fn , this . threshold ) ; } else { this . complete ( ) ; } } ; this . timeout = setTimeout ( fn , this . threshold ) ; } } stop ( ) { this . _count -- ; clearTimeout ( this . timeout ) ; } reset ( num = 0 ) { this . progress = num ; } complete ( all = false ) { this . _count -- ; if ( this . count <= 0 || all ) { this . progress = 100 ; this . _count = 0 ; setTimeout ( ( ) => { this . hide ( ) ; this . progress = 0 ; } , this . threshold * 2 ) ; } } hide ( ) { this . stop ( ) ; if ( this . instance ) { this . instance . visible = false ; } } private create ( ) { if ( ! this . component ) { this . component = this . injectionService . appendComponent ( LoadingComponent ) ; } this . instance . visible = true ; this . instance . progress = this . progress ; return this . component ; } private increment ( ) { if ( this . progress >= 100 ) return ; const stat = this . progress / 100 ; let rnd = 0 ; if ( stat >= 0 && stat < 0.25 ) { rnd = ( Math . random ( ) * ( 5 - 3 + 1 ) + 3 ) / 100 ; } else if ( stat >= 0.25 && stat < 0.65 ) { rnd = ( Math . random ( ) * 3 ) / 100 ; } else if ( stat >= 0.65 && stat < 0.9 ) { rnd = ( Math . random ( ) * 2 ) / 100 ; } else { rnd = 0.005 ; } this . progress = ( stat + rnd ) * 100 ; } }