-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmediacheck.service.ts
101 lines (93 loc) · 3.22 KB
/
mediacheck.service.ts
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
import { Injectable, NgZone } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class MediacheckService {
mqueries: { [key: string]: string; } = {
small: '(max-width: 767px)',
large: '(min-width: 768px)'
};
mq: string;
mq$: BehaviorSubject<string>;
constructor(private zone: NgZone) {}
// If you'd like to customize the object containing
// media queries, pass your new object to this method.
setQueries(newQueries: { [key: string]: string; }) {
this.mqueries = Object.assign({}, newQueries);
}
// Set mq$ / mq values
private _setMq(value: string) {
this.mq$.next(value);
this.mq = value;
}
// Call this method to automatically initialize mq$ subject.
// This will allow components to subscribe to mq$ to get the
// current breakpoint whenever it changes. This needs to be
// run AFTER setQueries(), if custom breakpoints are used.
initSubject() {
const nKeys = Object.keys(this.mqueries).length;
this.mq = this.getMqName();
this.mq$ = new BehaviorSubject<string>(this.mq);
switch (true) {
case nKeys > 2:
for (const key in this.mqueries) {
if (this.mqueries.hasOwnProperty(key)) {
const mqlist = window.matchMedia(this.mqueries[key]);
mqlist.addListener((mqlParam) => {
if (window.matchMedia(this.mqueries[key]).matches) {
this.zone.run(() => {
this._setMq(key);
});
}
});
}
}
break;
case nKeys === 2:
const firstQueryName = Object.keys(this.mqueries)[0];
const secondQueryName = Object.keys(this.mqueries)[1];
const mql = window.matchMedia(this.mqueries[firstQueryName]);
mql.addListener((mqlParam) => {
const currentQuery = window.matchMedia(this.mqueries[firstQueryName]).matches ? firstQueryName : secondQueryName;
this.zone.run(() => {
this._setMq(currentQuery);
});
});
break;
default:
console.warn(`You must define 2 or more breakpoints. You have only set ${nKeys}.`);
}
}
// Runs matchMedia to check if active breakpoint
// is the same as the one passed into the method.
check(mqName: string): boolean {
if (!this.mqueries[mqName]) {
console.warn(`No media query registered for "${mqName}"!`);
}
return window.matchMedia(this.mqueries[mqName]).matches;
}
// Get the name of the currently active breakpoint.
getMqName(): string {
for (const key in this.mqueries) {
if (window.matchMedia(this.mqueries[key]).matches) {
return key;
}
}
}
// Use this method to manually set up listeners
// with callbacks for specific breakpoints.
onMqChange(mqName: string, callback: any) {
if (typeof callback === 'function') {
const mql = window.matchMedia(this.mqueries[mqName]);
// if listener is already in list, this has no effect
mql.addListener((mqlParam) => {
this.zone.run(() => {
if (mqlParam.matches) {
callback(mqlParam);
}
});
});
} else {
console.warn(`No valid callback function has been provided for "${mqName}"!`);
}
}
}