import ServiceElectron , { IPCMessages as IPCElectronMessages } from '../../services/service.electron' ; import Logger from '../../tools/env.logger' ; const CSettings = { notificationDelayOnStream : 1000 , } ; interface IProgress { name : string ; progress : number ; started : number ; } export default class ProgressState { private _streamId : string ; private _tracks : Map < string , IProgress > = new Map ( ) ; private _timer : any ; private _last : number = Date . now ( ) ; private _logger : Logger ; constructor ( streamId ) { this . _streamId = streamId ; this . _logger = new Logger ( `ProgressState: ${ this . _streamId }` ) ; } public destroy ( ) { clearTimeout ( this . _timer ) ; this . _tracks . clear ( ) ; } public add ( id , name ) { if ( this . _tracks . has ( id ) ) { return ; } this . _tracks . set ( id , { name : name , progress : - 1 , started : Date . now ( ) , } ) ; } public remove ( id ) { const track = this . _tracks . get ( id ) ; if ( track === undefined ) { return ; } this . _logger . verbose ( `Task "${ track . name }" done in: ${ ( ( Date . now ( ) - track . started ) / 1000 ) . toFixed ( 2 ) }s` ) ; this . _tracks . delete ( id ) ; if ( this . _tracks . size === 0 ) { this . _logger . verbose ( `No states.` ) ; } this . _notify ( ) ; } public next ( id , progress ) { const track = this . _tracks . get ( id ) ; if ( track === undefined ) { return ; } if ( track . progress === progress ) { return ; } if ( progress < 0 || progress > 1 ) { return ; } track . progress = progress ; this . _tracks . set ( id , track ) ; this . _notify ( ) ; } private _notify ( ) { const send = ( ) => { ServiceElectron . IPC . send ( new IPCElectronMessages . StreamProgressState ( { streamId : this . _streamId , tracks : Array . from ( this . _tracks . values ( ) ) , } ) ) . catch ( ( error ) => { this . _logger . warn ( `Fail to send StreamProgressState due error: ${ error . message }` ) ; } ) . finally ( ( ) => { this . _last = Date . now ( ) ; } ) ; } ; clearTimeout ( this . _timer ) ; const past = Date . now ( ) - this . _last ; if ( past > CSettings . notificationDelayOnStream ) { send ( ) ; } else { this . _timer = setTimeout ( ( ) => { send ( ) ; } , CSettings . notificationDelayOnStream - past ) ; } } }