import { Injectable , OnDestroy } from '@angular/core' ; import { DaBreakpoint , DaBreakpoints , DaBreakpointsMap } from './layout.types' ; import { fromEvent , ReplaySubject , Subject } from 'rxjs' ; import { takeUntil } from 'rxjs/operators' ; @ Injectable ( { providedIn : 'root' } ) export class DaScreenMediaQueryService implements OnDestroy { private currentPoint : DaBreakpoint ; private pointChangeSub : ReplaySubject < { currentPoint : DaBreakpoint ; change : number ; compare : { [ key ] : number ; } ; } > = new ReplaySubject ( 1 ) ; private destroy$ = new Subject ( ) ; public getPoint ( ) { if ( ! this . currentPoint ) { this . currentPoint = this . getCurrentPoint ( ) ! ; this . pointChangeSub . next ( { currentPoint : this . currentPoint , change : 0 , compare : this . comparePoints ( this . currentPoint ) , } ) ; fromEvent ( window , 'resize' ) . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( ) => { const tempPoint = this . getCurrentPoint ( ) ! ; if ( this . currentPoint !== tempPoint ) { const change = this . comparePoints ( tempPoint , this . currentPoint ) as number ; this . currentPoint = tempPoint ; this . pointChangeSub . next ( { currentPoint : this . currentPoint , change : change , compare : this . comparePoints ( tempPoint ) , } ) ; } } ) ; } return this . pointChangeSub ; } private comparePoints ( p1 , p2 ? ) { let index1 , index2 ; for ( let i = 0 ; i < DaBreakpoints . length ; i ++ ) { if ( p1 === DaBreakpoints [ i ] ) { index1 = i ; } if ( p2 === DaBreakpoints [ i ] ) { index2 = i ; } } if ( ! p2 ) { let res = { } ; DaBreakpoints . forEach ( ( point , index ) => { res [ point ] = index1 - index ; } ) ; return res ; } return index1 - index2 ; } private getCurrentPoint ( ) { const currentScreenWidth = window . innerWidth ; for ( let i = 0 ; i < DaBreakpoints . length ; i ++ ) { if ( DaBreakpointsMap [ DaBreakpoints [ i ] ] >= currentScreenWidth || i === DaBreakpoints . length - 1 ) { return DaBreakpoints [ i ] as DaBreakpoint ; } } return ; } ngOnDestroy ( ) { this . destroy$ . next ( ) ; this . destroy$ . complete ( ) ; } }