Last active
March 14, 2017 03:26
-
-
Save burkeholland/5a0b42a29adb8e47422cd14539ae380e to your computer and use it in GitHub Desktop.
Proposed Changes To Settings.model For Syncronization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as appSettings from "application-settings"; | |
import { UnitTypes } from "./app-enums"; | |
import { DashboardWidgetInfo } from "./DashboardWidgetInfo.model"; | |
const serializableMetadataKey = Symbol("serializable"); | |
function serializable() { | |
return Reflect.metadata(serializableMetadataKey, true); | |
} | |
function isSerializable(target: any, propertyKey: string) { | |
return Reflect.getMetadata(serializableMetadataKey, target, propertyKey); | |
} | |
export class Settings { | |
/* Proposed changes to Settings object | |
Problem: Each setting may need to be pushed to Firebase at any time. | |
Solution: Create wrappers for the setType functions on the appsettings object | |
which can determine if a property should be pushed (per the serializable decorator) | |
and then push it, or store it for syncronization later if the system is offline | |
*/ | |
// Begin Wrapper functions | |
private static pushToFirebase(key: string, value: any) { | |
// Firebase logic goes here | |
console.log(`Pushing ${key} to Firebase`); | |
} | |
private static setBoolean(key: string, value: boolean) { | |
appSettings.setBoolean(key, value); | |
// if the property is serializable, push it to Firebase automagically | |
if (isSerializable(this, key)) { | |
this.pushToFirebase(key, value); | |
} | |
} | |
private static setString(key: string, value: string) { | |
appSettings.setString(key, value); | |
// if the property is serializable, push it to Firebase automagically | |
if (isSerializable(this, key)) { | |
this.pushToFirebase(key, value); | |
} | |
} | |
private static setNumber(key: string, value: number) { | |
appSettings.setNumber(key, value); | |
// if the property is serializable, push it to Firebase automagically | |
if (isSerializable(this, key)) { | |
this.pushToFirebase(key, value); | |
} | |
} | |
// End Wrapper functions | |
// Most important item of note is that all setters now call the wrapper functions instead | |
// of directly calling appsettings | |
// isDebugMode | |
public static get isDebugMode(): boolean { | |
return appSettings.getBoolean("isDebugMode", false); | |
} | |
public static set isDebugMode(value: boolean) { | |
this.setBoolean("isDebugMode", value); | |
} | |
// isDemoMode | |
public static get isDemoMode(): boolean { | |
return appSettings.getBoolean("isDemoMode", false); | |
} | |
public static set isDemoMode(value: boolean) { | |
this.setBoolean("isDemoMode", value); | |
} | |
// isAppConfigured | |
public static get isAppConfigured(): boolean { | |
return appSettings.getBoolean("isAppConfigured", false); | |
} | |
public static set isAppConfigured(value: boolean) { | |
this.setBoolean("isAppConfigured", value); | |
} | |
// isAwayActive | |
@serializable() | |
public static get isAwayActive(): boolean { | |
return appSettings.getBoolean("isAwayActive", false); | |
} | |
public static set isAwayActive(value: boolean) { | |
this.setBoolean("isAwayActive", value); | |
} | |
// isSmartAwayEnabled | |
@serializable() | |
public static get isSmartAwayEnabled(): boolean { | |
return appSettings.getBoolean("isSmartAwayEnabled", true); | |
} | |
public static set isSmartAwayEnabled(value: boolean) { | |
this.setBoolean("isSmartAwayEnabled", value); | |
} | |
// isTutorialDone | |
@serializable() | |
public static get isTutorialDone(): boolean { | |
return appSettings.getBoolean("isTutorialDone", false); | |
} | |
public static set isTutorialDone(value: boolean) { | |
this.setBoolean("isTutorialDone", value); | |
} | |
// isLocationEnabled | |
@serializable() | |
public static get isLocationEnabled(): boolean { | |
return appSettings.getBoolean("isLocationEnabled", false); | |
} | |
public static set isLocationEnabled(value: boolean) { | |
this.setBoolean("isLocationEnabled", value); | |
// appSettings.setBoolean("isLocationEnabled", value); | |
} | |
// isPinRequired | |
@serializable() | |
public static get isPinRequired(): boolean { | |
return appSettings.getBoolean("isPinRequired", false); | |
} | |
public static set isPinRequired(value: boolean) { | |
this.setBoolean("isPinRequired", value); | |
} | |
// ignoreAwayWarning | |
@serializable() | |
public static get ignoreAwayWarning(): boolean { | |
return appSettings.getBoolean("ignoreAwayWarning", false); | |
} | |
public static set ignoreAwayWarning(value: boolean) { | |
this.setBoolean("ignoreAwayWarning", value); | |
} | |
// filterAutoScenes | |
@serializable() | |
public static get filterAutoScenes(): boolean { | |
return appSettings.getBoolean("filterAutoScenes", true); | |
} | |
public static set filterAutoScenes(value: boolean) { | |
this.setBoolean("filterAutoScenes", value); | |
} | |
// showAddWidgetWidget | |
@serializable() | |
public static get showAddWidgetWidget(): boolean { | |
return appSettings.getBoolean("showAddWidgetWidget", true); | |
} | |
public static set showAddWidgetWidget(value: boolean) { | |
this.setBoolean("showAddWidgetWidget", value); | |
} | |
// ignoredDeviceIds | |
@serializable() | |
public static get ignoredDeviceIds(): Array<number> { | |
let r = appSettings.getString("ignoredDeviceIds"); | |
return (r === undefined) ? new Array<number>() : JSON.parse(r); | |
} | |
public static set ignoredDeviceIds(value: Array<number>) { | |
this.setString("ignoredDeviceIds", JSON.stringify(value)); | |
} | |
// ignoredAutoAwayDeviceIds | |
@serializable() | |
public static get ignoredAutoAwayDeviceIds(): Array<number> { | |
let r = appSettings.getString("ignoredAutoAwayDeviceIds"); | |
return (r === undefined) ? new Array<number>() : JSON.parse(r); | |
} | |
public static set ignoredAutoAwayDeviceIds(value: Array<number>) { | |
this.setString("ignoredAutoAwayDeviceIds", JSON.stringify(value)); | |
} | |
// favoriteDeviceIds | |
@serializable() | |
public static get favoriteDeviceIds(): Array<number> { | |
let r = appSettings.getString("favoriteDeviceIds"); | |
return (r === undefined) ? new Array<number>() : JSON.parse(r); | |
} | |
public static set favoriteDeviceIds(value: Array<number>) { | |
this.setString("favoriteDeviceIds", JSON.stringify(value)); | |
} | |
// dashboardWidgets | |
@serializable() | |
public static get dashboardWidgets(): Array<DashboardWidgetInfo> { | |
let r = appSettings.getString("dashboardWidgets"); | |
return (r === undefined) ? new Array<DashboardWidgetInfo>() : JSON.parse(r); | |
} | |
public static set dashboardWidgets(value: Array<DashboardWidgetInfo>) { | |
this.setString("dashboardWidgets", JSON.stringify(value)); | |
} | |
// deviceCategories | |
@serializable() | |
public static get deviceCategories(): Object { | |
let r = appSettings.getString("deviceCategories"); | |
return (r === undefined) ? {} : JSON.parse(r); | |
} | |
public static set deviceCategories(value: Object) { | |
this.setString("deviceCategories", JSON.stringify(value)); | |
} | |
// securityDeviceCategoryIds | |
@serializable() | |
public static get securityDeviceCategoryIds(): Array<number> { | |
let r = appSettings.getString("securityDeviceCategoryIds"); | |
return (r === undefined) ? new Array<number>() : JSON.parse(r); | |
} | |
public static set securityDeviceCategoryIds(value: Array<number>) { | |
this.setString("securityDeviceCategoryIds", JSON.stringify(value)); | |
} | |
// resumePin | |
@serializable() | |
public static get resumePin(): number { | |
return appSettings.getNumber("resumePin"); | |
} | |
public static set resumePin(value: number) { | |
this.setNumber("resumePin", value); | |
} | |
// controllerType | |
@serializable() | |
public static get controllerType(): string { | |
return appSettings.getString("controllerType", "vera"); | |
} | |
public static set controllerType(value: string) { | |
this.setString("controllerType", value); | |
} | |
// baseUrl | |
@serializable() | |
public static get baseUrl(): string { | |
return appSettings.getString("baseUrl"); | |
} | |
public static set baseUrl(value: string) { | |
this.setString("baseUrl", value); | |
} | |
// controllerStatus | |
@serializable() | |
public static get controllerStatus(): Object { | |
let r = appSettings.getString("controllerStatus"); | |
return (r === undefined) ? undefined : JSON.parse(r); | |
} | |
public static set controllerStatus(value: Object) { | |
this.setString("controllerStatus", JSON.stringify(value)); | |
} | |
// smartAwayResumeSceneId | |
@serializable() | |
public static get smartAwayResumeSceneId(): number { | |
return appSettings.getNumber("smartAwayResumeSceneId", 9999); | |
} | |
public static set smartAwayResumeSceneId(value: number) { | |
this.setNumber("smartAwayResumeSceneId", value); | |
} | |
// smartAwaySceneId | |
@serializable() | |
public static get smartAwaySceneId(): number { | |
return appSettings.getNumber("smartAwaySceneId", 9998); | |
} | |
public static set smartAwaySceneId(value: number) { | |
this.setNumber("smartAwaySceneId", value); | |
} | |
// awayDelaySeconds | |
@serializable() | |
public static get awayDelaySeconds(): number { | |
return appSettings.getNumber("awayDelaySeconds", 120); | |
} | |
public static set awayDelaySeconds(value: number) { | |
this.setNumber("awayDelaySeconds", value); | |
} | |
// zipCode | |
@serializable() | |
public static get zipCode(): string { | |
return appSettings.getString("zipCode"); | |
} | |
public static set zipCode(value: string) { | |
this.setString("zipCode", value); | |
} | |
// showTutorial | |
@serializable() | |
public static get showTutorial(): boolean { | |
return appSettings.getBoolean("showTutorial", true); | |
} | |
public static set showTutorial(value: boolean) { | |
this.setBoolean("showTutorial", value); | |
} | |
// port | |
@serializable() | |
public static get port(): string { | |
return appSettings.getString("port"); | |
} | |
public static set port(value: string) { | |
this.setString("port", value); | |
} | |
// ipaddr | |
@serializable() | |
public static get ipaddr(): string { | |
return appSettings.getString("ipaddr"); | |
} | |
public static set ipaddr(value: string) { | |
this.setString("ipaddr", value); | |
} | |
// sonosPort | |
@serializable() | |
public static get sonosPort(): string { | |
return appSettings.getString("sonosPort"); | |
} | |
public static set sonosPort(value: string) { | |
this.setString("sonosPort", value); | |
} | |
// lat | |
@serializable() | |
public static get lat(): string { | |
return appSettings.getString("lat", ""); | |
} | |
public static set lat(value: string) { | |
this.setString("lat", value); | |
} | |
// long | |
@serializable() | |
public static get long(): string { | |
return appSettings.getString("long", ""); | |
} | |
public static set long(value: string) { | |
this.setString("long", value); | |
} | |
// units | |
@serializable() | |
public static get units(): UnitTypes { | |
return appSettings.getNumber("units", UnitTypes.Auto); | |
} | |
public static set units(value: UnitTypes) { | |
this.setNumber("units", value); | |
} | |
// homeSceneId | |
@serializable() | |
public static get homeSceneId(): number { | |
return appSettings.getNumber("homeSceneId"); | |
} | |
public static set homeSceneId(value: number) { | |
this.setNumber("homeSceneId", value); | |
} | |
// awaySceneId | |
@serializable() | |
public static get awaySceneId(): number { | |
return appSettings.getNumber("awaySceneId"); | |
} | |
public static set awaySceneId(value: number) { | |
this.setNumber("awaySceneId", value); | |
} | |
// firebase user information | |
public static get userEmail(): string { | |
return appSettings.getString("userEmail"); | |
} | |
public static set userEmail(value: string) { | |
this.setString("userEmail", value); | |
} | |
public static get userUIID(): string { | |
return appSettings.getString("userUIID"); | |
} | |
public static set userUIID(value: string) { | |
this.setString("userUIID", value); | |
} | |
// is the user logged in | |
public static get isLoggedIn(): boolean { | |
return appSettings.getBoolean("isLoggedIn"); | |
} | |
public static set isLoggedIn(value: boolean) { | |
this.setBoolean("isLoggedIn", value); | |
} | |
// syncData | |
public static get syncData(): boolean { | |
return appSettings.getBoolean("syncData"); | |
} | |
public static set syncData(value: boolean) { | |
this.setBoolean("syncData", value); | |
} | |
// classes need a custom toJSON to be stringified ¯\_(ツ)_/¯ | |
public static toJSON() { | |
var result = {}; | |
for (var key in this) { | |
if (isSerializable(this, key)) { | |
result[key] = this[key]; | |
} | |
} | |
return result; | |
} | |
// overwrites the settings object with any matched props | |
public static update(obj: any) { | |
for (var key in obj) { | |
this[key] = obj[key]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Overall, makes sense.
Small improvement in this version to check that the new property value has actually changed before processing continues:
https://gist.github.com/toddanglin/2749a80eeaf632cb9cc9fec742c68935
Sanity check: How do you prevent "loops" when Firebase updates the setting on a new device?
Scenario:
isAway
property fromfalse
totrue
isAway
isAway
isAway
fromfalse
totrue
(value from Firebase)I guess at this point either A) Firebase filters out the extra update because the value on Device B and Firebase match, or B) Device A stops the cycle when it checks that the Setting value has changed before re-setting the property.
Okay. Seems to work. :)