lavva.exalushome
Version:
Library implementing communication and abstraction layers for ExalusHome system
222 lines • 10.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { Api } from "../Api";
import { AsyncLock } from "../AsyncLock";
import { DependencyContainer } from "../DependencyContainer";
import { Event } from "../Event";
import { TypedEvent } from "../TypedEvent";
import { AppState } from "./IAppStateService";
import { ConnectionState } from "./IExalusConnectionService";
export class AppStateService {
constructor() {
//// BLOCK DISCONNECTION WHEN PENDING REQUESTS
this._isConnectedAndAuthorized = false;
this._syncLock = new AsyncLock();
this._isInFouces = true;
this._canHibernate = true;
this._session = null;
this._connection = null;
this._currentAppState = AppState.Disconnected;
this._returnedFromSuspension = false;
this._onReturnedFromSuspensionEvent = new Event();
this._onSuspendedEvent = new Event();
this._onEnterLowPowerModeEvent = new Event();
this._onExitLowPowerModeEvent = new Event();
this._onBackButtonPressedEvent = new Event();
this._onForwardButtonPressedEvent = new Event();
this._onAppStateChanged = new TypedEvent();
this.MonitorAppState();
this._onAppStateChanged.Subscribe((state) => this._currentAppState = state);
if (navigator.userAgent.match(/Safari/i) != null && !navigator.mediaDevices) {
window.addEventListener("onblur", () => {
if (!this._isInFouces)
return;
this._isInFouces = false;
this.Suspend();
});
window.addEventListener("onfocus", () => {
if (this._isInFouces)
return;
this._isInFouces = true;
this.ReturnFromSuspension();
});
}
else {
window.addEventListener("visibilitychange", () => __awaiter(this, void 0, void 0, function* () {
yield this._syncLock.WaitForLockAsync();
this._syncLock.Lock();
if (this.IsHidden())
this.Suspend();
else
this.ReturnFromSuspension();
this._syncLock.Unlock();
}));
}
window.addEventListener("popstate", (event) => {
var _a, _b, _c, _d;
var loc = document.location;
if (event.state) {
// state is defined
if (event.state.direction == "forward") {
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, "Forward button pressed");
(_b = this._onForwardButtonPressedEvent) === null || _b === void 0 ? void 0 : _b.Invoke();
}
else {
(_c = DependencyContainer.Log) === null || _c === void 0 ? void 0 : _c.Warning(AppStateService.ServiceName, "Back button pressed");
(_d = this._onBackButtonPressedEvent) === null || _d === void 0 ? void 0 : _d.Invoke();
}
}
});
}
MonitorAppState() {
return __awaiter(this, void 0, void 0, function* () {
this._session = yield Api.GetAsync("SessionService");
this._connection = yield Api.GetAsync("ExalusConnectionService");
this._session.OnUserLoggedInEvent().Subscribe((user) => {
var _a;
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, `App state changed to: logged in`);
this._onAppStateChanged.Invoke(AppState.LoggedIn);
});
this._session.OnUserLoggedOutEvent().Subscribe((user) => {
var _a;
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, `App state changed to: logged out`);
this._onAppStateChanged.Invoke(AppState.LoggedOut);
});
this._connection.OnConnectionStateChangedEvent().Subscribe((state) => {
var _a, _b, _c, _d, _e, _f;
switch (state) {
case ConnectionState.ConnectedAndAuthorized:
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, `App state changed to: connected`);
this._isConnectedAndAuthorized = true;
this._onAppStateChanged.Invoke(AppState.Connected);
break;
case ConnectionState.Disconnected:
(_b = DependencyContainer.Log) === null || _b === void 0 ? void 0 : _b.Warning(AppStateService.ServiceName, `App state changed to: disconnected`);
if (this._isConnectedAndAuthorized)
this._onAppStateChanged.Invoke(AppState.Disconnected);
this._isConnectedAndAuthorized = false;
break;
case ConnectionState.Connecting:
(_c = DependencyContainer.Log) === null || _c === void 0 ? void 0 : _c.Warning(AppStateService.ServiceName, `App state changed to: connecting`);
this._onAppStateChanged.Invoke(AppState.Connecting);
break;
case ConnectionState.Disconnecting:
(_d = DependencyContainer.Log) === null || _d === void 0 ? void 0 : _d.Warning(AppStateService.ServiceName, `App state changed to: disconnecting`);
this._onAppStateChanged.Invoke(AppState.Disconnecting);
break;
case ConnectionState.Reconnecting:
(_e = DependencyContainer.Log) === null || _e === void 0 ? void 0 : _e.Warning(AppStateService.ServiceName, `App state changed to: reconnecting`);
this._onAppStateChanged.Invoke(AppState.Reconnecting);
break;
case ConnectionState.Failed:
(_f = DependencyContainer.Log) === null || _f === void 0 ? void 0 : _f.Warning(AppStateService.ServiceName, `App state changed to: failed`);
this._onAppStateChanged.Invoke(AppState.FailedToConnect);
break;
}
});
});
}
get CurrentAppState() {
return this._currentAppState;
}
OnAppStateChanged() {
return this._onAppStateChanged;
}
Suspend() {
var _a, _b;
if (!this.IsHibernationAllowed())
return;
this._returnedFromSuspension = false;
this._onSuspendedEvent.Invoke();
this._onAppStateChanged.Invoke(AppState.Suspended);
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, `App state changed to: suspended`);
(_b = DependencyContainer.Log) === null || _b === void 0 ? void 0 : _b.Warning(AppStateService.ServiceName, "App switched to background");
}
ReturnFromSuspension() {
var _a, _b;
if (!this.IsHibernationAllowed())
return;
this._returnedFromSuspension = true;
this._onReturnedFromSuspensionEvent.Invoke();
this._onAppStateChanged.Invoke(AppState.ReturnedFromSuspension);
(_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(AppStateService.ServiceName, `App state changed to: returned from suspension`);
(_b = DependencyContainer.Log) === null || _b === void 0 ? void 0 : _b.Warning(AppStateService.ServiceName, "App switched to foreground");
}
EnterLowPowerMode() {
this._onEnterLowPowerModeEvent.Invoke();
this._onAppStateChanged.Invoke(AppState.EnteredLowPowerMode);
}
ExitLowPowerMode() {
this._onExitLowPowerModeEvent.Invoke();
this._onAppStateChanged.Invoke(AppState.ExitedLowPowerMode);
}
IsWorkingInWebView() {
/// for all if index file is hosted locally
/// for Android WebView
if (window.location.protocol === "file:")
return true;
/// for apple devices
if (navigator.userAgent.match(/Safari/i) != null) {
/// normally iOS WebView does not support mediaDevices like in Safari or other browsers
if (navigator.mediaDevices)
return false;
else
return true;
}
else {
// is not android web view
return false;
}
}
IsHidden() {
return document.hidden;
}
IsActive() {
return !this.IsHidden();
}
IsInBackground() {
return this.IsHidden();
}
ReturnedFromSuspension() {
return this._returnedFromSuspension;
}
IsHibernationAllowed() {
return this._canHibernate;
}
DisallowHibernation() {
this._canHibernate = false;
}
AllowHibernation() {
this._canHibernate = true;
}
OnReturnedFromSuspension() {
return this._onReturnedFromSuspensionEvent;
}
OnSuspended() {
return this._onSuspendedEvent;
}
OnEnterLowPowerMode() {
return this._onEnterLowPowerModeEvent;
}
OnExitLowPowerMode() {
return this._onExitLowPowerModeEvent;
}
OnBackButtonPressed() {
return this._onBackButtonPressedEvent;
}
OnForwardButtonPressed() {
return this._onForwardButtonPressedEvent;
}
GetServiceName() {
return AppStateService.ServiceName;
}
}
AppStateService.ServiceName = "AppStateService";
//# sourceMappingURL=AppStateService.js.map