all files / common/core/media/ media.service.ts

75% Statements 24/32
100% Branches 4/4
55.56% Functions 5/9
77.78% Lines 21/27
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120                                                                                                                                                      32×     32×   32×   32× 32× 32× 32×   32× 128× 128× 32×       32× 45× 45×                                
/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
 
/* From Angular for infos
export const DEFAULT_BREAKPOINTS = [
    {
        alias: 'xs',
        mediaQuery: '(min-width: 0px) and (max-width: 599px)'
    },
    {
        alias: 'gt-xs',
        overlapping: true,
        mediaQuery: '(min-width: 600px)'
    },
    {
        alias: 'lt-sm',
        overlapping: true,
        mediaQuery: '(max-width: 599px)'
    },
    {
        alias: 'sm',
        mediaQuery: '(min-width: 600px) and (max-width: 959px)'
    },
    {
        alias: 'gt-sm',
        overlapping: true,
        mediaQuery: '(min-width: 960px)'
    },
    {
        alias: 'lt-md',
        overlapping: true,
        mediaQuery: '(max-width: 959px)'
    },
    {
        alias: 'md',
        mediaQuery: '(min-width: 960px) and (max-width: 1279px)'
    },
    {
        alias: 'gt-md',
        overlapping: true,
        mediaQuery: '(min-width: 1280px)'
    },
    {
        alias: 'lt-lg',
        overlapping: true,
        mediaQuery: '(max-width: 1279px)'
    },
    {
        alias: 'lg',
        mediaQuery: '(min-width: 1280px) and (max-width: 1919px)'
    },
    {
        alias: 'gt-lg',
        overlapping: true,
        mediaQuery: '(min-width: 1920px)'
    },
    {
        alias: 'lt-xl',
        overlapping: true,
        mediaQuery: '(max-width: 1920px)'
    },
    {
        alias: 'xl',
        mediaQuery: '(min-width: 1920px) and (max-width: 5000px)'
    }
];
*/
 
import { Injectable, NgZone, OnDestroy } from '@angular/core';
import { BehaviorSubject, from as observableFrom, Observable } from 'rxjs';
import { distinctUntilChanged, map, takeWhile } from 'rxjs/operators';
 
@Injectable()
export class MediaService implements OnDestroy {
    private isAlive = true;
    public isMobile$: Observable<boolean>;
    public mediaChanged$: BehaviorSubject<string>;
    public mql = {} as { [alias: string]: MediaQueryList };
 
    constructor(private zone: NgZone) {
 
        this.mql.xs = window.matchMedia('(max-width: 599px)');
        this.mql.sm = window.matchMedia('(min-width: 600px) and (max-width:959px)');
        this.mql.md = window.matchMedia('(min-width: 860px) and (max-width:1279px)');
        this.mql.lg = window.matchMedia('(min-width: 1280px)');
 
        Object.keys(this.mql).forEach((alias) => {
            this.mql[alias].addListener(this.onMQLEvent.bind(this, alias));
            if (this.mql[alias].matches) {
                this.mediaChanged$ = new BehaviorSubject(alias);
            }
        });
 
        this.isMobile$ = observableFrom(this.mediaChanged$).pipe(
            takeWhile(() => this.isAlive),
            map(() => this.mql.xs.matches || this.mql.sm.matches),
            distinctUntilChanged());
    }
 
    public ngOnDestroy() {
        Object.keys(this.mql).forEach((alias) => {
            this.mql[alias].removeListener(this.onMQLEvent as any);
            delete this.mql[alias];
        });
        this.isAlive = false;
    }
 
    private onMQLEvent(alias: string) {
        this.zone.run(() => {
            this.mediaChanged$.next(alias);
        });
    }
}