Repository URL to install this package:
|
Version:
3.0.2 ▾
|
"use strict";
/**
* @todo isAtBottom & isAtTop & isBottomVisible
* @todo onKeyDown?
* @todo all click boundaries re-use this?
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/13679
* @see https://github.com/Microsoft/TypeScript/issues/5073
*/
const debounce_1 = __importDefault(require("lodash/debounce"));
const exotic_1 = require("exotic");
const mobx_1 = require("xmobx/mobx");
const deps_1 = require("./deps");
const IS_BROWSER = typeof window === 'object';
/**
* @todo method like @connectTo('prop1', 'prop2')
* @todo debounce with requestAnimationFrame
*/
class ApplicationStore {
constructor() {
this.store = mobx_1.observable.map();
this.snackbar = {};
this.prev = {
screen: {
height: 0,
width: 0,
},
};
// struct makes sure observer won't be signaled unless diff is large...
// @observable.struct
this.screen = {
height: IS_BROWSER ? window.innerHeight : 0,
width: IS_BROWSER ? window.innerWidth : 0,
availHeight: IS_BROWSER ? window.screen.availHeight : 0,
availWidth: IS_BROWSER ? window.screen.availWidth : 0,
isGrowing: undefined,
isShrinking: undefined,
};
// @observable.struct
this.scroll = {
vertical: IS_BROWSER ? window.scrollY : 0,
horizontal: IS_BROWSER ? window.scrollX : 0,
direction: 'none',
};
this.hasError = false;
this.orientation = 'portrait';
// does not need to be observable or computed - does not change
this.isTouchDevice = IS_BROWSER && deps_1.isTouchDevice();
this.isModernBrowser = !deps_1.isEdgeOrInternetExplorer();
this.isOldBadBrowser = deps_1.isEdgeOrInternetExplorer();
/**
* @note - was this - but now is observe direct since we have typings
* observe(properties: string | Array<string>, subscriber: Function) {
* return observe(this, properties, subscriber)
* }
*/
this.observe = mobx_1.observe.bind(undefined, this);
}
// =========
// to always trigger
get isLoading() {
return this.store.get('isLoading');
}
set isLoading(isLoading) {
this.store.set('isLoading', isLoading);
}
get isLoadingBig() {
return this.isLoading && this.store.get('isLoadingBig');
}
showLoadingGauge(isLoading, duration = 3500) {
this.setIsLoading(true);
setTimeout(() => this.setIsLoading(false), duration);
return this;
}
setIsLoadingBig(isLoading) {
this.setIsLoading(isLoading);
this.store.set('isLoadingBig', isLoading);
return this;
}
setLoadingTimer(isLoading = true, duration = 3500) {
this.setIsLoading(isLoading);
this.store.set('isLoadingBig', isLoading);
setTimeout(() => this.setIsLoadingBig(false), duration);
return this;
}
setIsLoading(isLoading) {
if (isLoading !== this.isLoading) {
console.log('setIsLoading', isLoading);
this.isLoading = isLoading;
}
return this;
}
// =========
setError(message, meta = Object) {
const error = { message, meta };
this.store.set('error', error);
return this;
}
snack(message, meta) {
this.snackbar.message = message;
this.snackbar.meta = meta;
return this;
}
/**
* @todo @name isTheatre
* (small, medium, large) - 2200, 2400, 6000
*
* @todo @name isDesktop
* (small, medium, large) - 1440, 1600, 1920
*/
get isSuperSize() {
return this.screen.width >= 1200;
}
/**
* @todo @name isLaptop
* (small, medium, large) - 1024, 1280, 1366
*/
get isDesktop() {
return this.screen.width > 1024;
}
// get isMediumDesktop()
// get isLargeDesktop()
// get isSmallDesktop()
// get isSmallNotebook()
// get isMediumNotebook()
// get isLargeNotebook()
// get isLargeTablet()
// get isSmallTablet()
// get isMediumTablet()
// get isTablet()
// we aren't really checking tablet-desktop < -.-
get isTablet() {
return this.screen.width >= 768 && this.screen.width <= 1024;
}
get isTabletOrLarger() {
// return this.isTablet || this.isPhone
return this.screen.width <= 1024;
}
get isTabletOrSmaller() {
return this.isTablet || this.isPhone;
}
get isMobile() {
return this.isPhone;
}
get isMobileOrLarger() {
return this.isPhone;
}
get isPhone() {
return this.screen.width < 768;
}
get isDesktopOrLarger() {
return this.screen.width >= 1024;
}
get deviceType() {
return this.isDesktop ? 'desktop' : this.isTablet ? 'tablet' : 'mobile';
}
/**
* @private
*/
handleResize(event) {
if (this.isTouchDevice) {
console.info('[state:application] handleResize ... LIAR');
return;
}
this.updateDimensions();
}
/**
* @private
*/
updateDimensions() {
// if we trigger this like this, it will always trigger an update
// since we already debounce, struct is not 100% needed
this.prev = {
screen: {
height: this.screen.height,
width: this.screen.width,
},
};
this.screen = {
height: window.innerHeight,
width: window.innerWidth,
availHeight: window.screen.availHeight,
availWidth: window.screen.availWidth,
};
}
/**
* @private
*/
handleScroll(event) {
this.updateScrollPosition(event);
}
handleOrientation(event) {
this.updateDimensions();
}
/**
* @private
*/
updateScrollPosition(event) {
// minMovementInPixels
const minimum = 100;
// @todo - react event?
const scrollTop = event.srcElement.body.scrollTop || window.scrollY;
const scrollSide = window.scrollX;
/**
* higher value = lower down the page
*/
const scrollDirection = this.scroll.vertical < scrollTop ? 'down' : 'up';
// or in reverse
const verticalDifference = Math.abs(this.scroll.vertical - scrollTop);
// ignoring horizontal for now
// const horizontalDifference = Math.abs(this.scroll.horizontal - scrollSide)
// minimum < horizontalDifference &&
if (scrollDirection === this.scroll.direction) {
if (minimum < verticalDifference) {
// console.debug('application_scroll_ignored')
// ignore - we barely scrolled, and in the same direction
return;
}
}
// console.info('scrolling', {
// scrollTop,
// scrollDirection,
// verticalDifference,
// })
this.scroll = {
vertical: scrollTop,
horizontal: scrollSide,
direction: scrollDirection,
};
// @example
// if (scrollDirection === 'up') // hide
// else // show
}
get isScrollingUp() {
return this.scroll.direction === 'up';
}
get isScrollingDown() {
if (this.scroll.vertical >= 50 && this.scroll.direction === 'down') {
return true;
}
else {
return false;
}
}
// =========
toggle(key) {
const value = this.store.get(key);
const inverseValue = !value;
this.store.set(key, inverseValue);
return this;
}
toggleFor(key) {
return (event) => this.toggle(key);
}
set(key, value) {
// make setters easily
if (arguments.length === 1) {
return (lateValue) => {
this.set(key, lateValue);
return this;
};
}
// could also Object.define an observable property here...
this.store.set(key, value);
return this;
}
/**
* @example isFilterOpen
*/
get(key) {
if (arguments.length > 1) {
return exotic_1.fromArgumentsToArray.apply(undefined, arguments);
}
/**
* @example .get('isFilterOpen', 'isLoading')
* => {isFilterOpen: true, isLoading: false}
*/
if (exotic_1.isArray(key)) {
const obj = {};
const keyList = key;
keyList.forEach(name => {
obj[name] = this.store.get(name);
});
return obj;
}
return this.store.get(key);
}
// @computed
entries() {
return exotic_1.fromMapToObj(this.store);
}
}
__decorate([
mobx_1.observable.ref
], ApplicationStore.prototype, "prev", void 0);
__decorate([
mobx_1.observable
], ApplicationStore.prototype, "screen", void 0);
__decorate([
mobx_1.observable
], ApplicationStore.prototype, "scroll", void 0);
__decorate([
mobx_1.observable
], ApplicationStore.prototype, "hasError", void 0);
__decorate([
mobx_1.observable
], ApplicationStore.prototype, "orientation", void 0);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "showLoadingGauge", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "setIsLoadingBig", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "setLoadingTimer", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "setIsLoading", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "setError", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "snack", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isSuperSize", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isDesktop", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isTablet", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isTabletOrLarger", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isTabletOrSmaller", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isMobile", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isMobileOrLarger", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isPhone", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isDesktopOrLarger", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "deviceType", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "handleResize", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "updateDimensions", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "handleScroll", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "handleOrientation", null);
__decorate([
mobx_1.action
], ApplicationStore.prototype, "updateScrollPosition", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isScrollingUp", null);
__decorate([
mobx_1.computed
], ApplicationStore.prototype, "isScrollingDown", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "toggle", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "toggleFor", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "set", null);
__decorate([
mobx_1.action.bound
], ApplicationStore.prototype, "get", null);
exports.ApplicationStore = ApplicationStore;
const applicationContainer = new ApplicationStore();
exports.application = applicationContainer;
exports.applicationContainer = applicationContainer;
function handleResize(event) {
// console.debug('[application] resize subscribed')
applicationContainer.handleResize(event);
}
function handleScroll(event) {
// console.debug('[application] scroll subscribed')
applicationContainer.handleScroll(event);
}
function handleOrientation(event) {
// console.debug('[application] orientation subscribed')
// screen.orientation.angle
applicationContainer.handleOrientation(event);
}
function subscribe() {
// maybe no need to debounce if we use the struct?
// window.addEventListener('resize', debounce(applicationContainer.handleResize, 60))
// window.addEventListener('scroll', debounce(applicationContainer.handleScroll, 60))
// window.addEventListener('resize', handleResize)
// not debouncing, handling logic
window.addEventListener('scroll', handleScroll);
// https://jira.skava.net/browse/SKREACT-3957
// https://jira.skava.net/browse/SKREACT-3939
if (deps_1.isTouchDevice() === false) {
window.addEventListener('resize', debounce_1.default(handleResize, 60));
}
// window.addEventListener('scroll', debounce(handleScroll, 60))
/**
* @see https://developer.mozilla.org/en-US/docs/Web/Events/orientationchange
*/
if (deps_1.isTouchDevice()) {
window.addEventListener('orientationchange', handleOrientation);
}
}
if (IS_BROWSER) {
subscribe();
/**
* @note renamed from @name DEVTOOLS_GLOBALS_APPLICATION_ENABELD
*/
if (process.env.DEVTOOLS_GLOBALS_APPLICATION_ENABLED) {
window.application = applicationContainer;
}
}
exports.default = applicationContainer;
//# sourceMappingURL=application.js.map