import { ChangeDetectorRef , HostListener , Injectable , OnDestroy , ViewRef } from '@angular/core' ; import { Observable , pipe , Subject , UnaryFunction } from 'rxjs' ; import { debounceTime , distinctUntilChanged , map , takeUntil , tap } from 'rxjs/operators' ; import { Preferences } from '../models/preferences' ; import { AppUiStoreFacadeService } from '../services/ui-store/app-ui-store-facade.service' ; import { cdLog } from '../services/ui-store/app-ui-store.service' ; import { arraysEqual } from '../services/utils' ; @ Injectable ( ) export abstract class AbstractSubscriptionComponent implements OnDestroy { protected destroyed$ = new Subject < void > ( ) ; constructor ( protected readonly store , protected readonly cdr ) { } @ HostListener ( 'window:beforeunload' ) ngOnDestroy ( ) { this . destroyed$ . next ( ) ; this . destroyed$ . complete ( ) ; } protected listenForBasicPref$ < T > ( selector , ... logArgs ) { return this . store . listenPrefs$ ( ( prefs ) => selector ( prefs ) ) . pipe ( this . mapData ( ( [ pref ] ) => pref ) ) ; } protected mapData < T , R > ( extractor , equality = null , debounceTimeMs = 100 ) { return pipe ( debounceTime ( debounceTimeMs ) , distinctUntilChanged ( ( a , b ) => arraysEqual ( a , b ) ) , map ( extractor ) , distinctUntilChanged ( equality ?? ( ( a , b ) => arraysEqual ( a , b ) ) ) , tap ( ( filter ) => setTimeout ( ( ) => { if ( ! ( this . cdr as ViewRef ) ?. destroyed ) { this . cdr . detectChanges ( ) ; } } , 0 ) ) , tap ( ( filter ) => cdLog ( 'emitting value in ' , this . constructor . name , filter ) ) , takeUntil ( this . destroyed$ ) ) ; } }