ngx-foldable
Version:
Angular library to help you build dual-screen experiences for foldable or dual-screen devices
96 lines • 11.9 kB
JavaScript
import { Injectable } from '@angular/core';
import { fromEvent, merge, ReplaySubject } from 'rxjs';
import { map, filter, shareReplay, startWith, takeUntil } from 'rxjs/operators';
import { dualVerticalViewport, dualHorizontalViewport } from './media-queries';
import { ScreenSpanning } from './screen-spanning';
import * as i0 from "@angular/core";
/**
* This service allows to query and receive updates about current device's
* screen context.
*
* See {@link ScreenContextData}
*/
export class ScreenContext {
constructor() {
this.destroyed$ = new ReplaySubject(1);
this.currentContext = this.getScreenContext();
this.screenContext$ = merge(fromEvent(matchMedia(dualVerticalViewport), 'change'), fromEvent(matchMedia(dualHorizontalViewport), 'change')).pipe(filter(() => this.getScreenSpanning() !== this.currentContext.screenSpanning), startWith(1), map(() => {
this.currentContext = this.getScreenContext();
return this.currentContext;
}), shareReplay(1), takeUntil(this.destroyed$));
this.screenContext$.subscribe();
}
/** @ignored */
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
/**
* The list of available window segments.
*/
get windowSegments() {
return this.currentContext.windowSegments;
}
/**
* The current screen spanning mode.
*/
get screenSpanning() {
return this.currentContext.screenSpanning;
}
/**
* True is current device have multiple screens available.
*/
get isMultiScreen() {
return this.currentContext.isMultiScreen;
}
/**
* Gets an observable emitting when the screen context changes.
*/
asObservable() {
return this.screenContext$;
}
/**
* Gets the current screen context.
*/
asObject() {
return this.currentContext;
}
getScreenContext() {
const windowSegments = this.getWindowSegments();
const screenSpanning = this.getScreenSpanning();
return {
windowSegments,
screenSpanning,
isMultiScreen: screenSpanning !== ScreenSpanning.None,
};
}
getScreenSpanning() {
if (matchMedia(dualVerticalViewport).matches) {
return ScreenSpanning.DualVertical;
}
else if (matchMedia(dualHorizontalViewport).matches) {
return ScreenSpanning.DualHorizontal;
}
return ScreenSpanning.None;
}
getWindowSegments() {
if ('getWindowSegments' in window) {
console.warn('getWindowSegments() is not supported anymore, please update your browser to use the new visualViewport API');
}
if ('visualViewport' in window) {
return window.visualViewport.segments;
}
return [
new DOMRect(window.pageXOffset, window.pageYOffset, window.innerWidth, window.innerHeight),
];
}
}
ScreenContext.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ScreenContext, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
ScreenContext.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ScreenContext, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: ScreenContext, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return []; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyZWVuLWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9saWIvc3JjL2NvcmUvc2NyZWVuLWNvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBYyxhQUFhLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbkUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7O0FBb0JuRDs7Ozs7R0FLRztBQUlILE1BQU0sT0FBTyxhQUFhO0lBS3hCO1FBRlEsZUFBVSxHQUF3QixJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUc3RCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzlDLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUN6QixTQUFTLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQ3JELFNBQVMsQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FDeEQsQ0FBQyxJQUFJLENBQ0osTUFBTSxDQUNKLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUN0RSxFQUNELFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFDWixHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ1AsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUM5QyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDN0IsQ0FBQyxDQUFDLEVBQ0YsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUNkLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQzNCLENBQUM7UUFDRixJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxlQUFlO0lBQ2YsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGNBQWM7UUFDaEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGNBQWM7UUFDaEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILFlBQVk7UUFDVixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUM3QixDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2hELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2hELE9BQU87WUFDTCxjQUFjO1lBQ2QsY0FBYztZQUNkLGFBQWEsRUFBRSxjQUFjLEtBQUssY0FBYyxDQUFDLElBQUk7U0FDdEQsQ0FBQztJQUNKLENBQUM7SUFFTyxpQkFBaUI7UUFDdkIsSUFBSSxVQUFVLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxPQUFPLEVBQUU7WUFDNUMsT0FBTyxjQUFjLENBQUMsWUFBWSxDQUFDO1NBQ3BDO2FBQU0sSUFBSSxVQUFVLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxPQUFPLEVBQUU7WUFDckQsT0FBTyxjQUFjLENBQUMsY0FBYyxDQUFDO1NBQ3RDO1FBQ0QsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDO0lBQzdCLENBQUM7SUFFTyxpQkFBaUI7UUFDdkIsSUFBSSxtQkFBbUIsSUFBSSxNQUFNLEVBQUU7WUFDakMsT0FBTyxDQUFDLElBQUksQ0FBQyw0R0FBNEcsQ0FBQyxDQUFDO1NBQzVIO1FBQ0QsSUFBSSxnQkFBZ0IsSUFBSSxNQUFNLEVBQUU7WUFDOUIsT0FBUSxNQUFNLENBQUMsY0FBc0IsQ0FBQyxRQUFRLENBQUM7U0FDaEQ7UUFDRCxPQUFPO1lBQ0wsSUFBSSxPQUFPLENBQ1QsTUFBTSxDQUFDLFdBQVcsRUFDbEIsTUFBTSxDQUFDLFdBQVcsRUFDbEIsTUFBTSxDQUFDLFVBQVUsRUFDakIsTUFBTSxDQUFDLFdBQVcsQ0FDbkI7U0FDRixDQUFDO0lBQ0osQ0FBQzs7MEdBcEdVLGFBQWE7OEdBQWIsYUFBYSxjQUZaLE1BQU07MkZBRVAsYUFBYTtrQkFIekIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgZmlsdGVyLCBzaGFyZVJlcGxheSwgc3RhcnRXaXRoLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBkdWFsVmVydGljYWxWaWV3cG9ydCwgZHVhbEhvcml6b250YWxWaWV3cG9ydCB9IGZyb20gJy4vbWVkaWEtcXVlcmllcyc7XG5pbXBvcnQgeyBTY3JlZW5TcGFubmluZyB9IGZyb20gJy4vc2NyZWVuLXNwYW5uaW5nJztcblxuZGVjbGFyZSBnbG9iYWwge1xuICBpbnRlcmZhY2UgV2luZG93IHtcbiAgICBnZXRXaW5kb3dTZWdtZW50czogKCkgPT4gRE9NUmVjdFtdO1xuICB9XG59XG5cbi8qKlxuICogSG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRldmljZSBzY3JlZW4gY29udGV4dC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY3JlZW5Db250ZXh0RGF0YSB7XG4gIC8qKiBUaGUgbGlzdCBvZiBhdmFpbGFibGUgd2luZG93IHNlZ21lbnRzLiAqL1xuICByZWFkb25seSB3aW5kb3dTZWdtZW50czogRE9NUmVjdFtdO1xuICAvKiogVGhlIGN1cnJlbnQgc2NyZWVuIHNwYW5uaW5nIG1vZGUuICovXG4gIHJlYWRvbmx5IHNjcmVlblNwYW5uaW5nOiBTY3JlZW5TcGFubmluZztcbiAgLyoqIFRydWUgaXMgY3VycmVudCBkZXZpY2UgaGF2ZSBtdWx0aXBsZSBzY3JlZW5zIGF2YWlsYWJsZS4gKi9cbiAgcmVhZG9ubHkgaXNNdWx0aVNjcmVlbjogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGlzIHNlcnZpY2UgYWxsb3dzIHRvIHF1ZXJ5IGFuZCByZWNlaXZlIHVwZGF0ZXMgYWJvdXQgY3VycmVudCBkZXZpY2Unc1xuICogc2NyZWVuIGNvbnRleHQuXG4gKlxuICogU2VlIHtAbGluayBTY3JlZW5Db250ZXh0RGF0YX1cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFNjcmVlbkNvbnRleHQgaW1wbGVtZW50cyBTY3JlZW5Db250ZXh0RGF0YSwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBjdXJyZW50Q29udGV4dDogU2NyZWVuQ29udGV4dERhdGE7XG4gIHByaXZhdGUgc2NyZWVuQ29udGV4dCQ6IE9ic2VydmFibGU8U2NyZWVuQ29udGV4dERhdGE+O1xuICBwcml2YXRlIGRlc3Ryb3llZCQ6IFJlcGxheVN1YmplY3Q8dm9pZD4gPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gdGhpcy5nZXRTY3JlZW5Db250ZXh0KCk7XG4gICAgdGhpcy5zY3JlZW5Db250ZXh0JCA9IG1lcmdlKFxuICAgICAgZnJvbUV2ZW50KG1hdGNoTWVkaWEoZHVhbFZlcnRpY2FsVmlld3BvcnQpLCAnY2hhbmdlJyksXG4gICAgICBmcm9tRXZlbnQobWF0Y2hNZWRpYShkdWFsSG9yaXpvbnRhbFZpZXdwb3J0KSwgJ2NoYW5nZScpXG4gICAgKS5waXBlKFxuICAgICAgZmlsdGVyKFxuICAgICAgICAoKSA9PiB0aGlzLmdldFNjcmVlblNwYW5uaW5nKCkgIT09IHRoaXMuY3VycmVudENvbnRleHQuc2NyZWVuU3Bhbm5pbmdcbiAgICAgICksXG4gICAgICBzdGFydFdpdGgoMSksXG4gICAgICBtYXAoKCkgPT4ge1xuICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gdGhpcy5nZXRTY3JlZW5Db250ZXh0KCk7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRDb250ZXh0O1xuICAgICAgfSksXG4gICAgICBzaGFyZVJlcGxheSgxKSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCQpXG4gICAgKTtcbiAgICB0aGlzLnNjcmVlbkNvbnRleHQkLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqIEBpZ25vcmVkICovXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2YgYXZhaWxhYmxlIHdpbmRvdyBzZWdtZW50cy5cbiAgICovXG4gIGdldCB3aW5kb3dTZWdtZW50cygpOiBET01SZWN0W10ge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRDb250ZXh0LndpbmRvd1NlZ21lbnRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHNjcmVlbiBzcGFubmluZyBtb2RlLlxuICAgKi9cbiAgZ2V0IHNjcmVlblNwYW5uaW5nKCk6IFNjcmVlblNwYW5uaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50Q29udGV4dC5zY3JlZW5TcGFubmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnVlIGlzIGN1cnJlbnQgZGV2aWNlIGhhdmUgbXVsdGlwbGUgc2NyZWVucyBhdmFpbGFibGUuXG4gICAqL1xuICBnZXQgaXNNdWx0aVNjcmVlbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50Q29udGV4dC5pc011bHRpU2NyZWVuO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYW4gb2JzZXJ2YWJsZSBlbWl0dGluZyB3aGVuIHRoZSBzY3JlZW4gY29udGV4dCBjaGFuZ2VzLlxuICAgKi9cbiAgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8U2NyZWVuQ29udGV4dERhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5zY3JlZW5Db250ZXh0JDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBjdXJyZW50IHNjcmVlbiBjb250ZXh0LlxuICAgKi9cbiAgYXNPYmplY3QoKTogU2NyZWVuQ29udGV4dERhdGEge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRDb250ZXh0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTY3JlZW5Db250ZXh0KCk6IFNjcmVlbkNvbnRleHREYXRhIHtcbiAgICBjb25zdCB3aW5kb3dTZWdtZW50cyA9IHRoaXMuZ2V0V2luZG93U2VnbWVudHMoKTtcbiAgICBjb25zdCBzY3JlZW5TcGFubmluZyA9IHRoaXMuZ2V0U2NyZWVuU3Bhbm5pbmcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgd2luZG93U2VnbWVudHMsXG4gICAgICBzY3JlZW5TcGFubmluZyxcbiAgICAgIGlzTXVsdGlTY3JlZW46IHNjcmVlblNwYW5uaW5nICE9PSBTY3JlZW5TcGFubmluZy5Ob25lLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldFNjcmVlblNwYW5uaW5nKCk6IFNjcmVlblNwYW5uaW5nIHtcbiAgICBpZiAobWF0Y2hNZWRpYShkdWFsVmVydGljYWxWaWV3cG9ydCkubWF0Y2hlcykge1xuICAgICAgcmV0dXJuIFNjcmVlblNwYW5uaW5nLkR1YWxWZXJ0aWNhbDtcbiAgICB9IGVsc2UgaWYgKG1hdGNoTWVkaWEoZHVhbEhvcml6b250YWxWaWV3cG9ydCkubWF0Y2hlcykge1xuICAgICAgcmV0dXJuIFNjcmVlblNwYW5uaW5nLkR1YWxIb3Jpem9udGFsO1xuICAgIH1cbiAgICByZXR1cm4gU2NyZWVuU3Bhbm5pbmcuTm9uZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0V2luZG93U2VnbWVudHMoKTogRE9NUmVjdFtdIHtcbiAgICBpZiAoJ2dldFdpbmRvd1NlZ21lbnRzJyBpbiB3aW5kb3cpIHtcbiAgICAgIGNvbnNvbGUud2FybignZ2V0V2luZG93U2VnbWVudHMoKSBpcyBub3Qgc3VwcG9ydGVkIGFueW1vcmUsIHBsZWFzZSB1cGRhdGUgeW91ciBicm93c2VyIHRvIHVzZSB0aGUgbmV3IHZpc3VhbFZpZXdwb3J0IEFQSScpO1xuICAgIH1cbiAgICBpZiAoJ3Zpc3VhbFZpZXdwb3J0JyBpbiB3aW5kb3cpIHtcbiAgICAgIHJldHVybiAod2luZG93LnZpc3VhbFZpZXdwb3J0IGFzIGFueSkuc2VnbWVudHM7XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICBuZXcgRE9NUmVjdChcbiAgICAgICAgd2luZG93LnBhZ2VYT2Zmc2V0LFxuICAgICAgICB3aW5kb3cucGFnZVlPZmZzZXQsXG4gICAgICAgIHdpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgICB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICAgICksXG4gICAgXTtcbiAgfVxufVxuIl19