import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { filter, distinctUntilChanged, map } from 'rxjs/operators'; import { HostWindowState } from './search/host-window.reducer'; import { Injectable } from '@angular/core'; import { createSelector, select, Store } from '@ngrx/store'; import { hasValue } from './empty.util'; import { AppState } from '../app.reducer'; import { CSSVariableService } from './sass-helper/sass-helper.service'; export enum WidthCategory { XS, SM, MD, LG, XL } const hostWindowStateSelector = (state: AppState) => state.hostWindow; const widthSelector = createSelector(hostWindowStateSelector, (hostWindow: HostWindowState) => hostWindow.width); @Injectable() export class HostWindowService { private breakPoints: { XS_MIN, SM_MIN, MD_MIN, LG_MIN, XL_MIN } = {} as any; constructor( private store: Store<AppState>, private variableService: CSSVariableService ) { /* See _exposed_variables.scss */ variableService.getAllVariables() .subscribe((variables) => { this.breakPoints.XL_MIN = parseInt(variables.xlMin, 10); this.breakPoints.LG_MIN = parseInt(variables.lgMin, 10); this.breakPoints.MD_MIN = parseInt(variables.mdMin, 10); this.breakPoints.SM_MIN = parseInt(variables.smMin, 10); }); } private getWidthObs(): Observable<number> { return this.store.pipe( select(widthSelector), filter((width) => hasValue(width)) ); } get widthCategory(): Observable<WidthCategory> { return this.getWidthObs().pipe( map((width: number) => { if (width < this.breakPoints.SM_MIN) { return WidthCategory.XS } else if (width >= this.breakPoints.SM_MIN && width < this.breakPoints.MD_MIN) { return WidthCategory.SM } else if (width >= this.breakPoints.MD_MIN && width < this.breakPoints.LG_MIN) { return WidthCategory.MD } else if (width >= this.breakPoints.LG_MIN && width < this.breakPoints.XL_MIN) { return WidthCategory.LG } else { return WidthCategory.XL } }), distinctUntilChanged() ); } isXs(): Observable<boolean> { return this.widthCategory.pipe( map((widthCat: WidthCategory) => widthCat === WidthCategory.XS), distinctUntilChanged() ); } isSm(): Observable<boolean> { return this.widthCategory.pipe( map((widthCat: WidthCategory) => widthCat === WidthCategory.SM), distinctUntilChanged() ); } isMd(): Observable<boolean> { return this.widthCategory.pipe( map((widthCat: WidthCategory) => widthCat === WidthCategory.MD), distinctUntilChanged() ); } isLg(): Observable<boolean> { return this.widthCategory.pipe( map((widthCat: WidthCategory) => widthCat === WidthCategory.LG), distinctUntilChanged() ); } isXl(): Observable<boolean> { return this.widthCategory.pipe( map((widthCat: WidthCategory) => widthCat === WidthCategory.XL), distinctUntilChanged() ); } isXsOrSm(): Observable<boolean> { return observableCombineLatest( this.isXs(), this.isSm() ).pipe( map(([isXs, isSm]) => isXs || isSm), distinctUntilChanged() ); } }