summaryrefslogtreecommitdiff
path: root/www/js
diff options
context:
space:
mode:
Diffstat (limited to 'www/js')
-rw-r--r--www/js/DataModel.js366
-rw-r--r--www/js/LoginCtrl.js33
-rw-r--r--www/js/NewsCtrl.js14
-rw-r--r--www/js/app.js433
-rw-r--r--www/js/ionicUtils.js7
5 files changed, 526 insertions, 327 deletions
diff --git a/www/js/DataModel.js b/www/js/DataModel.js
index df92729e..681e8fbd 100644
--- a/www/js/DataModel.js
+++ b/www/js/DataModel.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
-/* global cordova,StatusBar,angular,console, URI, moment*/
+/* global cordova,StatusBar,angular,console, URI, moment, localforage*/
// This is my central data respository and common functions
// that many other controllers use
@@ -10,7 +10,7 @@
angular.module('zmApp.controllers')
-.service('ZMDataModel', ['$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$ionicNativeTransitions', '$translate',
+.service('ZMDataModel', ['$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$ionicNativeTransitions', '$translate', '$cordovaSQLite',
function
($http, $q, $ionicLoading, $ionicBackdrop, $fileLogger,
zm, $rootScope, $ionicContentBanner, $timeout, $cordovaPinDialog,
@@ -24,6 +24,8 @@ angular.module('zmApp.controllers')
var monitors = [];
var multiservers = [];
var oldevents = [];
+ var migrationComplete = false;
+
var languages = [
{
@@ -41,7 +43,10 @@ angular.module('zmApp.controllers')
];
var serverGroupList = {};
-
+ var defaultLang = 'en';
+ var isFirstUse = true;
+ var lastUpdateCheck = null;
+ var latestBlogPostChecked = null;
var loginData = {
'serverName': '',
'username': '',
@@ -65,7 +70,7 @@ angular.module('zmApp.controllers')
'eventServerInterval': '', // list of intervals for all monitors
'refreshSec': '2', // timer value for frame change in sec
'enableLogs': true,
- 'enableDebug': false, // if enabled with log messages with "debug"
+ 'enableDebug': true, // if enabled with log messages with "debug"
'usePin': false,
'pinCode': '',
'canSwipeMonitors': true,
@@ -140,11 +145,29 @@ angular.module('zmApp.controllers')
}
+
+
function setLogin(newLogin) {
loginData = angular.copy(newLogin);
serverGroupList[loginData.serverName] = angular.copy(loginData);
- $localstorage.setObject("serverGroupList", serverGroupList);
- $localstorage.set("defaultServerName", loginData.serverName);
+ //$localstorage.setObject("serverGroupList", serverGroupList);
+ localforage.setItem("serverGroupList", serverGroupList, function (err) {
+ if (err) zmLog("localforage store error " + JSON.stringify(err));
+ });
+ //$localstorage.set("defaultServerName", loginData.serverName);
+ localforage.setItem("defaultServerName", loginData.serverName, function (err) {
+ if (err) zmLog("localforage store error " + JSON.stringify(err));
+ });
+
+
+
+ //setDB("serverGroupList", serverGroupList);
+ //setDB ("defaultServerName", loginData.serverName);
+
+
+
+
+
// console.log ("SAVING " + loginData.serverName);
// console.log ("DATA IS " + JSON.stringify(loginData));
@@ -205,8 +228,13 @@ angular.module('zmApp.controllers')
// used by various controllers to log messages to file
//-------------------------------------------------------------
- isEmpty: function (obj)
- {
+ migrationComplete: function () {
+ migrationComplete = true;
+ },
+
+
+
+ isEmpty: function (obj) {
return isEmpty(obj);
},
@@ -223,6 +251,25 @@ angular.module('zmApp.controllers')
zmDebug(val);
},
+ setLastUpdateCheck: function (val) {
+ lastUpdateCheck = val;
+ localforage.setItem("lastUpdateCheck", lastUpdateCheck);
+ },
+
+ getLastUpdateCheck: function () {
+ return lastUpdateCheck;
+ },
+
+ setLatestBlogPostChecked: function (val) {
+ latestBlogPostChecked = val;
+ localforage.seItem("latestBlogPostChecked", latestBlogPostChecked);
+ },
+
+ getLatestBlogPostChecked: function () {
+ return latestBlogPostChecked;
+ },
+
+
// This function is called when the app is ready to run
// sets up various variables
// including persistent login data for the ZM apis and portal
@@ -369,185 +416,206 @@ angular.module('zmApp.controllers')
init: function () {
// console.log("****** DATAMODEL INIT SERVICE CALLED ********");
- zmLog("ZMData init: checking for stored variables & setting up log file");
- serverGroupList = $localstorage.getObject("serverGroupList");
- var demoServer = "{\"serverName\":\"zmNinjaDemo\",\"username\":\"zmninja\",\"password\":\"zmNinja$xc129\",\"url\":\"https://demo.zoneminder.com/zm\",\"apiurl\":\"https://demo.zoneminder.com/zm/api\",\"eventServer\":\"\",\"maxMontage\":\"40\",\"streamingurl\":\"https://demo.zoneminder.com/cgi-bin-zm\",\"maxFPS\":\"3\",\"montageQuality\":\"50\",\"singleImageQuality\":\"100\",\"montageHistoryQuality\":\"50\",\"useSSL\":true,\"keepAwake\":true,\"isUseAuth\":\"1\",\"isUseEventServer\":false,\"disablePush\":false,\"eventServerMonitors\":\"\",\"eventServerInterval\":\"\",\"refreshSec\":\"2\",\"enableDebug\":false,\"usePin\":false,\"pinCode\":\"\",\"canSwipeMonitors\":true,\"persistMontageOrder\":false,\"onTapScreen\":\"Events\",\"enableh264\":true,\"gapless\":false,\"montageOrder\":\"\",\"montageHiddenOrder\":\"\",\"montageArraySize\":\"0\",\"graphSize\":2000,\"enableAlarmCount\":true,\"montageSize\":\"3\",\"useNphZms\":true,\"useNphZmsForEvents\":true,\"packMontage\":false,\"exitOnSleep\":false,\"forceNetworkStop\":false,\"defaultPushSound\":false,\"enableBlog\":true,\"use24hr\":false, \"packeryPositions\":\"\"}";
- var demoS = JSON.parse(demoServer);
- console.log("JSON parsed demo" + JSON.stringify(demoS));
- var isFoundDemo = false;
- var as = Object.keys(serverGroupList);
- for (var x = 0; x < as.length; x++) {
- if (as[x] == 'zmNinjaDemo')
- isFoundDemo = true;
- //console.log ("************ FOUND SERVER NAME " + as[x]);
- // if serverGroupList[x]
- }
- // Don't add the demo if there is another server
- // because this means the user deleted it
- if (!isFoundDemo && as.length == 0) {
- zmDebug("Pushing demo server config to server groups");
- //serverGroupList.push(demoS);
- serverGroupList[demoS.serverName] = angular.copy(demoS);
- }
- var sname =
- $localstorage.get("defaultServerName");
- //console.log ("!!!!!!!!!!!!!!!!!!default server name is " + sname);
+ zmLog("ZMData init: checking for stored variables & setting up log file");
- var loadedData = serverGroupList[sname];
- if (!isEmpty(loadedData)) {
- loginData = loadedData;
+ $ionicLoading.show({
+ template: "retrieving profile data..."
+ });
+ localforage.getItem("serverGroupList").then(function (val) {
+ $ionicLoading.hide();
+ serverGroupList = val;
+ console.log(">>>> serverGroupList " + JSON.stringify(serverGroupList));
+ var demoServer = "{\"serverName\":\"zmNinjaDemo\",\"username\":\"zmninja\",\"password\":\"zmNinja$xc129\",\"url\":\"https://demo.zoneminder.com/zm\",\"apiurl\":\"https://demo.zoneminder.com/zm/api\",\"eventServer\":\"\",\"maxMontage\":\"40\",\"streamingurl\":\"https://demo.zoneminder.com/cgi-bin-zm\",\"maxFPS\":\"3\",\"montageQuality\":\"50\",\"singleImageQuality\":\"100\",\"montageHistoryQuality\":\"50\",\"useSSL\":true,\"keepAwake\":true,\"isUseAuth\":\"1\",\"isUseEventServer\":false,\"disablePush\":false,\"eventServerMonitors\":\"\",\"eventServerInterval\":\"\",\"refreshSec\":\"2\",\"enableDebug\":false,\"usePin\":false,\"pinCode\":\"\",\"canSwipeMonitors\":true,\"persistMontageOrder\":false,\"onTapScreen\":\"Events\",\"enableh264\":true,\"gapless\":false,\"montageOrder\":\"\",\"montageHiddenOrder\":\"\",\"montageArraySize\":\"0\",\"graphSize\":2000,\"enableAlarmCount\":true,\"montageSize\":\"3\",\"useNphZms\":true,\"useNphZmsForEvents\":true,\"packMontage\":false,\"exitOnSleep\":false,\"forceNetworkStop\":false,\"defaultPushSound\":false,\"enableBlog\":true,\"use24hr\":false, \"packeryPositions\":\"\"}";
+ var demoS = JSON.parse(demoServer);
+ console.log("JSON parsed demo" + JSON.stringify(demoS));
+
+ var isFoundDemo = false;
+ var as = Object.keys(serverGroupList);
+ for (var x = 0; x < as.length; x++) {
+ if (as[x] == 'zmNinjaDemo')
+ isFoundDemo = true;
+ //console.log ("************ FOUND SERVER NAME " + as[x]);
+ // if serverGroupList[x]
+ }
- // old version hacks for new variables
+ // Don't add the demo if there is another server
+ // because this means the user deleted it
- if (typeof loginData.enableAlarmCount === 'undefined') {
- zmDebug("enableAlarmCount does not exist, setting to true");
- loginData.enableAlarmCount = true;
+ if (!isFoundDemo && as.length == 0) {
+ zmDebug("Pushing demo server config to server groups");
+ //serverGroupList.push(demoS);
+ serverGroupList[demoS.serverName] = angular.copy(demoS);
}
-
- if (typeof loginData.onTapScreen == 'undefined')
- {
- loginData.onTapScreen = $translate.instant('kTapMontage');
- }
-
- if (loginData.onTapScreen != $translate.instant('kTapMontage') &&
- loginData.onTapScreen != $translate.instant('kTapEvents') &&
- loginData.onTapScreen != $translate.instant('kTapLiveMonitor'))
- {
- zmLog ("Invalid onTap setting found, resetting");
- loginData.onTapScreen = $translate.instant('kMontage');
- }
-
- if (typeof loginData.minAlarmCount === 'undefined') {
- zmDebug("minAlarmCount does not exist, setting to true");
- loginData.minAlarmCount = 1;
- }
+ var sname;
+ $ionicLoading.show({
+ template: "retrieving profile data..."
+ });
+ localforage.getItem("defaultServerName")
+ .then(function (val) {
+ $ionicLoading.hide();
+ //console.log ("!!!!!!!!!!!!!!!!!!default server name is " + sname);
+ sname = val;
+ console.log("!!!!!!!!!!!!!!!!!!!Got VAL " + sname);
+ var loadedData = serverGroupList[sname];
+ console.log(">>>>>>>>>>> loadedData is: " + JSON.stringify(loadedData));
+ if (!isEmpty(loadedData)) {
+ loginData = loadedData;
+
+ // old version hacks for new variables
+
+ if (typeof loginData.enableAlarmCount === 'undefined') {
+ zmDebug("enableAlarmCount does not exist, setting to true");
+ loginData.enableAlarmCount = true;
+ }
+ if (typeof loginData.onTapScreen == 'undefined') {
+ loginData.onTapScreen = $translate.instant('kTapMontage');
+ }
- if (typeof loginData.montageSize == 'undefined') {
- zmDebug("montageSize does not exist, setting to 2 (2 per col)");
- loginData.montageSize = 2;
- }
+ if (loginData.onTapScreen != $translate.instant('kTapMontage') &&
+ loginData.onTapScreen != $translate.instant('kTapEvents') &&
+ loginData.onTapScreen != $translate.instant('kTapLiveMonitor')) {
+ zmLog("Invalid onTap setting found, resetting");
+ loginData.onTapScreen = $translate.instant('kMontage');
+ }
- if (typeof loginData.useNphZms == 'undefined') {
- zmDebug("useNphZms does not exist. Setting to true");
- loginData.useNphZms = true;
- }
+ if (typeof loginData.minAlarmCount === 'undefined') {
+ zmDebug("minAlarmCount does not exist, setting to true");
+ loginData.minAlarmCount = 1;
+ }
+ if (typeof loginData.montageSize == 'undefined') {
+ zmDebug("montageSize does not exist, setting to 2 (2 per col)");
+ loginData.montageSize = 2;
+ }
- if (typeof loginData.useNphZmsForEvents == 'undefined') {
- zmDebug("useNphZmsForEvents does not exist. Setting to true");
- loginData.useNphZmsForEvents = true;
- }
- if (typeof loginData.forceImageModePath == 'undefined') {
- zmDebug("forceImageModePath does not exist. Setting to false");
- loginData.forceImageModePath = false;
- }
+ if (typeof loginData.useNphZms == 'undefined') {
+ zmDebug("useNphZms does not exist. Setting to true");
+ loginData.useNphZms = true;
+ }
- if (typeof loginData.reachability == 'undefined') {
- zmDebug("reachability does not exist. Setting to true");
- loginData.reachability = true;
- }
- // force it - this may not be the problem
- loginData.reachability = true;
- // and now, force enable it
- loginData.useNphZms = true;
- loginData.useNphZmsForEvents = true;
- if (typeof loginData.packMontage == 'undefined') {
- zmDebug("packMontage does not exist. Setting to false");
- loginData.packMontage = false;
- }
+ if (typeof loginData.useNphZmsForEvents == 'undefined') {
+ zmDebug("useNphZmsForEvents does not exist. Setting to true");
+ loginData.useNphZmsForEvents = true;
+ }
- if (typeof loginData.forceNetworkStop == 'undefined') {
- zmDebug("forceNetwork does not exist. Setting to false");
- loginData.forceNetworkStop = false;
- }
+ if (typeof loginData.forceImageModePath == 'undefined') {
+ zmDebug("forceImageModePath does not exist. Setting to false");
+ loginData.forceImageModePath = false;
+ }
- if (typeof loginData.enableLogs == 'undefined') {
- zmDebug("enableLogs does not exist. Setting to true");
- loginData.enableLogs = true;
- }
+ if (typeof loginData.reachability == 'undefined') {
+ zmDebug("reachability does not exist. Setting to true");
+ loginData.reachability = true;
+ }
+ // force it - this may not be the problem
+ loginData.reachability = true;
+ // and now, force enable it
+ loginData.useNphZms = true;
+ loginData.useNphZmsForEvents = true;
+ if (typeof loginData.packMontage == 'undefined') {
+ zmDebug("packMontage does not exist. Setting to false");
+ loginData.packMontage = false;
+ }
- if (typeof loginData.defaultPushSound == 'undefined') {
- zmDebug("defaultPushSound does not exist. Setting to false");
- loginData.defaultPushSound = false;
- }
+ if (typeof loginData.forceNetworkStop == 'undefined') {
+ zmDebug("forceNetwork does not exist. Setting to false");
+ loginData.forceNetworkStop = false;
+ }
+ if (typeof loginData.enableLogs == 'undefined') {
+ zmDebug("enableLogs does not exist. Setting to true");
+ loginData.enableLogs = true;
+ }
- if (typeof loginData.exitOnSleep == 'undefined') {
- zmDebug("exitOnSleep does not exist. Setting to false");
- loginData.exitOnSleep = false;
- }
- if (typeof loginData.enableBlog == 'undefined') {
- zmDebug("enableBlog does not exist. Setting to true");
- loginData.enableBlog = true;
+ if (typeof loginData.defaultPushSound == 'undefined') {
+ zmDebug("defaultPushSound does not exist. Setting to false");
+ loginData.defaultPushSound = false;
+ }
- }
- if (typeof loginData.packeryPositions == 'undefined') {
- zmDebug("packeryPositions does not exist. Setting to empty");
- loginData.packeryPositions = "";
- }
+ if (typeof loginData.exitOnSleep == 'undefined') {
+ zmDebug("exitOnSleep does not exist. Setting to false");
+ loginData.exitOnSleep = false;
+ }
+ if (typeof loginData.enableBlog == 'undefined') {
+ zmDebug("enableBlog does not exist. Setting to true");
+ loginData.enableBlog = true;
- if (typeof loginData.packerySizes == 'undefined') {
- zmDebug("packerySizes does not exist. Setting to empty");
- loginData.packerySizes = "";
+ }
- }
+ if (typeof loginData.packeryPositions == 'undefined') {
+ zmDebug("packeryPositions does not exist. Setting to empty");
+ loginData.packeryPositions = "";
- if (typeof loginData.use24hr == 'undefined') {
- zmDebug("use24hr does not exist. Setting to false");
- loginData.use24hr = false;
+ }
- }
- if (typeof timelineModalGraphType == 'undefined') {
- zmDebug("timeline graph type not set. Setting to all");
- loginData.timelineModalGraphType = $translate.instant('kGraphAll');
- console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + loginData.timelineModalGraphType);
- }
+ if (typeof loginData.packerySizes == 'undefined') {
+ zmDebug("packerySizes does not exist. Setting to empty");
+ loginData.packerySizes = "";
- if (typeof loginData.resumeDelay == 'undefined') {
- zmDebug("resumeDelay does not exist. Setting to 0");
- loginData.resumeDelay = "0";
+ }
- }
+ if (typeof loginData.use24hr == 'undefined') {
+ zmDebug("use24hr does not exist. Setting to false");
+ loginData.use24hr = false;
+ }
+ if (typeof timelineModalGraphType == 'undefined') {
+ zmDebug("timeline graph type not set. Setting to all");
+ loginData.timelineModalGraphType = $translate.instant('kGraphAll');
+ console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + loginData.timelineModalGraphType);
+ }
- if (typeof loginData.montageHistoryQuality == 'undefined') {
- zmDebug("montageHistoryQuality does not exist. Setting to 50");
- loginData.montageHistoryQuality = "50";
+ if (typeof loginData.resumeDelay == 'undefined') {
+ zmDebug("resumeDelay does not exist. Setting to 0");
+ loginData.resumeDelay = "0";
+
+ }
- }
- zmLog("DataModel init recovered this loginData as " + JSON.stringify(loginData));
- } else {
- zmLog("defaultServer configuration NOT found. Keeping login at defaults");
- }
+ if (typeof loginData.montageHistoryQuality == 'undefined') {
+ zmDebug("montageHistoryQuality does not exist. Setting to 50");
+ loginData.montageHistoryQuality = "50";
- monitorsLoaded = 0;
- //console.log("Getting out of ZMDataModel init");
- $rootScope.showBlog = loginData.enableBlog;
- zmDebug("loginData structure values: " + JSON.stringify(loginData));
+ }
+
+ zmLog("DataModel init recovered this loginData as " + JSON.stringify(loginData));
+ } else {
+ zmLog("defaultServer configuration NOT found. Keeping login at defaults");
+ }
+ // FIXME: HACK: This is the latest entry point into dataModel init, so start portal login after this
+ // not the neatest way
+ $rootScope.$emit('init-complete');
+ });
+
+ monitorsLoaded = 0;
+ //console.log("Getting out of ZMDataModel init");
+ $rootScope.showBlog = loginData.enableBlog;
+ zmDebug("loginData structure values: " + JSON.stringify(loginData));
+ //$rootScope.$emit('init-complete');
+ });
},
@@ -592,10 +660,16 @@ angular.module('zmApp.controllers')
setDefaultLanguage: function (l, permanent) {
if (!l) l = 'en';
+ defaultLang = l;
var d = $q.defer();
- if (permanent)
- window.localStorage.setItem("defaultLang", l);
+ if (permanent) {
+ //window.localStorage.setItem("defaultLang", l);
+
+ console.log("setting default lang");
+ localforage.setItem("defaultlang", l);
+ }
+ console.log("invoking translate use with " + l);
$translate.use(l).then(function (data) {
zmLog("Device Language is:" + data);
moment.locale(data);
@@ -613,7 +687,8 @@ angular.module('zmApp.controllers')
},
getDefaultLanguage: function () {
- return window.localStorage.getItem("defaultLang");
+ return defaultLang;
+ //return window.localStorage.getItem("defaultLang");
},
@@ -653,7 +728,9 @@ angular.module('zmApp.controllers')
},
isFirstUse: function () {
- return ((window.localStorage.getItem("isFirstUse") == undefined) ? true : false);
+ console.log("isFirstUse is " + isFirstUse);
+ return isFirstUse;
+ // return ((window.localStorage.getItem("isFirstUse") == undefined) ? true : false);
},
@@ -665,7 +742,10 @@ angular.module('zmApp.controllers')
// Allow the option to reset first use if I need it in future
//-----------------------------------------------------------------
setFirstUse: function (val) {
- window.localStorage.setItem("isFirstUse", val ? "1" : "0");
+ //window.localStorage.setItem("isFirstUse", val ? "1" : "0");
+ //localforage.setItem("isFirstUse", val,
+ // function(err) {if (err) zmLog ("localforage error, //storing isFirstUse: " + JSON.stringify(err));});
+ isFirstUse = val;
},
diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js
index 06164891..643d0ff9 100644
--- a/www/js/LoginCtrl.js
+++ b/www/js/LoginCtrl.js
@@ -1,8 +1,8 @@
/* jshint -W041 */
/* jslint browser: true*/
-/* global cordova,StatusBar,angular,console,alert,URI */
+/* global cordova,StatusBar,angular,console,alert,URI, localforage */
-angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', 'zmAutoLogin', '$cordovaPinDialog', 'EventServer', '$ionicHistory', '$state', '$ionicActionSheet', 'SecuredPopups', '$localstorage', '$stateParams', '$translate', function ($scope, $rootScope, zm, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading, zmAutoLogin, $cordovaPinDialog, EventServer, $ionicHistory, $state, $ionicActionSheet, SecuredPopups, $localstorage, $stateParams, $translate) {
+angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', 'zmAutoLogin', '$cordovaPinDialog', 'EventServer', '$ionicHistory', '$state', '$ionicActionSheet', 'SecuredPopups', '$stateParams', '$translate', function ($scope, $rootScope, zm, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading, zmAutoLogin, $cordovaPinDialog, EventServer, $ionicHistory, $state, $ionicActionSheet, SecuredPopups, $stateParams, $translate) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -34,7 +34,7 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
function onPause()
{
ZMDataModel.zmLog ("Login screen going to background, saving data");
- $localstorage.setObject ("settings-temp-data",$scope.loginData);
+ localforage.setItem ("settings-temp-data",$scope.loginData);
}
@@ -251,17 +251,22 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
else
{
- var savedData = $localstorage.getObject ("settings-temp-data");
- if (! ZMDataModel.isEmpty(savedData))
- {
- $scope.loginData = savedData;
- ZMDataModel.zmLog ("retrieved pre-stored loginData on past pause: " + JSON.stringify($scope.loginData));
- $localstorage.setObject("settings-temp-data", {});
- }
- else
- {
- ZMDataModel.zmLog ("Not recovering login data as its empty");
- }
+ var savedData;
+ localforage.getItem("settings-temp-data").then (function(value) {
+ savedData = value;
+ //= zmStorageService.getObject ("settings-temp-data");
+ if (! ZMDataModel.isEmpty(savedData))
+ {
+ $scope.loginData = savedData;
+ ZMDataModel.zmLog ("retrieved pre-stored loginData on past pause: " + JSON.stringify($scope.loginData));
+ localforage.removeItem("settings-temp-data");
+ //zmStorageService.setObject("settings-temp-data", {});
+ }
+ else
+ {
+ ZMDataModel.zmLog ("Not recovering login data as its empty");
+ }
+ });
}
diff --git a/www/js/NewsCtrl.js b/www/js/NewsCtrl.js
index a0ab8565..b914b32a 100644
--- a/www/js/NewsCtrl.js
+++ b/www/js/NewsCtrl.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
/* global cordova,StatusBar,angular,console,moment*/
-angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$rootScope', '$ionicModal', 'ZMDataModel','$ionicSideMenuDelegate', '$ionicHistory', '$state', '$http', 'zm', '$localstorage', function ($scope, $rootScope, $ionicModal, ZMDataModel,$ionicSideMenuDelegate, $ionicHistory, $state, $http, zm, $localstorage) {
+angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$rootScope', '$ionicModal', 'ZMDataModel','$ionicSideMenuDelegate', '$ionicHistory', '$state', '$http', 'zm', function ($scope, $rootScope, $ionicModal, ZMDataModel,$ionicSideMenuDelegate, $ionicHistory, $state, $http, zm) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -39,7 +39,8 @@ $scope.openMenu = function () {
$scope.isUnread = function(itemdate)
{
- var lastDate = $localstorage.get("latestBlogPostChecked");
+ var lastDate = ZMDataModel.getLatestBlogPostChecked();
+ //get("latestBlogPostChecked");
if (!lastDate) return true;
var mLastDate = moment(lastDate);
var mItemDate = moment(itemdate);
@@ -52,13 +53,15 @@ $scope.openMenu = function () {
$scope.loadPost = function (item, itemdate)
{
- var lastDate = $localstorage.get("latestBlogPostChecked");
+ var lastDate =
+ ZMDataModel.getLatestBlogPostChecked(); //zmStorageService.get("latestBlogPostChecked");
if (!lastDate)
{
ZMDataModel.zmDebug ("First time checking blog posts, I see");
- $localstorage.set("latestBlogPostChecked", itemdate);
+ ZMDataModel.setLatestBlogPostChecked(itemdate);
+ //zmStorageService.set("latestBlogPostChecked", itemdate);
}
else
@@ -71,7 +74,8 @@ $scope.openMenu = function () {
if (mItemDate.diff(mLastDate) >0)
{
ZMDataModel.zmDebug ("Updating lastDate to this post");
- $localstorage.set("latestBlogPostChecked", itemdate);
+
+ ZMDataModel.setLatestBlogPostChecked(itemdate); //zmStorageService.set("latestBlogPostChecked", itemdate);
if (itemdate == $scope.newsItems[0].date)
{
diff --git a/www/js/app.js b/www/js/app.js
index b6afba53..40fb76cb 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -1,11 +1,12 @@
/* jshint -W041 */
/* jslint browser: true*/
-/* global cordova,StatusBar,angular,console,alert,PushNotification, moment ,ionic, URI,Packery, ConnectSDK,$*/
+/* global cordova,StatusBar,angular,console,alert,PushNotification, moment ,ionic, URI,Packery, ConnectSDK, localforage,$*/
var appVersion = "0.0.0";
+
// core app start stuff
angular.module('zmApp', [
'ionic',
@@ -76,7 +77,9 @@ angular.module('zmApp', [
nphSwitchTimer: 3000,
eventHistoryTimer: 10000,
eventPlaybackQuery: 3000,
- packeryTimer:500
+ packeryTimer: 500,
+ dbName: 'zmninja.db',
+ dbTableName: 'userProfile'
@@ -84,23 +87,23 @@ angular.module('zmApp', [
// filter for montage iteration
-.filter('onlyEnabled', function() {
+.filter('onlyEnabled', function () {
- // Create the return function and set the required parameter name to **input**
- return function(input) {
+ // Create the return function and set the required parameter name to **input**
+ return function (input) {
- var out = [];
+ var out = [];
- angular.forEach(input, function(item) {
+ angular.forEach(input, function (item) {
- if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled!='0')) {
- out.push(item);
- }
-
- });
+ if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0')) {
+ out.push(item);
+ }
- return out;
- };
+ });
+
+ return out;
+ };
})
@@ -115,19 +118,20 @@ angular.module('zmApp', [
})
-.directive('dannyPackery', ['$rootScope', function($rootScope) {
+.directive('dannyPackery', ['$rootScope', function ($rootScope) {
return {
restrict: 'A',
- link: function(scope, element, attrs) {
+ link: function (scope, element, attrs) {
console.log('Running dannyPackery linking function!');
- if($rootScope.packery === undefined || $rootScope.packery === null){
+ if ($rootScope.packery === undefined || $rootScope.packery === null) {
console.log('making packery!');
- $rootScope.packery = new Packery(element[0].parentElement, {columnWidth: '.item'});
+ $rootScope.packery = new Packery(element[0].parentElement, {
+ columnWidth: '.item'
+ });
$rootScope.packery.bindResize();
$rootScope.packery.appended(element[0]);
- $rootScope.packery.items.splice(1,1); // hack to fix a bug where the first element was added twice in two different positions
- }
- else{
+ $rootScope.packery.items.splice(1, 1); // hack to fix a bug where the first element was added twice in two different positions
+ } else {
$rootScope.packery.appended(element[0]);
}
$rootScope.packery.layout();
@@ -137,23 +141,23 @@ angular.module('zmApp', [
// credit https://gist.github.com/Zren/beaafd64f395e23f4604
-.directive('mouseWheelScroll', function($timeout) {
+.directive('mouseWheelScroll', function ($timeout) {
return {
- restrict: 'A',
- link: function($scope, $element, $attrs) {
- var onMouseWheel, scrollCtrl;
- scrollCtrl = $element.controller('$ionicScroll');
- //console.log(scrollCtrl);
- if (!scrollCtrl) {
- return console.error('mouseWheelScroll must be attached to a $ionicScroll controller.');
+ restrict: 'A',
+ link: function ($scope, $element, $attrs) {
+ var onMouseWheel, scrollCtrl;
+ scrollCtrl = $element.controller('$ionicScroll');
+ //console.log(scrollCtrl);
+ if (!scrollCtrl) {
+ return console.error('mouseWheelScroll must be attached to a $ionicScroll controller.');
+ }
+ onMouseWheel = function (e) {
+ return scrollCtrl.scrollBy(0, -e.wheelDeltaY, false);
+ };
+ return scrollCtrl.element.addEventListener('wheel', onMouseWheel);
}
- onMouseWheel = function(e) {
- return scrollCtrl.scrollBy(0, -e.wheelDeltaY, false);
- };
- return scrollCtrl.element.addEventListener('wheel', onMouseWheel);
- }
};
- })
+})
// this can be used to route img-src through interceptors. Works well, but when
// nph-zms streams images it doesn't work as success is never received
@@ -452,7 +456,7 @@ angular.module('zmApp', [
'request': function (config) {
- // console.log (">>>>"+config.url);
+ // console.log (">>>>"+config.url);
// handle basic auth properly
if (config.url.indexOf("@") > -1) {
//console.log ("HTTP basic auth INTERCEPTOR URL IS " + config.url);
@@ -483,14 +487,10 @@ angular.module('zmApp', [
// these can take time, so lets bump up timeout
config.timeout = zm.largeHttpTimeout;
- }
- else if ((config.url.indexOf("view=view_video")> -1) ||
- config.url.indexOf(".mp4")>-1)
- {
- console.log (">>> skipping timers for MP4");
- }
- else
- {
+ } else if ((config.url.indexOf("view=view_video") > -1) ||
+ config.url.indexOf(".mp4") > -1) {
+ console.log(">>> skipping timers for MP4");
+ } else {
config.timeout = zm.httpTimeout;
}
return config;
@@ -537,7 +537,7 @@ angular.module('zmApp', [
function checkUpdate() {
- var lastdateString = $localstorage.get("lastUpdateCheck");
+ var lastdateString = ZMDataModel.getLastUpdateCheck();
var lastdate;
if (!lastdateString) {
@@ -558,8 +558,8 @@ angular.module('zmApp', [
$http.get(zm.latestRelease)
.then(function (success) {
-
- $localstorage.set("lastUpdateCheck", moment().toISOString());
+ ZMDataModel.setLastUpdateCheck(moment().toISOString());
+ // $localstorage.set("lastUpdateCheck", moment().toISOString());
//console.log ("FULL STRING " + success.data.tag_name);
var res = success.data.tag_name.match("v(.*)");
zmUpdateVersion = res[1];
@@ -584,7 +584,7 @@ angular.module('zmApp', [
return;
}
- var lastDate = $localstorage.get("latestBlogPostChecked");
+ var lastDate = ZMDataModel.getLatestBlogPostChecked();
if (!lastDate) {
$rootScope.newBlogPost = "(new post)";
@@ -649,6 +649,11 @@ angular.module('zmApp', [
// doLogin() emits this when our auth credentials work
//------------------------------------------------------------------
+ $rootScope.$on("init-complete", function () {
+ ZMDataModel.zmLog (">>>>>>>>>>>>>>> All init over, going to portal login");
+ $state.go("zm-portal-login");
+ });
+
$rootScope.$on("auth-success", function () {
var contentBannerInstance = $ionicContentBanner.show({
@@ -723,7 +728,7 @@ angular.module('zmApp', [
});
-
+
return d.promise;
@@ -818,7 +823,7 @@ angular.module('zmApp', [
//eventServer.start();
$rootScope.loggedIntoZm = 1;
- ZMDataModel.zmLog("zmAutologin successfully logged into Zoneminder");
+ ZMDataModel.zmLog("zmAutolog.runin successfully logged into Zoneminder");
d.resolve("Login Success");
@@ -916,10 +921,10 @@ angular.module('zmApp', [
//====================================================================
-.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate) {
+.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate, $localstorage) {
+
-
$rootScope.appName = "zmNinja";
$rootScope.zmGlobalCookie = "";
@@ -951,7 +956,7 @@ angular.module('zmApp', [
// only for android
$rootScope.exitApp = function () {
ZMDataModel.zmLog("user exited app");
-
+
ionic.Platform.exitApp();
};
@@ -979,7 +984,7 @@ angular.module('zmApp', [
});
}, false);
-
+
// This code takes care of trapping the Android back button
// and takes it to the menu.
@@ -1024,6 +1029,7 @@ angular.module('zmApp', [
$rootScope.userCancelledAuth = true;
window.stop();
+ console.log ("inside cancelAuth , calling wizard");
$state.go("login", {
"wizard": false
});
@@ -1037,14 +1043,16 @@ angular.module('zmApp', [
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
- if (ZMDataModel.isLoggedIn()) {
+ if (ZMDataModel.isLoggedIn() || toState.name =="login" ) {
//console.log("State transition is authorized");
return;
} else {
- ZMDataModel.zmLog("Not logged in, requested to go to " + JSON.stringify(toState));
+ ZMDataModel.zmLog("In Auth State trans: Not logged in, requested to go to " + JSON.stringify(toState));
// event.preventDefault();
- // $state.transitionTo('login');
+ //
+
+ $state.transitionTo('login');
}
@@ -1071,111 +1079,208 @@ angular.module('zmApp', [
//---------------------------------------------------------------------
$ionicPlatform.ready(function () {
-
- var pixelRatio = window.devicePixelRatio || 1;
- $rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width);
- $rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height);
- // for making sure we canuse $state.go with ng-click
- // needed for views that use popovers
- $rootScope.$state = $state;
- $rootScope.$stateParams = $stateParams;
-
-
- if (window.cordova && window.cordova.plugins.Keyboard) {
- cordova.plugins.Keyboard.disableScroll(true);
- }
- if (window.StatusBar) {
- // org.apache.cordova.statusbar required
- StatusBar.styleDefault();
- }
-
-
- if (window.cordova) {
- $cordovaSplashscreen.hide();
-
- ZMDataModel.zmLog ("Enabling insecure SSL");
- cordova.plugins.certificates.trustUnsecureCerts(true);
-
- cordova.getAppVersion(function (version) {
- appVersion = version;
- ZMDataModel.zmLog("App Version: " + appVersion);
- ZMDataModel.setAppVersion(appVersion);
- });
- }
-
- $fileLogger.checkFile().then(function (resp) {
- if (parseInt(resp.size) > zm.logFileMaxSize) {
-
- $fileLogger.deleteLogfile().then(function () {
- ZMDataModel.zmLog("Deleting old log file as it exceeds " + zm.logFileMaxSize + " bytes");
- });
- }
- });
-
- $fileLogger.setStorageFilename(zm.logFile);
- $fileLogger.setTimestampFormat('MMM d, y ' + ZMDataModel.getTimeFormat());
-
-
+ $rootScope.db = null;
$rootScope.platformOS = "desktop";
ZMDataModel.zmLog("Device is ready");
- var ld = ZMDataModel.getLogin();
+ // var ld = ZMDataModel.getLogin();
if ($ionicPlatform.is('ios'))
$rootScope.platformOS = "ios";
if ($ionicPlatform.is('android'))
$rootScope.platformOS = "android";
ZMDataModel.zmLog("You are running on " + $rootScope.platformOS);
-
- $ionicNativeTransitions.enable(true, false);
-
-
- var lang = ZMDataModel.getDefaultLanguage();
-
-
- if (lang == undefined)
- {
- ZMDataModel.zmLog ("No language set, switching to en");
- lang = "en";
+
+
+
+ localforage.defineDriver(window.cordovaSQLiteDriver).then(function () {
+ return localforage.setDriver([
+ // Try setting cordovaSQLiteDriver if available,
+ window.cordovaSQLiteDriver._driver,
+ // otherwise use one of the default localforage drivers as a fallback.
+ // This should allow you to transparently do your tests in a browser
+ localforage.LOCALSTORAGE,
+ localforage.INDEXEDDB,
+ localforage.WEBSQL
-
- }
- else
- {
- ZMDataModel.zmLog ("Language stored as:"+lang);
-
- }
-
- // This always returns success - I'm not rejecting
- ZMDataModel.setDefaultLanguage(lang, false)
- .then (function(success) {
- ZMDataModel.zmLog(">>>>Language to be used:" + $translate.proposedLanguage());
- moment.locale($translate.proposedLanguage());
- continueRestOfInit();
-
- });
+ ]);
+ }).then(function () {
+ // this should alert "cordovaSQLiteDriver" when in an emulator or a device
+ ZMDataModel.zmLog("localforage driver for storage:" + localforage.driver());
+
+ // Now lets import old data if it exists:
+ var defaultServerName = $localstorage.get("defaultServerName");
+
+ localforage.getItem("defaultServerName")
+ .then (function (val)
+ {
+ if (!val && defaultServerName)
+ {
+ ZMDataModel.zmLog (">>>>Importing data from localstorage....");
+
+
+
+ var dsn = defaultServerName;
+ var dl = $localstorage.get('defaultLang');
+ var ifu = ($localstorage.get('isFirstUse')=='0' ? false:true);
+ var luc = $localstorage.get('lastUpdateCheck');
+ var lbpc = $localstorage.get('latestBlogPostChecked');
+ var sgl = $localstorage.getObject('serverGroupList');
+
+ ZMDataModel.zmLog (">>>Localstorage data found as below:");
+ ZMDataModel.zmLog ("server name:"+dsn);
+ ZMDataModel.zmLog ("default lang :"+dl);
+ ZMDataModel.zmLog ("is first use:"+ifu);
+ ZMDataModel.zmLog ("last update check:"+luc);
+ ZMDataModel.zmLog ("latest blog post check:"+lbpc);
+ ZMDataModel.zmLog ("server group list:"+sgl);
+
+ localforage.setItem('defaultLang', dl)
+ .then (function() {
+
+ ZMDataModel.zmLog (">>>>migrated defaultLang...");
+ ZMDataModel.setFirstUse(ifu);
+ return localforage.setItem('isFirstUse', ifu);
+ })
+ .then (function() {
+ ZMDataModel.zmLog (">>>>migrated isFirstUse...");
+ return localforage.setItem('lastUpdateCheck', ifu);
+ })
+ .then (function() {
+ ZMDataModel.zmLog (">>>>migrated lastUpdateCheck...");
+ return localforage.setItem('latestBlogPostChecked', lbpc);
+ })
+ .then (function() {
+ ZMDataModel.zmLog (">>>>migrated latestBlogPostChecked...");
+ return localforage.setItem('serverGroupList', sgl);
+ })
+ .then (function() {
+ ZMDataModel.zmLog (">>>>migrated serverGroupList...");
+ return localforage.setItem('defaultServerName',dsn);
+ })
+ .then (function() {
+ ZMDataModel.zmLog (">>>>migrated defaultServerName...");
+ ZMDataModel.zmLog (">>>>Migrated all values, continuing...");
+ //ZMDataModel.migrationComplete();
+ continueInitialInit();
+ });
+
+ }
+ else
+ {
+ ZMDataModel.zmLog (">>>>No data to import....");
+ //ZMDataModel.migrationComplete();
+ continueInitialInit();
+ }
+
+
+
+ });
+
+ });
+
-
-
- function continueRestOfInit()
+ function continueInitialInit()
{
+ var pixelRatio = window.devicePixelRatio || 1;
+ $rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width);
+ $rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height);
+ // for making sure we canuse $state.go with ng-click
+ // needed for views that use popovers
+ $rootScope.$state = $state;
+ $rootScope.$stateParams = $stateParams;
+
+
+ if (window.cordova && window.cordova.plugins.Keyboard) {
+ cordova.plugins.Keyboard.disableScroll(true);
+ }
+ if (window.StatusBar) {
+ // org.apache.cordova.statusbar required
+ StatusBar.styleDefault();
+ }
+
+
+ if (window.cordova) {
+ $cordovaSplashscreen.hide();
+
+ ZMDataModel.zmLog("Enabling insecure SSL");
+ cordova.plugins.certificates.trustUnsecureCerts(true);
+
+ cordova.getAppVersion(function (version) {
+ appVersion = version;
+ ZMDataModel.zmLog("App Version: " + appVersion);
+ ZMDataModel.setAppVersion(appVersion);
+ });
+ }
+
+ $fileLogger.checkFile().then(function (resp) {
+ if (parseInt(resp.size) > zm.logFileMaxSize) {
+
+ $fileLogger.deleteLogfile().then(function () {
+ ZMDataModel.zmLog("Deleting old log file as it exceeds " + zm.logFileMaxSize + " bytes");
+
+ });
+ }
+ });
+
+ $fileLogger.setStorageFilename(zm.logFile);
+ $fileLogger.setTimestampFormat('MMM d, y ' + ZMDataModel.getTimeFormat());
+
+
+
+
+ $ionicNativeTransitions.enable(true, false);
+
+
+ var lang = ZMDataModel.getDefaultLanguage();
+
+
+ if (lang == undefined) {
+ ZMDataModel.zmLog("No language set, switching to en");
+ lang = "en";
+
+
+ } else {
+ ZMDataModel.zmLog("Language stored as:" + lang);
+
+ }
+ //continueRestOfInit();
+ // This always returns success - I'm not rejecting
+ ZMDataModel.setDefaultLanguage(lang, false)
+ .then(function (success) {
+ ZMDataModel.zmLog(">>>>Language to be used:" + $translate.proposedLanguage());
+ moment.locale($translate.proposedLanguage());
+ continueRestOfInit();
+
+ });
+ }
+
+
+
+
+
+
+ function continueRestOfInit() {
ZMDataModel.zmLog("Language file loaded, continuing with rest");
ZMDataModel.init();
EventServer.init();
zmCheckUpdates.start();
ZMDataModel.zmLog("Setting up POST LOGIN timer");
zmAutoLogin.start();
+
+
+
}
-
- //---------------------------------------------------------------------------
- // resume handler
- //----------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------------
+ // resume handler
+ //----------------------------------------------------------------------------
document.addEventListener("resume", function () {
ZMDataModel.zmLog("App is resuming from background");
var forceDelay = ZMDataModel.getLogin().resumeDelay;
@@ -1218,9 +1323,9 @@ angular.module('zmApp', [
}, false);
- //---------------------------------------------------------------------------
- // background handler
- //----------------------------------------------------------------------------
+ //---------------------------------------------------------------------------
+ // background handler
+ //----------------------------------------------------------------------------
document.addEventListener("pause", function () {
ZMDataModel.setBackground(true);
ZMDataModel.setJustResumed(true); // used for window stop
@@ -1251,9 +1356,9 @@ angular.module('zmApp', [
}, false);
-
-
+
+
}); //platformReady
@@ -1302,28 +1407,28 @@ angular.module('zmApp', [
$ionicNativeTransitionsProvider.setDefaultOptions({
duration: 250,
});
-
+
$translateProvider.useStaticFilesLoader({
- prefix: 'lang/locale-',
- suffix: '.json'
- });
-
+ prefix: 'lang/locale-',
+ suffix: '.json'
+ });
+
//$translateProvider.useLocalStorage();
-
-
- $translateProvider.registerAvailableLanguageKeys(['en', 'de','es', 'fr', 'it', 'ja', 'ko', 'zh', 'zh_CN', 'zh_TW', 'pt'], {
- 'en_*': 'en',
- 'de_*': 'de',
- 'es_*': 'es',
- 'fr_*': 'fr',
- 'it_*': 'it',
- 'ja_*': 'ja',
- 'ko_*': 'ko',
- 'pt_*': 'pt',
- '*': 'en' // must be last
- });
-
-
+
+
+ $translateProvider.registerAvailableLanguageKeys(['en', 'de', 'es', 'fr', 'it', 'ja', 'ko', 'zh', 'zh_CN', 'zh_TW', 'pt'], {
+ 'en_*': 'en',
+ 'de_*': 'de',
+ 'es_*': 'es',
+ 'fr_*': 'fr',
+ 'it_*': 'it',
+ 'ja_*': 'ja',
+ 'ko_*': 'ko',
+ 'pt_*': 'pt',
+ '*': 'en' // must be last
+ });
+
+
//$translateProvider.determinePreferredLanguage();
//$translateProvider.preferredLanguage("en");
@@ -1605,8 +1710,8 @@ angular.module('zmApp', [
$urlRouterProvider.otherwise(function ($injector, $location) {
var $state = $injector.get("$state");
-
- $state.go("zm-portal-login");
+ // we will do this after data is loaded
+ // $state.go("zm-portal-login");
});
diff --git a/www/js/ionicUtils.js b/www/js/ionicUtils.js
index dab37f6f..9b8a21ff 100644
--- a/www/js/ionicUtils.js
+++ b/www/js/ionicUtils.js
@@ -6,8 +6,13 @@
angular.module('ionic.utils', [])
-.factory('$localstorage', ['$window', function($window) {
+.factory('$localstorage', ['$window', function($window) {
return {
+
+ init: function()
+ {
+ },
+
set: function(key, value) {
$window.localStorage[key] = value;
},