import { fromEvent , Observable , Subject , Subscription } from 'rxjs' ; import { auditTime } from 'rxjs/operators' ; import { Directive , NgZone , OnDestroy } from '@angular/core' ; const DEFAULT_EVENT_TIME = 100 ; @ Directive ( ) export abstract class ThyEventDispatcher implements OnDestroy { private _globalSubscription : Subscription = null ; private _event$ = new Subject < Event > ( ) ; private _subscriptionCount = 0 ; private _addGlobalListener ( ) { this . _globalSubscription = this . ngZone . runOutsideAngular ( ( ) => { return fromEvent ( this . document , this . eventName ) . subscribe ( ( event ) => { this . _event$ . next ( event ) ; } ) ; } ) ; } private _removeGlobalListener ( ) { if ( this . _globalSubscription ) { this . _globalSubscription . unsubscribe ( ) ; this . _globalSubscription = null ; } } get globalSubscription ( ) : Subscription { return this . _globalSubscription ; } constructor ( private document , private ngZone , private eventName ) { } protected subscribe ( auditTimeInMs = DEFAULT_EVENT_TIME ) { return new Observable ( observer => { if ( ! this . _globalSubscription ) { this . _addGlobalListener ( ) ; } const subscription = auditTimeInMs > 0 ? this . _event$ . pipe ( auditTime ( auditTimeInMs ) ) . subscribe ( observer ) : this . _event$ . subscribe ( observer ) ; this . _subscriptionCount ++ ; return ( ) => { subscription . unsubscribe ( ) ; this . _subscriptionCount -- ; if ( ! this . _subscriptionCount ) { this . _removeGlobalListener ( ) ; } } ; } ) ; } ngOnDestroy ( ) { this . _removeGlobalListener ( ) ; this . _event$ . complete ( ) ; } }