diff options
| -rw-r--r-- | electron_js/main.js | 7 | ||||
| -rwxr-xr-x | make_desktop.sh | 1 | ||||
| -rwxr-xr-x | www/js/app.js | 2942 |
3 files changed, 1320 insertions, 1630 deletions
diff --git a/electron_js/main.js b/electron_js/main.js index 243e1f21..7aae0ea0 100644 --- a/electron_js/main.js +++ b/electron_js/main.js @@ -1,8 +1,7 @@ const electron = require('electron'); const windowStateKeeper = require('electron-window-state'); -//require('electron-debug')({showDevTools: true}); -// Module to control application life. const {app, globalShortcut} = electron; + // Module to create native browser window. const {BrowserWindow} = electron; var isFs = false; @@ -51,7 +50,6 @@ const mx = globalShortcut.register('CommandOrControl+Alt+F', () => { webPreferences:{nodeIntegration:false} }); - //win = new BrowserWindow({width: 1024, height: 900, webPreferences:{nodeIntegration:false}}); win = new BrowserWindow({ x: mainWindowState.x, y: mainWindowState.y, @@ -109,9 +107,6 @@ app.on('activate', () => { }); app.on('will-quit', () => { - // Unregister a shortcut. - //globalShortcut.unregister('CommandOrControl+X') - // Unregister all shortcuts. globalShortcut.unregisterAll() }); diff --git a/make_desktop.sh b/make_desktop.sh index 9353843d..b3d6e4e5 100755 --- a/make_desktop.sh +++ b/make_desktop.sh @@ -32,6 +32,7 @@ if [ -d "$i" ]; then exe cp -R www/* $i/app/ exe cp electron_js/* $i/app exe cp www/ZMNINJA-LICENSE-DESKTOP-CLIENT.txt ../$DIRNAME + echo $APPVER > ../$DIRNAME/version exe cp resources/icon.png ../$DIRNAME exe cd $i cat app/js/DataModel.js | sed "s/var zmAppVersion[ ]*=[ ]*\"unknown\"/var zmAppVersion=\"$APPVER\"/" > app/js/DataModel.js.tmp diff --git a/www/js/app.js b/www/js/app.js index eca72814..7df17a9d 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -13,1253 +13,1100 @@ var appVersion = "0.0.0"; // core app start stuff angular.module('zmApp', [ - 'ionic', - 'ion-datetime-picker', - 'ngIOS9UIWebViewPatch', - 'zmApp.controllers', - 'fileLogger', - 'angular-carousel', - 'angularAwesomeSlider', - 'com.2fdevs.videogular', - 'com.2fdevs.videogular.plugins.controls', - 'com.2fdevs.videogular.plugins.overlayplay', - 'ionic-native-transitions', - 'mgo-angular-wizard', - 'pascalprecht.translate', - 'jett.ionic.scroll.sista', - 'uk.ac.soton.ecs.videogular.plugins.cuepoints', - 'dcbImgFallback' - -]) - -// ------------------------------------------ -// Various constants central repository -// Feel free to change them as you see fit -//------------------------------------------------ - -.constant('zm', -{ - minAppVersion: '1.28.107', // if ZM is less than this, the app won't work - recommendedAppVersion: '1.29', - minEventServerVersion: '0.9', - castAppId: 'BA30FB4C', - alarmFlashTimer: 20000, // time to flash alarm - gcmSenderId: '710936220256', - httpTimeout: 15000, - largeHttpTimeout: 60000, - logFile: 'zmNinjaLog.txt', - authoremail: 'pliablepixels+zmNinja@gmail.com', - logFileMaxSize: 20000, // after this limit log gets reset - loginInterval: 300000, //5m*60s*1000 - ZM auto login after 5 mins - - //loginInterval: 30000, - updateCheckInterval: 86400000, // 24 hrs - loadingTimeout: 15000, - slowLoadingTimeout:60000, - safeMontageLimit: 100, - safeImageQuality: 10, - maxFPS: 30, - defaultFPS: 3, - maxMontageQuality: 70, - defaultMontageQuality: 50, - progressIntervalCheck: 5000, // used for progress indicator on event playback - graphFillColor: 'rgba(151,187,205,0.5)', - graphStrokeColor: 'rgba(151,187,205,0.8)', - graphHighlightFill: 'rgba(0,163,124,0.5)', - graphItemMax: 2000, - graphDesktopItemMax: 2000, - monitorCheckingColor: '#03A9F4', - monitorNotRunningColor: '#F44336', - monitorPendingColor: '#FF9800', - monitorRunningColor: '#4CAF50', - monitorErrorColor: '#795548', - montageScaleFrequency: 300, - eventsListDetailsHeight: 230.0, - eventsListScrubHeight: 330, - loginScreenString: "var currentView = 'login'", // Isn't there a better way? - desktopUrl: "/zm", - desktopApiUrl: "/api/zm", - latestRelease: "https://api.github.com/repos/pliablepixels/zmNinja/releases/latest", - blogUrl: "https://medium.com/zmninja/latest?format=json", - nphSwitchTimer: 3000, - eventHistoryTimer: 5000, - eventPlaybackQuery: 3000, - - packeryTimer: 500, - dbName: 'zmninja', - cipherKey: 'sdf#@#%FSXSA_AR', - minCycleTime: 5, - - eventPlaybackQueryLowBW: 6000, - loginIntervalLowBW: 600000, //10m login - eventSingleImageQualityLowBW: 70, - monSingleImageQualityLowBW: 70, - montageQualityLowBW: 50, - eventMontageQualityLowBW: 50, - maxGifCount:60, - maxGifCount2:100, - maxGifWidth:800.0, - quantSample:15, - -}) - -//http://stackoverflow.com/a/24519069/1361529 -.filter('trusted', ['$sce', function ($sce) { - return function(url) { - return $sce.trustAsResourceUrl(url); - }; -}]) - - -// for events view -.filter ('eventListFilter', function(NVRDataModel) -{ - return function (input) { - var ld = NVRDataModel.getLogin(); - var out = []; - angular.forEach (input, function (item) - { - if (item.Event.Archived == '0' || !ld.hideArchived) { - out.push(item); - } - }); - return out; - }; + 'ionic', + 'ion-datetime-picker', + 'ngIOS9UIWebViewPatch', + 'zmApp.controllers', + 'fileLogger', + 'angular-carousel', + 'angularAwesomeSlider', + 'com.2fdevs.videogular', + 'com.2fdevs.videogular.plugins.controls', + 'com.2fdevs.videogular.plugins.overlayplay', + 'ionic-native-transitions', + 'mgo-angular-wizard', + 'pascalprecht.translate', + 'jett.ionic.scroll.sista', + 'uk.ac.soton.ecs.videogular.plugins.cuepoints', + 'dcbImgFallback' + + ]) + + // ------------------------------------------ + // Various constants central repository + // Feel free to change them as you see fit + //------------------------------------------------ + + .constant('zm', { + minAppVersion: '1.28.107', // if ZM is less than this, the app won't work + recommendedAppVersion: '1.29', + minEventServerVersion: '0.9', + castAppId: 'BA30FB4C', + alarmFlashTimer: 20000, // time to flash alarm + gcmSenderId: '710936220256', + httpTimeout: 15000, + largeHttpTimeout: 60000, + logFile: 'zmNinjaLog.txt', + authoremail: 'pliablepixels+zmNinja@gmail.com', + logFileMaxSize: 20000, // after this limit log gets reset + loginInterval: 300000, //5m*60s*1000 - ZM auto login after 5 mins + + //loginInterval: 30000, + updateCheckInterval: 86400000, // 24 hrs + loadingTimeout: 15000, + slowLoadingTimeout: 60000, + safeMontageLimit: 100, + safeImageQuality: 10, + maxFPS: 30, + defaultFPS: 3, + maxMontageQuality: 70, + defaultMontageQuality: 50, + progressIntervalCheck: 5000, // used for progress indicator on event playback + graphFillColor: 'rgba(151,187,205,0.5)', + graphStrokeColor: 'rgba(151,187,205,0.8)', + graphHighlightFill: 'rgba(0,163,124,0.5)', + graphItemMax: 2000, + graphDesktopItemMax: 2000, + monitorCheckingColor: '#03A9F4', + monitorNotRunningColor: '#F44336', + monitorPendingColor: '#FF9800', + monitorRunningColor: '#4CAF50', + monitorErrorColor: '#795548', + montageScaleFrequency: 300, + eventsListDetailsHeight: 230.0, + eventsListScrubHeight: 330, + loginScreenString: "var currentView = 'login'", // Isn't there a better way? + desktopUrl: "/zm", + desktopApiUrl: "/api/zm", + latestRelease: "https://api.github.com/repos/pliablepixels/zmNinja/releases/latest", + blogUrl: "https://medium.com/zmninja/latest?format=json", + nphSwitchTimer: 3000, + eventHistoryTimer: 5000, + eventPlaybackQuery: 3000, + + packeryTimer: 500, + dbName: 'zmninja', + cipherKey: 'sdf#@#%FSXSA_AR', + minCycleTime: 5, + + eventPlaybackQueryLowBW: 6000, + loginIntervalLowBW: 600000, //10m login + eventSingleImageQualityLowBW: 70, + monSingleImageQualityLowBW: 70, + montageQualityLowBW: 50, + eventMontageQualityLowBW: 50, + maxGifCount: 60, + maxGifCount2: 100, + maxGifWidth: 800.0, + quantSample: 15, -}) + }) -// filter for montage iteration -.filter('onlyEnabled', function() -{ + //http://stackoverflow.com/a/24519069/1361529 + .filter('trusted', ['$sce', function ($sce) { + return function (url) { + return $sce.trustAsResourceUrl(url); + }; + }]) - // Create the return function and set the required parameter name to **input** - return function(input) - { - var out = []; + // for events view + .filter('eventListFilter', function (NVRDataModel) { + return function (input) { + var ld = NVRDataModel.getLogin(); + var out = []; + angular.forEach(input, function (item) { + if (item.Event.Archived == '0' || !ld.hideArchived) { + out.push(item); + } + }); + return out; + }; - angular.forEach(input, function(item) - { + }) - if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0')) - { - out.push(item); - } + // filter for montage iteration + .filter('onlyEnabled', function () { - }); + // Create the return function and set the required parameter name to **input** + return function (input) { - return out; - }; + var out = []; -}) + angular.forEach(input, function (item) { -// filter for EH iteration -.filter('onlyEnabledAndEventHas', function() -{ + if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0')) { + out.push(item); + } - // Create the return function and set the required parameter name to **input** - return function(input) - { + }); + + return out; + }; - var out = []; + }) - angular.forEach(input, function(item) - { + // filter for EH iteration + .filter('onlyEnabledAndEventHas', function () { - if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0') && (item.Monitor.eventUrl != 'img/noevent.png') && (item.Monitor.listDisplay != 'noshow')) - { - out.push(item); - } + // Create the return function and set the required parameter name to **input** + return function (input) { - }); + var out = []; - return out; - }; - -}) - - -//credit: http://stackoverflow.com/a/23931217/1361529 -.directive('hidepassword', function () { - - var modelSet = function (str) - { - - return str; - }; - - var viewSet = function (str) - { - //https://github.com/garycourt/uri-js - if (!str) return str; - var c = URI.parse(str); - //if (c.userinfo) c.userinfo="***:***"; - if (c.userinfo) c.userinfo="\u2022\u2022\u2022:\u2022\u2022\u2022"; - - var ostr = ""; - if (c.scheme) ostr = ostr+c.scheme+"://"; - if (c.userinfo) ostr = ostr+c.userinfo+"@"; - if (c.host) ostr = ostr+c.host; - if (c.port) ostr = ostr+":"+c.port; - if (c.path) ostr = ostr+c.path; - if (c.query) ostr = ostr+c.query; - if (c.fragment) ostr = ostr+c.fragment; - - - /*var vc = URI.serialize({scheme : c.scheme, - userinfo: c.userinfo, - host: c.host, - port: c.port, - path: c.path, - query: c.query, - fragment: c.fragment - },{unicodeSupport:true});*/ - // console.log ("CONVERTED IS "+vc); - - - return ostr; - }; - - return { - - restrict: 'A', - require: 'ngModel', - link: function (scope, element, attr, ngModel) { - ngModel.$parsers.push(modelSet); - ngModel.$formatters.push(viewSet); - - element.bind('blur', function() { - element.val(viewSet(ngModel.$modelValue)); - }); - element.bind('focus', function () { - element.val(ngModel.$modelValue); - }); - - } - }; -}) - - - -// credit https://gist.github.com/Zren/beaafd64f395e23f4604 - -.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.'); - } - 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 -// (keeps reading data). Hence not using it now -//credit: http://stackoverflow.com/questions/34958575/intercepting-img-src-via-http-interceptor-as-well-as-not-lose-the-ability-to-kee -.directive('httpSrc', [ - '$http', 'imageLoadingDataShare', 'NVRDataModel', - function($http, imageLoadingDataShare, NVRDataModel) - { - var directive = { - link: postLink, - restrict: 'A' - }; - return directive; - - function postLink(scope, element, attrs) - { - //console.log ("HELLO NEW"); - var requestConfig = { - method: 'GET', - //url: attrs.httpSrc, - responseType: 'arraybuffer', - cache: 'true' - }; + angular.forEach(input, function (item) { - function base64Img(data) - { - var arr = new Uint8Array(data); - var raw = ''; - var i, j, subArray, chunk = 5000; - for (i = 0, j = arr.length; i < j; i += chunk) - { - subArray = arr.subarray(i, i + chunk); - raw += String.fromCharCode.apply(null, subArray); + if ((item.Monitor.Function != 'None') && (item.Monitor.Enabled != '0') && (item.Monitor.eventUrl != 'img/noevent.png') && (item.Monitor.listDisplay != 'noshow')) { + out.push(item); } - return btoa(raw); - } - attrs.$observe('httpSrc', function(newValue) - { - requestConfig.url = newValue; - //console.log ("requestConfig is " + JSON.stringify(requestConfig)); - imageLoadingDataShare.set(1); - $http(requestConfig) - .success(function(data) - { - //console.log ("Inside HTTP after Calling " + requestConfig.url); - //console.log ("data got " + JSON.stringify(data)); - - var b64 = base64Img(data); - attrs.$set('src', "data:image/jpeg;base64," + b64); - imageLoadingDataShare.set(0); - }); + }); - } - } -]) - -//------------------------------------------------------------------ -// switch between collection repeat or ng-repeat -//------------------------------------------------------------------- -.directive('repeatsmart', function($compile, $rootScope) -{ - return { - restrict: 'A', - priority: 2000, - terminal: true, - link: function(scope, element) - { - var repeatDirective = ($rootScope.platformOS == 'desktop') ? 'ng-repeat' : 'collection-repeat'; - //console.log("*********** REPEAT SCROLL IS " + repeatDirective); - - element.attr(repeatDirective, element.attr('repeatsmart')); - element.removeAttr('repeatsmart'); - $compile(element)(scope); - } - }; -}) - -//------------------------------------------------------------------ -// I use this factory to share data between carousel and lazy load -// carousel will not progress autoslide till imageLoading is 0 or -1 -//------------------------------------------------------------------- -.factory('imageLoadingDataShare', function() -{ - var imageLoading = 0; // 0 = not loading, 1 = loading, -1 = error; - return { - 'set': function(val) - { - imageLoading = val; - //console.log ("** IMAGE LOADING **"+val); - }, - 'get': function() - { - - return imageLoading; - } - }; -}) + return out; + }; + + }) + -/*.factory('qHttp', function($q, $http) { - //credit: http://stackoverflow.com/a/29719693 - var queue = $q.when(); + //credit: http://stackoverflow.com/a/23931217/1361529 + .directive('hidepassword', function () { - return function queuedHttp(httpConf) { - var f = function(data) { - return $http(httpConf); + var modelSet = function (str) { + + return str; }; - return queue = queue.then(f, f); - }; -})*/ - -//credit: http://stackoverflow.com/a/14468276 -.factory('qHttp', function($q, $http) -{ - - var queue = []; - var execNext = function() - { - var task = queue[0]; - //console.log ("qHTTP>>> Executing:"+JSON.stringify(task.c)+">>> pending:"+queue.length); - - $http(task.c).then(function(data) - { - queue.shift(); - task.d.resolve(data); - if (queue.length > 0) execNext(); - }, function(err) - { - queue.shift(); - task.d.reject(err); - if (queue.length > 0) execNext(); - }); - }; - return function(config) - { - var d = $q.defer(); - //config.headers.push({'X-qHttp':'enabled'}); - queue.push( - { - c: config, - d: d - }); - if (queue.length === 1) - { - execNext(); - } - //else - //console.log ("qHTTP>>> Queuing:"+JSON.stringify(config)); - return d.promise; - }; -}) -//credit: https://github.com/driftyco/ionic/issues/3131 -.factory('SecuredPopups', [ - '$ionicPopup', - '$q', - function($ionicPopup, $q) - { + var viewSet = function (str) { + //https://github.com/garycourt/uri-js + if (!str) return str; + var c = URI.parse(str); + //if (c.userinfo) c.userinfo="***:***"; + if (c.userinfo) c.userinfo = "\u2022\u2022\u2022:\u2022\u2022\u2022"; + + var ostr = ""; + if (c.scheme) ostr = ostr + c.scheme + "://"; + if (c.userinfo) ostr = ostr + c.userinfo + "@"; + if (c.host) ostr = ostr + c.host; + if (c.port) ostr = ostr + ":" + c.port; + if (c.path) ostr = ostr + c.path; + if (c.query) ostr = ostr + c.query; + if (c.fragment) ostr = ostr + c.fragment; + + return ostr; + }; + + return { + + restrict: 'A', + require: 'ngModel', + link: function (scope, element, attr, ngModel) { + ngModel.$parsers.push(modelSet); + ngModel.$formatters.push(viewSet); + + element.bind('blur', function () { + element.val(viewSet(ngModel.$modelValue)); + }); + element.bind('focus', function () { + element.val(ngModel.$modelValue); + }); + + } + }; + }) - var firstDeferred = $q.defer(); - firstDeferred.resolve(); - var lastPopupPromise = firstDeferred.promise; - // Change this var to true if you want that popups will automaticly close before opening another - var closeAndOpen = false; + // credit https://gist.github.com/Zren/beaafd64f395e23f4604 + .directive('mouseWheelScroll', function ($timeout) { return { - 'show': function(method, object) - { - var deferred = $q.defer(); - var closeMethod = null; - deferred.promise.isOpen = false; - deferred.promise.close = function() - { - if (deferred.promise.isOpen && angular.isFunction(closeMethod)) - { - closeMethod(); - } + 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); + } + }; + }) - if (closeAndOpen && lastPopupPromise.isOpen) - { - lastPopupPromise.close(); + // 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 + // (keeps reading data). Hence not using it now + //credit: http://stackoverflow.com/questions/34958575/intercepting-img-src-via-http-interceptor-as-well-as-not-lose-the-ability-to-kee + .directive('httpSrc', [ + '$http', 'imageLoadingDataShare', 'NVRDataModel', + function ($http, imageLoadingDataShare, NVRDataModel) { + var directive = { + link: postLink, + restrict: 'A' + }; + return directive; + + function postLink(scope, element, attrs) { + //console.log ("HELLO NEW"); + var requestConfig = { + method: 'GET', + //url: attrs.httpSrc, + responseType: 'arraybuffer', + cache: 'true' + }; + + function base64Img(data) { + var arr = new Uint8Array(data); + var raw = ''; + var i, j, subArray, chunk = 5000; + for (i = 0, j = arr.length; i < j; i += chunk) { + subArray = arr.subarray(i, i + chunk); + raw += String.fromCharCode.apply(null, subArray); + } + return btoa(raw); } + attrs.$observe('httpSrc', function (newValue) { + requestConfig.url = newValue; + //console.log ("requestConfig is " + JSON.stringify(requestConfig)); + imageLoadingDataShare.set(1); + $http(requestConfig) + .success(function (data) { + //console.log ("Inside HTTP after Calling " + requestConfig.url); + //console.log ("data got " + JSON.stringify(data)); - lastPopupPromise.then(function() - { - deferred.promise.isOpen = true; - var popupInstance = $ionicPopup[method](object); - - closeMethod = popupInstance.close; - popupInstance.then(function(res) - { - deferred.promise.isOpen = false; - deferred.resolve(res); - }); + var b64 = base64Img(data); + attrs.$set('src', "data:image/jpeg;base64," + b64); + imageLoadingDataShare.set(0); + }); }); - lastPopupPromise = deferred.promise; + } + } + ]) - return deferred.promise; + //------------------------------------------------------------------ + // switch between collection repeat or ng-repeat + //------------------------------------------------------------------- + .directive('repeatsmart', function ($compile, $rootScope) { + return { + restrict: 'A', + priority: 2000, + terminal: true, + link: function (scope, element) { + var repeatDirective = ($rootScope.platformOS == 'desktop') ? 'ng-repeat' : 'collection-repeat'; + //console.log("*********** REPEAT SCROLL IS " + repeatDirective); + + element.attr(repeatDirective, element.attr('repeatsmart')); + element.removeAttr('repeatsmart'); + $compile(element)(scope); } }; - } -]) - -//------------------------------------------------------------------ -// this directive will be called any time an image completes loading -// via img tags where this directive is added (I am using this in -// events and monitor view to show a loader while the image is -// downloading from ZM -//------------------------------------------------------------------ - -.directive('imageonload', function() -{ - return { - restrict: 'A', - link: function(scope, element, attrs) - { - element.bind('load', function() - { - //call the function that was passed - scope.$apply(attrs.imageonload); + }) + + //------------------------------------------------------------------ + // I use this factory to share data between carousel and lazy load + // carousel will not progress autoslide till imageLoading is 0 or -1 + //------------------------------------------------------------------- + .factory('imageLoadingDataShare', function () { + var imageLoading = 0; // 0 = not loading, 1 = loading, -1 = error; + return { + 'set': function (val) { + imageLoading = val; + //console.log ("** IMAGE LOADING **"+val); + }, + 'get': function () { + + return imageLoading; + } + }; + }) + + /*.factory('qHttp', function($q, $http) { + //credit: http://stackoverflow.com/a/29719693 + var queue = $q.when(); + + return function queuedHttp(httpConf) { + var f = function(data) { + return $http(httpConf); + }; + return queue = queue.then(f, f); + }; + })*/ + + //credit: http://stackoverflow.com/a/14468276 + .factory('qHttp', function ($q, $http) { + + var queue = []; + var execNext = function () { + var task = queue[0]; + //console.log ("qHTTP>>> Executing:"+JSON.stringify(task.c)+">>> pending:"+queue.length); + + $http(task.c).then(function (data) { + queue.shift(); + task.d.resolve(data); + if (queue.length > 0) execNext(); + }, function (err) { + queue.shift(); + task.d.reject(err); + if (queue.length > 0) execNext(); + }); + }; + return function (config) { + var d = $q.defer(); + //config.headers.push({'X-qHttp':'enabled'}); + queue.push({ + c: config, + d: d }); + if (queue.length === 1) { + execNext(); + } + //else + //console.log ("qHTTP>>> Queuing:"+JSON.stringify(config)); + return d.promise; + }; + }) + + //credit: https://github.com/driftyco/ionic/issues/3131 + .factory('SecuredPopups', [ + '$ionicPopup', + '$q', + function ($ionicPopup, $q) { + + var firstDeferred = $q.defer(); + firstDeferred.resolve(); + + var lastPopupPromise = firstDeferred.promise; + + // Change this var to true if you want that popups will automaticly close before opening another + var closeAndOpen = false; + + return { + 'show': function (method, object) { + var deferred = $q.defer(); + var closeMethod = null; + deferred.promise.isOpen = false; + deferred.promise.close = function () { + if (deferred.promise.isOpen && angular.isFunction(closeMethod)) { + closeMethod(); + } + }; + + if (closeAndOpen && lastPopupPromise.isOpen) { + lastPopupPromise.close(); + } + + lastPopupPromise.then(function () { + deferred.promise.isOpen = true; + var popupInstance = $ionicPopup[method](object); + + closeMethod = popupInstance.close; + popupInstance.then(function (res) { + deferred.promise.isOpen = false; + deferred.resolve(res); + }); + }); + + lastPopupPromise = deferred.promise; + + return deferred.promise; + } + }; } + ]) - }; -}) + //------------------------------------------------------------------ + // this directive will be called any time an image completes loading + // via img tags where this directive is added (I am using this in + // events and monitor view to show a loader while the image is + // downloading from ZM + //------------------------------------------------------------------ -//-------------------------------------------------------------------------------------------- -// This directive is adapted from https://github.com/paveisistemas/ionic-image-lazy-load -// I've removed lazyLoad and only made it show a spinner when an image is loading -//-------------------------------------------------------------------------------------------- -.directive('imageSpinnerSrc', ['$document', '$compile', 'imageLoadingDataShare', '$timeout', - function($document, $compile, imageLoadingDataShare, $timeout) - { + .directive('imageonload', function () { return { restrict: 'A', - scope: - { - imageSpinnerBackgroundImage: "@imageSpinnerBackgroundImage" - }, - link: function($scope, $element, $attributes) - { + link: function (scope, element, attrs) { + element.bind('load', function () { + //call the function that was passed + scope.$apply(attrs.imageonload); + }); + } - /*if ($attributes.imageSpinnerLoader) { - var loader = $compile('<div class="image-loader-container"><ion-spinner class="image-loader" icon="' + $attributes.imageSpinnerLoader + '"></ion-spinner></div>')($scope); - $element.after(loader); - }*/ + }; + }) - if ($attributes.imageSpinnerLoader) - { - var loader = $compile('<div class="image-loader-container"><ion-spinner class="image-loader" icon="' + 'bubbles' + '"></ion-spinner></div>')($scope); - $element.after(loader); - } - imageLoadingDataShare.set(1); - loadImage(); + //-------------------------------------------------------------------------------------------- + // This directive is adapted from https://github.com/paveisistemas/ionic-image-lazy-load + // I've removed lazyLoad and only made it show a spinner when an image is loading + //-------------------------------------------------------------------------------------------- + .directive('imageSpinnerSrc', ['$document', '$compile', 'imageLoadingDataShare', '$timeout', + function ($document, $compile, imageLoadingDataShare, $timeout) { + return { + restrict: 'A', + scope: { + imageSpinnerBackgroundImage: "@imageSpinnerBackgroundImage" + }, + link: function ($scope, $element, $attributes) { - $attributes.$observe('imageSpinnerSrc', function(value) - { - //console.log ("DIRECTIVE SOURCE CHANGED"); + /*if ($attributes.imageSpinnerLoader) { + var loader = $compile('<div class="image-loader-container"><ion-spinner class="image-loader" icon="' + $attributes.imageSpinnerLoader + '"></ion-spinner></div>')($scope); + $element.after(loader); + }*/ + + if ($attributes.imageSpinnerLoader) { + var loader = $compile('<div class="image-loader-container"><ion-spinner class="image-loader" icon="' + 'bubbles' + '"></ion-spinner></div>')($scope); + $element.after(loader); + } imageLoadingDataShare.set(1); loadImage(); - //deregistration(); - }); - - // show an image-missing image - $element.bind('error', function() - { - // console.log ("DIRECTIVE: IMAGE ERROR"); - loader.remove(); + $attributes.$observe('imageSpinnerSrc', function (value) { + //console.log ("DIRECTIVE SOURCE CHANGED"); + imageLoadingDataShare.set(1); + loadImage(); + //deregistration(); - var url = 'img/novideo.png'; - $element.prop('src', url); - imageLoadingDataShare.set(0); - }); + }); - function waitForFrame1() - { - ionic.DomUtil.requestAnimationFrame( - function() - { - imageLoadingDataShare.set(0); - //console.log ("IMAGE LOADED"); - }); + // show an image-missing image + $element.bind('error', function () { + // console.log ("DIRECTIVE: IMAGE ERROR"); + loader.remove(); - } + var url = 'img/novideo.png'; + $element.prop('src', url); + imageLoadingDataShare.set(0); + }); - function loadImage() - { - $element.bind("load", function(e) - { - if ($attributes.imageSpinnerLoader) - { - //console.log ("DIRECTIVE: IMAGE LOADED"); - loader.remove(); - //imageLoadingDataShare.set(0); - //console.log ("rendered"); - - // lets wait for 2 frames for animation - // to render - hoping this will improve tear - // of images - ionic.DomUtil.requestAnimationFrame( - function() - { - waitForFrame1(); - }); + function waitForFrame1() { + ionic.DomUtil.requestAnimationFrame( + function () { + imageLoadingDataShare.set(0); + //console.log ("IMAGE LOADED"); + }); - } - }); + } - if ($scope.imageSpinnerBackgroundImage == "true") - { - var bgImg = new Image(); - bgImg.onload = function() - { - if ($attributes.imageSpinnerLoader) - { + function loadImage() { + $element.bind("load", function (e) { + if ($attributes.imageSpinnerLoader) { + //console.log ("DIRECTIVE: IMAGE LOADED"); loader.remove(); + //imageLoadingDataShare.set(0); + //console.log ("rendered"); + + // lets wait for 2 frames for animation + // to render - hoping this will improve tear + // of images + ionic.DomUtil.requestAnimationFrame( + function () { + waitForFrame1(); + }); + } - // set style attribute on element (it will load image) - if (imageLoadingDataShare.get() != 1) + }); + + if ($scope.imageSpinnerBackgroundImage == "true") { + var bgImg = new Image(); + bgImg.onload = function () { + if ($attributes.imageSpinnerLoader) { + loader.remove(); + } + // set style attribute on element (it will load image) + if (imageLoadingDataShare.get() != 1) + + $element[0].style.backgroundImage = 'url(' + $attributes.imageSpinnerSrc + ')'; - $element[0].style.backgroundImage = 'url(' + $attributes.imageSpinnerSrc + ')'; + //$element[0].style.backgroundImage = 'url(' + 'img/novideo.png'+ ')'; - //$element[0].style.backgroundImage = 'url(' + 'img/novideo.png'+ ')'; + }; - }; + bgImg.src = $attributes.imageSpinnerSrc; - bgImg.src = $attributes.imageSpinnerSrc; + } else { + $element[0].src = $attributes.imageSpinnerSrc; // set src attribute on element (it will load image) + } } - else - { - $element[0].src = $attributes.imageSpinnerSrc; // set src attribute on element (it will load image) + function isInView() { + return true; } - } - function isInView() - { - return true; + $element.on('$destroy', function () { + + }); + } + }; + } + ]) - $element.on('$destroy', function() { + //------------------------------------------------------------------ + // In Android, HTTP requests seem to get stuck once in a while + // It may be a crosswalk issue. + // To tackle this gracefully, I've set up a global interceptor + // If the HTTP request does not complete in 15 seconds, it cancels + // That way the user can try again, and won't get stuck + // Also remember you need to add it to .config + //------------------------------------------------------------------ + .factory('timeoutHttpIntercept', ['$rootScope', '$q', 'zm', '$injector', function ($rootScope, $q, zm, $injector) { + $rootScope.zmCookie = ""; + //console.log ("HHHHHHHHHHHHHH**************************"); - }); + return { - } - }; - } -]) - -//------------------------------------------------------------------ -// In Android, HTTP requests seem to get stuck once in a while -// It may be a crosswalk issue. -// To tackle this gracefully, I've set up a global interceptor -// If the HTTP request does not complete in 15 seconds, it cancels -// That way the user can try again, and won't get stuck -// Also remember you need to add it to .config -//------------------------------------------------------------------ -.factory('timeoutHttpIntercept', ['$rootScope', '$q', 'zm', '$injector', function($rootScope, $q, zm, $injector) -{ - $rootScope.zmCookie = ""; - //console.log ("HHHHHHHHHHHHHH**************************"); - - return { - - 'request': function(config) - { - if (!config) return config; - if (!config.url) return config; - - // NOTE ON TIMEOUTS: As of Oct 10 2016, it seems - // the Http queue often gets messed up when there is a timeout - // and the # of requests are plentiful. I'm going to disable it and see - - // console.log (">>>>"+config.url); - // handle basic auth properly - if (config.url.indexOf("@") > -1) - { - //console.log ("HTTP basic auth INTERCEPTOR URL IS " + config.url); - var components = URI.parse(config.url); - // console.log ("Parsed data is " + JSON.stringify(components)); - var credentials = btoa(components.userinfo); - //var authorization = {'Authorization': 'Basic ' + credentials}; - //config.headers.Authorization = 'Basic ' + credentials; + 'request': function (config) { + if (!config) return config; + if (!config.url) return config; - // console.log ("Full headers: " + JSON.stringify(config.headers)); + // NOTE ON TIMEOUTS: As of Oct 10 2016, it seems + // the Http queue often gets messed up when there is a timeout + // and the # of requests are plentiful. I'm going to disable it and see - } + // console.log (">>>>"+config.url); + // handle basic auth properly + if (config.url.indexOf("@") > -1) { + //console.log ("HTTP basic auth INTERCEPTOR URL IS " + config.url); + var components = URI.parse(config.url); + // console.log ("Parsed data is " + JSON.stringify(components)); + var credentials = btoa(components.userinfo); + //var authorization = {'Authorization': 'Basic ' + credentials}; + //config.headers.Authorization = 'Basic ' + credentials; - //console.log (">>>>>>>>>>>>> INTERCEPT OBJECT " + JSON.stringify(config)); + // console.log ("Full headers: " + JSON.stringify(config.headers)); - if ($rootScope.zmCookie) - { - config.headers.Cookie = "ZMSESSID=" + $rootScope.zmCookie; - } - else - { - // console.log ("No cookie present in " + config.url); - } + } - if ((config.url.indexOf("/api/states/change/") > -1) || - (config.url.indexOf("getDiskPercent.json") > -1) || - (config.url.indexOf("daemonCheck.json") > -1) || - (config.url.indexOf("getLoad.json") > -1)) + //console.log (">>>>>>>>>>>>> INTERCEPT OBJECT " + JSON.stringify(config)); - { + if ($rootScope.zmCookie) { + config.headers.Cookie = "ZMSESSID=" + $rootScope.zmCookie; + } else { + // console.log ("No cookie present in " + config.url); + } - // these can take time, so lets bump up timeout - config.timeout = zm.largeHttpTimeout; + if ((config.url.indexOf("/api/states/change/") > -1) || + (config.url.indexOf("getDiskPercent.json") > -1) || + (config.url.indexOf("daemonCheck.json") > -1) || + (config.url.indexOf("getLoad.json") > -1)) - } - else if ((config.url.indexOf("view=view_video") > -1) || - config.url.indexOf(".mp4") > -1) - { - // console.log(">>> skipping timers for MP4"); - // put a timeout for zms urls - } - else if (config.url.indexOf("zms?") > -1) - { - // config.timeout = zm.httpTimeout; + { - } - return config; - }, + // these can take time, so lets bump up timeout + config.timeout = zm.largeHttpTimeout; - 'response': function(response) - { - var cookies = response.headers("Set-Cookie"); - if (cookies != null) - { + } else if ((config.url.indexOf("view=view_video") > -1) || + config.url.indexOf(".mp4") > -1) { + // console.log(">>> skipping timers for MP4"); + // put a timeout for zms urls + } else if (config.url.indexOf("zms?") > -1) { + // config.timeout = zm.httpTimeout; - var zmSess = cookies.match("ZMSESSID=(.*?);"); + } + return config; + }, - if (zmSess) - { - if (zmSess[1]) - { + 'response': function (response) { + var cookies = response.headers("Set-Cookie"); + if (cookies != null) { + + var zmSess = cookies.match("ZMSESSID=(.*?);"); + + if (zmSess) { + if (zmSess[1]) { - // console.log ("***** SETTING COOKIE TO " + zmCookie); - $rootScope.zmCookie = zmSess[1]; + // console.log ("***** SETTING COOKIE TO " + zmCookie); + $rootScope.zmCookie = zmSess[1]; + } } } + + //console.log ("HTTP response"); + return response; } - //console.log ("HTTP response"); - return response; - } + }; + }]) + + //----------------------------------------------------------------- + // This service automatically checks for new versions every 24 hrs + //------------------------------------------------------------------ + .factory('zmCheckUpdates', function ($interval, $http, zm, $timeout, $localstorage, NVRDataModel, $rootScope, $translate) { + var zmUpdateHandle; + var zmUpdateVersion = ""; - }; -}]) - -//----------------------------------------------------------------- -// This service automatically checks for new versions every 24 hrs -//------------------------------------------------------------------ -.factory('zmCheckUpdates', function($interval, $http, zm, $timeout, $localstorage, NVRDataModel, $rootScope, $translate) -{ - var zmUpdateHandle; - var zmUpdateVersion = ""; - - function start() - { - checkUpdate(); - $interval.cancel(zmUpdateHandle); - zmUpdateHandle = $interval(function() - { + function start() { checkUpdate(); + $interval.cancel(zmUpdateHandle); + zmUpdateHandle = $interval(function () { + checkUpdate(); - }, zm.updateCheckInterval); + }, zm.updateCheckInterval); - function checkUpdate() - { - var lastdateString = NVRDataModel.getLastUpdateCheck(); - var lastdate; - if (!lastdateString) - { + function checkUpdate() { + var lastdateString = NVRDataModel.getLastUpdateCheck(); + var lastdate; + if (!lastdateString) { - lastdate = moment().subtract(2, 'day'); + lastdate = moment().subtract(2, 'day'); - } - else - { - lastdate = moment(lastdateString); - } - var timdiff = moment().diff(lastdate, 'hours'); - if (timdiff < 24) - { - NVRDataModel.log("Checked for update " + timdiff + " hours ago. Not checking again"); + } else { + lastdate = moment(lastdateString); + } + var timdiff = moment().diff(lastdate, 'hours'); + if (timdiff < 24) { + NVRDataModel.log("Checked for update " + timdiff + " hours ago. Not checking again"); - return; - } - NVRDataModel.log("Checking for new version updates..."); + return; + } + NVRDataModel.log("Checking for new version updates..."); + + $http.get(zm.latestRelease) + .then(function (success) { + + NVRDataModel.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]; + var currentVersion = NVRDataModel.getAppVersion(); + if ($rootScope.platformOS == "desktop") { + zmUpdateVersion = zmUpdateVersion + "D"; + } + //if (NVRDataModel.getAppVersion() != zmUpdateVersion) { + if (NVRDataModel.versionCompare(NVRDataModel.getAppVersion(), zmUpdateVersion) == -1) { + $rootScope.newVersionAvailable = "v" + zmUpdateVersion + " available"; + } else { + $rootScope.newVersionAvailable = ""; + } + NVRDataModel.debug("current version: " + currentVersion + " & available version " + zmUpdateVersion); + //console.log ("Version compare returned: " + NVRDataModel.versionCompare(currentVersion, //zmUpdateVersion)); + // console.log ("Version compare returned: " + NVRDataModel.versionCompare(zmUpdateVersion, currentVersion)); + //console.log ("UPDATE " + zmVersion); + }); - $http.get(zm.latestRelease) - .then(function(success) - { + NVRDataModel.log("Checking for news updates"); + $http.get(zm.blogUrl, { + transformResponse: function (d, h) { + var trunc = "])}while(1);</x>"; + d = d.substr(trunc.length); + return d; + } + }) - NVRDataModel.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]; - var currentVersion = NVRDataModel.getAppVersion(); - if ($rootScope.platformOS == "desktop") - { - zmUpdateVersion = zmUpdateVersion + "D"; - } - //if (NVRDataModel.getAppVersion() != zmUpdateVersion) { - if (NVRDataModel.versionCompare(NVRDataModel.getAppVersion(), zmUpdateVersion) == -1) - { - $rootScope.newVersionAvailable = "v" + zmUpdateVersion + " available"; - } - else - { - $rootScope.newVersionAvailable = ""; - } - NVRDataModel.debug("current version: " + currentVersion + " & available version " + zmUpdateVersion); - //console.log ("Version compare returned: " + NVRDataModel.versionCompare(currentVersion, //zmUpdateVersion)); - // console.log ("Version compare returned: " + NVRDataModel.versionCompare(zmUpdateVersion, currentVersion)); - //console.log ("UPDATE " + zmVersion); - }); + .success(function (datastr) { - NVRDataModel.log("Checking for news updates"); - $http.get(zm.blogUrl, - {transformResponse: function(d,h) - { - var trunc = "])}while(1);</x>"; - d = d.substr(trunc.length); - return d; - } - }) - - .success(function(datastr) - { - - var data = JSON.parse(datastr); - $rootScope.newBlogPost = ""; - if (data.payload.posts.length <= 0) - { + var data = JSON.parse(datastr); $rootScope.newBlogPost = ""; - return; - } + if (data.payload.posts.length <= 0) { + $rootScope.newBlogPost = ""; + return; + } - var lastDate = NVRDataModel.getLatestBlogPostChecked(); - //console.log ("************ BLOG LAST DATE " + lastDate); - if (!lastDate) - { + var lastDate = NVRDataModel.getLatestBlogPostChecked(); + //console.log ("************ BLOG LAST DATE " + lastDate); + if (!lastDate) { - $rootScope.newBlogPost = "("+$translate.instant('kNewPost')+")"; - NVRDataModel.setLatestBlogPostChecked(moment().format("YYYY-MM-DD HH:mm:ss")); - return; + $rootScope.newBlogPost = "(" + $translate.instant('kNewPost') + ")"; + NVRDataModel.setLatestBlogPostChecked(moment().format("YYYY-MM-DD HH:mm:ss")); + return; - } - var mLastDate = moment(lastDate); - var mItemDate = moment(data.payload.posts[0].createdAt); - - if (mItemDate.diff(mLastDate, 'seconds') > 0) - { - /*console.log ("DIFF IS "+mItemDate.diff(mLastDate, 'seconds')); - console.log ("DIFF mLastDate="+mLastDate); - console.log ("DIFF mItemDate="+mItemDate); - console.log ("FORMAT DIFF mLastDate="+mLastDate.format("YYYY-MM-DD HH:mm:ss") ); - console.log ("FORMAT DIFF mItemDate="+mItemDate.format("YYYY-MM-DD HH:mm:ss") );*/ - - NVRDataModel.debug("New post dated " + mItemDate.format("YYYY-MM-DD HH:mm:ss") + " found, last date checked was "+mLastDate.format("YYYY-MM-DD HH:mm:ss")); - - $rootScope.newBlogPost = "("+$translate.instant('kNewPost')+")"; - NVRDataModel.setLatestBlogPostChecked(mItemDate.format("YYYY-MM-DD HH:mm:ss")); - - - - } - else - { - NVRDataModel.debug("Latest post dated " + mItemDate.format("YYYY-MM-DD HH:mm:ss") + " but you read " + lastDate); - } + } + var mLastDate = moment(lastDate); + var mItemDate = moment(data.payload.posts[0].createdAt); - }); + if (mItemDate.diff(mLastDate, 'seconds') > 0) { + /*console.log ("DIFF IS "+mItemDate.diff(mLastDate, 'seconds')); + console.log ("DIFF mLastDate="+mLastDate); + console.log ("DIFF mItemDate="+mItemDate); + console.log ("FORMAT DIFF mLastDate="+mLastDate.format("YYYY-MM-DD HH:mm:ss") ); + console.log ("FORMAT DIFF mItemDate="+mItemDate.format("YYYY-MM-DD HH:mm:ss") );*/ - } - } + NVRDataModel.debug("New post dated " + mItemDate.format("YYYY-MM-DD HH:mm:ss") + " found, last date checked was " + mLastDate.format("YYYY-MM-DD HH:mm:ss")); - function getLatestUpdateVersion() - { - return (zmUpdateVersion == "") ? "(unknown)" : zmUpdateVersion; - } + $rootScope.newBlogPost = "(" + $translate.instant('kNewPost') + ")"; + NVRDataModel.setLatestBlogPostChecked(mItemDate.format("YYYY-MM-DD HH:mm:ss")); - return { - start: start, - getLatestUpdateVersion: getLatestUpdateVersion - //stop: stop, - }; -}) + } else { + NVRDataModel.debug("Latest post dated " + mItemDate.format("YYYY-MM-DD HH:mm:ss") + " but you read " + lastDate); + } -//----------------------------------------------------------------- -// This service automatically logs into ZM at periodic intervals -//------------------------------------------------------------------ + }); -.factory('zmAutoLogin', function($interval, NVRDataModel, $http, zm, $browser, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate) -{ - var zmAutoLoginHandle; + } + } - //------------------------------------------------------------------ - // doLogin() emits this when there is an auth error in the portal - //------------------------------------------------------------------ + function getLatestUpdateVersion() { + return (zmUpdateVersion == "") ? "(unknown)" : zmUpdateVersion; + } - $rootScope.$on("auth-error", function() - { + return { + start: start, + getLatestUpdateVersion: getLatestUpdateVersion + //stop: stop, - NVRDataModel.debug("zmAutoLogin: Inside auth-error emit"); - NVRDataModel.displayBanner('error', ['ZoneMinder authentication failed', 'Please check settings']); + }; - }); + }) - //------------------------------------------------------------------ - // broadcasted after : - // a) device is ready - // b) language loaded - // c) localforage data loaded + //----------------------------------------------------------------- + // This service automatically logs into ZM at periodic intervals //------------------------------------------------------------------ - $rootScope.$on("init-complete", function() - { - NVRDataModel.log(">>>>>>>>>>>>>>> All init over, going to portal login"); - $ionicHistory.nextViewOptions( - { - disableAnimate: true - }); - $state.go("zm-portal-login"); - return; - }); + .factory('zmAutoLogin', function ($interval, NVRDataModel, $http, zm, $browser, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate) { + var zmAutoLoginHandle; - //------------------------------------------------------------------ - // doLogin() emits this when our auth credentials work - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // doLogin() emits this when there is an auth error in the portal + //------------------------------------------------------------------ + + $rootScope.$on("auth-error", function () { + + NVRDataModel.debug("zmAutoLogin: Inside auth-error emit"); + NVRDataModel.displayBanner('error', ['ZoneMinder authentication failed', 'Please check settings']); - $rootScope.$on("auth-success", function() - { - var contentBannerInstance = $ionicContentBanner.show( - { - text: ['ZoneMinder' + $translate.instant('kAuthSuccess')], - interval: 2000, - type: 'info', - transition: 'vertical' }); - $timeout(function() - { - contentBannerInstance(); - }, 2000); - NVRDataModel.debug("auth-success emit:Successful"); - }); + //------------------------------------------------------------------ + // broadcasted after : + // a) device is ready + // b) language loaded + // c) localforage data loaded + //------------------------------------------------------------------ + + $rootScope.$on("init-complete", function () { + NVRDataModel.log(">>>>>>>>>>>>>>> All init over, going to portal login"); + $ionicHistory.nextViewOptions({ + disableAnimate: true + }); + $state.go("zm-portal-login"); + return; + }); - $rootScope.getProfileName = function() - { - var ld = NVRDataModel.getLogin(); - return (ld.serverName || '(none)'); - }; + //------------------------------------------------------------------ + // doLogin() emits this when our auth credentials work + //------------------------------------------------------------------ - $rootScope.getLocalTimeZone = function() - { - return moment.tz.guess(); - }; + $rootScope.$on("auth-success", function () { + var contentBannerInstance = $ionicContentBanner.show({ + text: ['ZoneMinder' + $translate.instant('kAuthSuccess')], + interval: 2000, + type: 'info', + transition: 'vertical' + }); - $rootScope.getServerTimeZoneNow = function() - { + $timeout(function () { + contentBannerInstance(); + }, 2000); + NVRDataModel.debug("auth-success emit:Successful"); + }); - return NVRDataModel.getTimeZoneNow(); + $rootScope.getProfileName = function () { + var ld = NVRDataModel.getLogin(); + return (ld.serverName || '(none)'); + }; - }; + $rootScope.getLocalTimeZone = function () { + return moment.tz.guess(); + }; - $rootScope.isTzSupported = function() - { - return NVRDataModel.isTzSupported(); - }; + $rootScope.getServerTimeZoneNow = function () { - //------------------------------------------------------------------ - // doLogin() is the function that tries to login to ZM - // it also makes sure we are not back to the same page - // which actually means auth failed, but ZM treats it as a success - //------------------------------------------------------------------ + return NVRDataModel.getTimeZoneNow(); - function doLogin(str) - { + }; + $rootScope.isTzSupported = function () { + return NVRDataModel.isTzSupported(); + }; - var d = $q.defer(); + //------------------------------------------------------------------ + // doLogin() is the function that tries to login to ZM + // it also makes sure we are not back to the same page + // which actually means auth failed, but ZM treats it as a success + //------------------------------------------------------------------ - console.log (">>>>>>>>>>> DO LOGIN"); + function doLogin(str) { - NVRDataModel.processFastLogin() - // coming here means login not needed, old login is valid - .then(function(success) - { - d.resolve("Login Success due to fast login"); - $rootScope.$emit('auth-success', "fast login mode"); - return d.promise; - }, - // coming here means login is needed - function(error) - { - console.log (">>>>>>>>>>>> FAST FAILED - THIS IS OK"); + var d = $q.defer(); - var statename = $ionicHistory.currentStateName(); + console.log(">>>>>>>>>>> DO LOGIN"); - if (statename == "montage-history") - { - NVRDataModel.log("Skipping login process as we are in montage history. Re-logging will mess up the stream"); - d.resolve("success"); + NVRDataModel.processFastLogin() + // coming here means login not needed, old login is valid + .then(function (success) { + d.resolve("Login Success due to fast login"); + $rootScope.$emit('auth-success', "fast login mode"); return d.promise; + }, - } + // coming here means login is needed + function (error) { + console.log(">>>>>>>>>>>> FAST FAILED - THIS IS OK"); - if ($rootScope.isDownloading) - { - NVRDataModel.log("Skipping login process as we are downloading..."); - d.resolve("success"); - return d.promise; - } + var statename = $ionicHistory.currentStateName(); - NVRDataModel.debug("Resetting zmCookie..."); - $rootScope.zmCookie = ''; - // first try to login, if it works, good - // else try to do reachability - - console.log (">>>>>>>>>>>> CALLING DO LOGIN"); - proceedWithLogin() - .then(function(success) - { - - NVRDataModel.debug("Storing login time as " + moment().toString()); - localforage.setItem("lastLogin", moment().toString()); - d.resolve(success); - return d.promise; - }, - function(error) - // login to main failed, so try others - { - console.log (">>>>>>>>>>>> Failed first login, trying reachability"); - NVRDataModel.getReachableConfig(true) - .then(function(data) - { - proceedWithLogin() - .then(function(success) - { - d.resolve(success); - return d.promise; - }, - function(error) - { - d.reject(error); - return d.promise; - }); - - }, - function(error) - { - d.reject(error); - return d.promise; - }); + if (statename == "montage-history") { + NVRDataModel.log("Skipping login process as we are in montage history. Re-logging will mess up the stream"); + d.resolve("success"); + return d.promise; - }); + } - return d.promise; + if ($rootScope.isDownloading) { + NVRDataModel.log("Skipping login process as we are downloading..."); + d.resolve("success"); + return d.promise; + } - function proceedWithLogin() - { - // recompute rand anyway so even if you don't have auth - // your stream should not get frozen - $rootScope.rand = Math.floor((Math.random() * 100000) + 1); - $rootScope.modalRand = Math.floor((Math.random() * 100000) + 1); + NVRDataModel.debug("Resetting zmCookie..."); + $rootScope.zmCookie = ''; + // first try to login, if it works, good + // else try to do reachability - // console.log ("***** STATENAME IS " + statename); + console.log(">>>>>>>>>>>> CALLING DO LOGIN"); + proceedWithLogin() + .then(function (success) { - var d = $q.defer(); - var ld = NVRDataModel.getLogin(); - NVRDataModel.log("zmAutologin called"); + NVRDataModel.debug("Storing login time as " + moment().toString()); + localforage.setItem("lastLogin", moment().toString()); + d.resolve(success); + return d.promise; + }, + function (error) + // login to main failed, so try others + { + console.log(">>>>>>>>>>>> Failed first login, trying reachability"); + NVRDataModel.getReachableConfig(true) + .then(function (data) { + proceedWithLogin() + .then(function (success) { + d.resolve(success); + return d.promise; + }, + function (error) { + d.reject(error); + return d.promise; + }); + + }, + function (error) { + d.reject(error); + return d.promise; + }); + }); - // This is a good time to check if auth is used :-p - if (!ld.isUseAuth) - { - NVRDataModel.log ("Auth is disabled!"); - d.resolve("Login Success"); + return d.promise; - $rootScope.$emit('auth-success', 'no auth'); + function proceedWithLogin() { + // recompute rand anyway so even if you don't have auth + // your stream should not get frozen + $rootScope.rand = Math.floor((Math.random() * 100000) + 1); + $rootScope.modalRand = Math.floor((Math.random() * 100000) + 1); - } + // console.log ("***** STATENAME IS " + statename); - if (str) - { - $ionicLoading.show( - { - template: str, - noBackdrop: true, - duration: zm.httpTimeout - }); - } + var d = $q.defer(); + var ld = NVRDataModel.getLogin(); + NVRDataModel.log("zmAutologin called"); - console.log (">>>>>>>>>>>>>> ISRECAPTCHA"); - NVRDataModel.isReCaptcha() - .then(function(result) - { - if (result == true) - { - $ionicLoading.hide(); - NVRDataModel.displayBanner('error', ['reCaptcha must be disabled', ], "", 8000); - var alertPopup = $ionicPopup.alert( - { - title: 'reCaptcha enabled', - template: $translate.instant('kRecaptcha'), - okText: $translate.instant('kButtonOk'), - cancelText: $translate.instant('kButtonCancel'), - }); + // This is a good time to check if auth is used :-p + if (!ld.isUseAuth) { + NVRDataModel.log("Auth is disabled!"); + d.resolve("Login Success"); - // close it after 5 seconds - $timeout(function() - { + $rootScope.$emit('auth-success', 'no auth'); - alertPopup.close(); - }, 5000); + } - d.reject("Error-disable recaptcha"); - return (d.promise); - } + if (str) { + $ionicLoading.show({ + template: str, + noBackdrop: true, + duration: zm.httpTimeout + }); + } - }); + console.log(">>>>>>>>>>>>>> ISRECAPTCHA"); + + NVRDataModel.isReCaptcha() + .then(function (result) { + if (result == true) { + $ionicLoading.hide(); + NVRDataModel.displayBanner('error', ['reCaptcha must be disabled', ], "", 8000); + var alertPopup = $ionicPopup.alert({ + title: 'reCaptcha enabled', + template: $translate.instant('kRecaptcha'), + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), + }); - var loginData = NVRDataModel.getLogin(); - console.log (">>>>>>>>>>>>>> PARALLEL POST WITH RECAPTCHA TO "+loginData.url); - - var hDelay = loginData.enableSlowLoading ? zm.largeHttpTimeout: zm.httpTimeout; - //NVRDataModel.debug ("*** AUTH LOGIN URL IS " + loginData.url); - $http( - { - - method: 'POST', - timeout:hDelay, - //withCredentials: true, - url: loginData.url + '/index.php', - headers: - { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Accept': 'application/json', - }, - transformRequest: function(obj) - { - var str = []; - for (var p in obj) - str.push(encodeURIComponent(p) + "=" + - encodeURIComponent(obj[p])); - var params = str.join("&"); - return params; - }, + // close it after 5 seconds + $timeout(function () { - data: - { - username: loginData.username, - password: loginData.password, - action: "login", - view: "console" - } - }) - .success(function(data, status, headers) - { - console.log (">>>>>>>>>>>>>> PARALLEL POST SUCCESS"); - $ionicLoading.hide(); - - // Coming here does not mean success - // it could also be a bad login, but - // ZM returns you to login.php and returns 200 OK - // so we will check if the data has - // <title>ZM - Login</title> -- it it does then its the login page - - if (data.indexOf(zm.loginScreenString) == -1) - { - //eventServer.start(); - $rootScope.loggedIntoZm = 1; + alertPopup.close(); + }, 5000); - NVRDataModel.log("zmAutologin successfully logged into Zoneminder"); + d.reject("Error-disable recaptcha"); + return (d.promise); + } - d.resolve("Login Success"); + }); - $rootScope.$emit('auth-success', data); + var loginData = NVRDataModel.getLogin(); + console.log(">>>>>>>>>>>>>> PARALLEL POST WITH RECAPTCHA TO " + loginData.url); + + var hDelay = loginData.enableSlowLoading ? zm.largeHttpTimeout : zm.httpTimeout; + //NVRDataModel.debug ("*** AUTH LOGIN URL IS " + loginData.url); + $http({ + + method: 'POST', + timeout: hDelay, + //withCredentials: true, + url: loginData.url + '/index.php', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json', + }, + transformRequest: function (obj) { + var str = []; + for (var p in obj) + str.push(encodeURIComponent(p) + "=" + + encodeURIComponent(obj[p])); + var params = str.join("&"); + return params; + }, + + data: { + username: loginData.username, + password: loginData.password, + action: "login", + view: "console" + } + }) + .success(function (data, status, headers) { + console.log(">>>>>>>>>>>>>> PARALLEL POST SUCCESS"); + $ionicLoading.hide(); - } - else // this means login error - { - $rootScope.loggedIntoZm = -1; - //console.log("**** ZM Login FAILED"); - NVRDataModel.log("zmAutologin Error: Bad Credentials ", "error"); - $rootScope.$emit('auth-error', "incorrect credentials"); + // Coming here does not mean success + // it could also be a bad login, but + // ZM returns you to login.php and returns 200 OK + // so we will check if the data has + // <title>ZM - Login</title> -- it it does then its the login page - d.reject("Login Error"); - return (d.promise); - } + if (data.indexOf(zm.loginScreenString) == -1) { + //eventServer.start(); + $rootScope.loggedIntoZm = 1; - // Now go ahead and re-get auth key - // if login was a success - $rootScope.authSession = "undefined"; - var ld = NVRDataModel.getLogin(); - NVRDataModel.getAuthKey($rootScope.validMonitorId) - .then(function(success) - { - - //console.log(success); - $rootScope.authSession = success; - NVRDataModel.log("Stream authentication construction: " + - $rootScope.authSession); - - }, - function(error) - { - //console.log(error); - - NVRDataModel.log("Modal: Error returned Stream authentication construction. Retaining old value of: " + $rootScope.authSession); - NVRDataModel.debug("Error was: " + JSON.stringify(error)); - }); + NVRDataModel.log("zmAutologin successfully logged into Zoneminder"); - return (d.promise); + d.resolve("Login Success"); - }) - .error(function(error, status) - { + $rootScope.$emit('auth-success', data); - console.log (">>>>>>>>>>>>>> PARALLEL POST ERROR"); - $ionicLoading.hide(); + } else // this means login error + { + $rootScope.loggedIntoZm = -1; + //console.log("**** ZM Login FAILED"); + NVRDataModel.log("zmAutologin Error: Bad Credentials ", "error"); + $rootScope.$emit('auth-error', "incorrect credentials"); + + d.reject("Login Error"); + return (d.promise); + } + + // Now go ahead and re-get auth key + // if login was a success + $rootScope.authSession = "undefined"; + var ld = NVRDataModel.getLogin(); + NVRDataModel.getAuthKey($rootScope.validMonitorId) + .then(function (success) { + + //console.log(success); + $rootScope.authSession = success; + NVRDataModel.log("Stream authentication construction: " + + $rootScope.authSession); + + }, + function (error) { + //console.log(error); + + NVRDataModel.log("Modal: Error returned Stream authentication construction. Retaining old value of: " + $rootScope.authSession); + NVRDataModel.debug("Error was: " + JSON.stringify(error)); + }); - //console.log("**** ZM Login FAILED"); + return (d.promise); - // FIXME: Is this sometimes results in null + }) + .error(function (error, status) { - NVRDataModel.log("zmAutologin Error " + JSON.stringify(error) + " and status " + status); - // bad urls etc come here - $rootScope.loggedIntoZm = -1; - $rootScope.$emit('auth-error', error); + console.log(">>>>>>>>>>>>>> PARALLEL POST ERROR"); + $ionicLoading.hide(); - d.reject("Login Error"); - return d.promise; - }); - return d.promise; - } - }); - return d.promise; + //console.log("**** ZM Login FAILED"); - } + // FIXME: Is this sometimes results in null - function start() - { - var ld = NVRDataModel.getLogin(); - // lets keep this timer irrespective of auth or no auth - $rootScope.loggedIntoZm = 0; - $interval.cancel(zmAutoLoginHandle); - //doLogin(); - zmAutoLoginHandle = $interval(function() - { - doLogin(""); + NVRDataModel.log("zmAutologin Error " + JSON.stringify(error) + " and status " + status); + // bad urls etc come here + $rootScope.loggedIntoZm = -1; + $rootScope.$emit('auth-error', error); - }, zm.loginInterval); // Auto login every 5 minutes - // PHP timeout is around 10 minutes - // should be ok? + d.reject("Login Error"); + return d.promise; + }); + return d.promise; + } + }); + return d.promise; - } + } - function stop() - { - var ld = NVRDataModel.getLogin(); + function start() { + var ld = NVRDataModel.getLogin(); + // lets keep this timer irrespective of auth or no auth + $rootScope.loggedIntoZm = 0; + $interval.cancel(zmAutoLoginHandle); + //doLogin(); + zmAutoLoginHandle = $interval(function () { + doLogin(""); - $interval.cancel(zmAutoLoginHandle); - $rootScope.loggedIntoZm = 0; - NVRDataModel.log("Cancelling zmAutologin timer"); + }, zm.loginInterval); // Auto login every 5 minutes + // PHP timeout is around 10 minutes + // should be ok? + + } - } + function stop() { + var ld = NVRDataModel.getLogin(); - return { - start: start, - stop: stop, - doLogin: doLogin - }; -}) + $interval.cancel(zmAutoLoginHandle); + $rootScope.loggedIntoZm = 0; + NVRDataModel.log("Cancelling zmAutologin timer"); -//==================================================================== -// First run in ionic -//==================================================================== + } -.run(function($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate, $localstorage) - { + return { + start: start, + stop: stop, + doLogin: doLogin + }; + }) + + //==================================================================== + // First run in ionic + //==================================================================== + + .run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate, $localstorage) { $rootScope.appName = "zmNinja"; $rootScope.zmGlobalCookie = ""; @@ -1287,40 +1134,32 @@ angular.module('zmApp', [ $rootScope.apiVersion = ""; // only for android - $rootScope.exitApp = function() - { + $rootScope.exitApp = function () { NVRDataModel.log("user exited app"); ionic.Platform.exitApp(); }; // This is a global exception interceptor - $rootScope.exceptionMessage = function(error) - { + $rootScope.exceptionMessage = function (error) { NVRDataModel.debug("**EXCEPTION**" + error.reason + " caused by " + error.cause); }; - window.addEventListener('beforeunload', function(ev) - { + window.addEventListener('beforeunload', function (ev) { - if ($rootScope.platformOS != 'desktop') - { + if ($rootScope.platformOS != 'desktop') { ev.returnValue = "true"; return; } - localforage.setItem('last-desktop-state', - { + localforage.setItem('last-desktop-state', { 'name': $ionicHistory.currentView().stateName, 'params': $ionicHistory.currentView().stateParams - }).then(function() - { + }).then(function () { return localforage.getItem('last-desktop-state'); - }).then(function(value) - { + }).then(function (value) { ev.returnValue = "true"; - }).catch(function(err) - { + }).catch(function (err) { ev.returnValue = "true"; }); @@ -1330,10 +1169,8 @@ angular.module('zmApp', [ // lets see if it really works $rootScope.online = navigator.onLine; - $window.addEventListener("offline", function() - { - $rootScope.$apply(function() - { + $window.addEventListener("offline", function () { + $rootScope.$apply(function () { $rootScope.online = false; NVRDataModel.log("Your network went offline"); @@ -1342,27 +1179,21 @@ angular.module('zmApp', [ }); }, false); - $window.addEventListener("online", function() - { - $rootScope.$apply(function() - { + $window.addEventListener("online", function () { + $rootScope.$apply(function () { $rootScope.online = true; - $timeout(function() - { + $timeout(function () { var networkState = navigator.connection.type; NVRDataModel.debug("Detected network type as: " + networkState); var strState = NVRDataModel.getBandwidth(); NVRDataModel.debug("getBandwidth() normalized it as: " + strState); $rootScope.runMode = strState; if ((NVRDataModel.getLogin().autoSwitchBandwidth == true) && - (NVRDataModel.getLogin().enableLowBandwidth == true)) - { + (NVRDataModel.getLogin().enableLowBandwidth == true)) { NVRDataModel.debug("Setting app state to: " + strState); $rootScope.$emit('bandwidth-change', strState); - } - else - { + } else { NVRDataModel.debug("Not changing bandwidth state, as auto change is not on"); } @@ -1377,17 +1208,13 @@ angular.module('zmApp', [ // This code takes care of trapping the Android back button // and takes it to the menu. //console.log (">>>>>>>>>>>>>>>>>>BACK BUTTON REGISTERED"); - $ionicPlatform.registerBackButtonAction(function(e) - { + $ionicPlatform.registerBackButtonAction(function (e) { e.preventDefault(); //console.log ("******** back called with isOpenLeft: " + $ionicSideMenuDelegate.isOpenLeft()); - if (!$ionicSideMenuDelegate.isOpenLeft()) - { + if (!$ionicSideMenuDelegate.isOpenLeft()) { $ionicSideMenuDelegate.toggleLeft(); //console.log("Status of SIDE MENU IS : " + $ionicSideMenuDelegate.isOpen()); - } - else - { + } else { navigator.app.exitApp(); } }, 501); @@ -1395,8 +1222,7 @@ angular.module('zmApp', [ // this works reliably on both Android and iOS. The "onorientation" seems to reverse w/h in Android. Go figure. // http://stackoverflow.com/questions/1649086/detect-rotation-of-android-phone-in-the-browser-with-javascript - var checkOrientation = function() - { + var checkOrientation = function () { var pixelRatio = window.devicePixelRatio || 1; $rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width); $rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height); @@ -1409,12 +1235,10 @@ angular.module('zmApp', [ // we come here when a user forcibly cancels portal auth // useful when you know your auth won't succeed and you need to // switch to another server - $rootScope.cancelAuth = function() - { + $rootScope.cancelAuth = function () { $ionicLoading.hide(); NVRDataModel.log("User cancelled login"); - $ionicHistory.nextViewOptions( - { + $ionicHistory.nextViewOptions({ disableAnimate: true, disableBack: true }); @@ -1422,8 +1246,7 @@ angular.module('zmApp', [ window.stop(); //console.log ("inside cancelAuth , calling wizard"); - $state.go("login", - { + $state.go("login", { "wizard": false }); return; @@ -1433,26 +1256,21 @@ angular.module('zmApp', [ // authorize state transitions //---------------------------------------------------------------------------- - $rootScope.$on('$stateChangeStart', function(event, toState, toParams) - { + $rootScope.$on('$stateChangeStart', function (event, toState, toParams) { var requireLogin = toState.data.requireLogin; - if ($rootScope.apiValid == false && toState.name != 'invalidapi' && toState.data.requireLogin == true) - { + if ($rootScope.apiValid == false && toState.name != 'invalidapi' && toState.data.requireLogin == true) { event.preventDefault(); $state.transitionTo('invalidapi'); return; } - if (NVRDataModel.isLoggedIn() || toState.data.requireLogin == false) - { + if (NVRDataModel.isLoggedIn() || toState.data.requireLogin == false) { //console.log("State transition is authorized"); return; - } - else - { + } else { NVRDataModel.log("In Auth State trans: Not logged in, requested to go to " + JSON.stringify(toState)); // event.preventDefault(); // @@ -1461,11 +1279,9 @@ angular.module('zmApp', [ } - if (requireLogin) - { + if (requireLogin) { - $ionicPopup.alert( - { + $ionicPopup.alert({ title: $translate.instant('kCredentialsTitle'), template: $translate.instant('kCredentialsBody') }); @@ -1497,37 +1313,34 @@ angular.module('zmApp', [ // called when device is ready //--------------------------------------------------------------------- - function getTextZoomCallback(tz) - { + function getTextZoomCallback(tz) { $rootScope.textScaleFactor = parseFloat(tz + "%") / 100.0; NVRDataModel.debug("text zoom factor is " + $rootScope.textScaleFactor); } - $ionicPlatform.ready(function() - { - - - - // handles URL launches - // if you just launch zmninja:// then it will honor the settings in "tap screen" -> events or montage - // if you launch with zmninja://<mid> it will take you to live view for that mid - window.handleOpenURL = function(url) { - $rootScope.tappedNotification = 1; - $rootScope.tappedMid = 0; - var c= URI.parse(url); - //NVRDataModel.log ("***********launched with "+ JSON.stringify(c)); - if (c.query) - { + $ionicPlatform.ready(function () { + + + + // handles URL launches + // if you just launch zmninja:// then it will honor the settings in "tap screen" -> events or montage + // if you launch with zmninja://<mid> it will take you to live view for that mid + window.handleOpenURL = function (url) { + $rootScope.tappedNotification = 1; + $rootScope.tappedMid = 0; + var c = URI.parse(url); + //NVRDataModel.log ("***********launched with "+ JSON.stringify(c)); + if (c.query) { var qm = getQueryVariable(c.query, "mid"); if (qm) $rootScope.tappedMid = parseInt(qm); - NVRDataModel.log ("external URL called with MID="+$rootScope.tappedMid); + NVRDataModel.log("external URL called with MID=" + $rootScope.tappedMid); //console.log (">>>>>>>>> EID="+getQueryVariable(c.query, "eid")); - } + } - - - }; + + + }; $rootScope.textScaleFactor = 1.0; $rootScope.apiValid = false; @@ -1553,23 +1366,20 @@ angular.module('zmApp', [ // $rootScope.lastState = "events"; //$rootScope.lastStateParam = "0"; - localforage.config( - { + localforage.config({ name: zm.dbName }); var order = []; - if ($rootScope.platformOS == 'ios') - { + if ($rootScope.platformOS == 'ios') { order = [window.cordovaSQLiteDriver._driver, localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE ]; - } - else + } else { // don't do SQL for non IOS - seems to hang? @@ -1582,15 +1392,13 @@ angular.module('zmApp', [ } - localforage.defineDriver(window.cordovaSQLiteDriver).then(function() - { + localforage.defineDriver(window.cordovaSQLiteDriver).then(function () { return localforage.setDriver( // Try setting cordovaSQLiteDriver if available, order ); - }).then(function() - { + }).then(function () { // this should alert "cordovaSQLiteDriver" when in an emulator or a device NVRDataModel.log("localforage driver for storage:" + localforage.driver()); @@ -1598,12 +1406,10 @@ angular.module('zmApp', [ var defaultServerName = $localstorage.get("defaultServerName"); localforage.getItem("defaultServerName") - .then(function(val) - { + .then(function (val) { // console.log (">>>> localforage reported defaultServerName as " + val); // if neither, we are in first use, mates! - if (!val && !defaultServerName) - { + if (!val && !defaultServerName) { continueInitialInit(); /* NVRDataModel.debug ("Neither localstorage or forage - First use, showing warm and fuzzy..."); $ionicHistory.nextViewOptions({ @@ -1611,9 +1417,7 @@ angular.module('zmApp', [ disableBack: true }); $state.go('first-use');*/ - } - else if (!val && defaultServerName) - { + } else if (!val && defaultServerName) { NVRDataModel.log(">>>>Importing data from localstorage...."); var dsn = defaultServerName; @@ -1632,25 +1436,21 @@ angular.module('zmApp', [ NVRDataModel.log("server group list:" + JSON.stringify(sgl)); localforage.setItem('defaultLang', dl) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated defaultLang..."); NVRDataModel.setFirstUse(ifu); return localforage.setItem('isFirstUse', ifu); }) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated isFirstUse..."); return localforage.setItem('lastUpdateCheck', ifu); }) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated lastUpdateCheck..."); return localforage.setItem('latestBlogPostChecked', lbpc); }) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated latestBlogPostChecked..."); // lets encrypt serverGroupList NVRDataModel.log("server group list is " + JSON.stringify(sgl)); @@ -1659,27 +1459,22 @@ angular.module('zmApp', [ ct = sgl; return localforage.setItem('serverGroupList', ct); }) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated serverGroupList..."); return localforage.setItem('defaultServerName', dsn); }) - .then(function() - { + .then(function () { NVRDataModel.log(">>>>migrated defaultServerName..."); NVRDataModel.log(">>>>Migrated all values, continuing..."); //NVRDataModel.migrationComplete(); continueInitialInit(); }) - .catch(function(err) - { + .catch(function (err) { NVRDataModel.log("Migration error : " + JSON.stringify(err)); continueInitialInit(); }); - } - else - { + } else { NVRDataModel.log(">>>>No data to import...."); //NVRDataModel.migrationComplete(); continueInitialInit(); @@ -1689,8 +1484,7 @@ angular.module('zmApp', [ }); - function continueInitialInit() - { + 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); @@ -1699,12 +1493,10 @@ angular.module('zmApp', [ $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; - if (window.cordova && window.cordova.plugins.Keyboard) - { + if (window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.disableScroll(true); } - if (window.StatusBar) - { + if (window.StatusBar) { // org.apache.cordova.statusbar required NVRDataModel.log("Updating statusbar"); StatusBar.styleDefault(); @@ -1712,27 +1504,22 @@ angular.module('zmApp', [ StatusBar.backgroundColorByHexString("#2980b9"); } - if (window.cordova) - { + if (window.cordova) { $cordovaSplashscreen.hide(); - - cordova.getAppVersion.getVersionNumber().then(function(version) - { + + cordova.getAppVersion.getVersionNumber().then(function (version) { appVersion = version; NVRDataModel.log("App Version: " + appVersion); NVRDataModel.setAppVersion(appVersion); }); } - $fileLogger.checkFile().then(function(resp) - { - if (parseInt(resp.size) > zm.logFileMaxSize) - { + $fileLogger.checkFile().then(function (resp) { + if (parseInt(resp.size) > zm.logFileMaxSize) { - $fileLogger.deleteLogfile().then(function() - { + $fileLogger.deleteLogfile().then(function () { NVRDataModel.log("Deleting old log file as it exceeds " + zm.logFileMaxSize + " bytes"); }); @@ -1742,13 +1529,10 @@ angular.module('zmApp', [ $fileLogger.setStorageFilename(zm.logFile); $fileLogger.setTimestampFormat('MMM d, y ' + NVRDataModel.getTimeFormat()); - if (NVRDataModel.getLogin().disableNative) - { + if (NVRDataModel.getLogin().disableNative) { NVRDataModel.log("Disabling native transitions..."); $ionicNativeTransitions.enable(false); - } - else - { + } else { NVRDataModel.log("Enabling native transitions..."); $ionicNativeTransitions.enable(true); } @@ -1757,44 +1541,35 @@ angular.module('zmApp', [ NVRDataModel.log("Retrieving language before init is called..."); localforage.getItem("defaultLang") - .then(function(val) - { + .then(function (val) { var lang = val; //console.log (">>>>>>>>>>>>>> LANG IS " + val); - if (lang == undefined || lang == null) - { + if (lang == undefined || lang == null) { NVRDataModel.log("No language set, switching to en"); lang = "en"; - } - else - { + } else { NVRDataModel.log("Language stored as:" + lang); } NVRDataModel.setDefaultLanguage(lang, false) - .then(function(success) - { + .then(function (success) { NVRDataModel.log(">>>>Language to be used:" + $translate.proposedLanguage()); moment.locale($translate.proposedLanguage()); // Remember this is before data Init // so I need to do a direct forage fetch localforage.getItem("isFirstUse") - .then(function(val) - { + .then(function (val) { //console.log ("isFirstUse is " + val); - if (val == null || val == true) - { + if (val == null || val == true) { NVRDataModel.log("First time detected"); $state.go("first-use"); return; - } - else - { + } else { continueRestOfInit(); } @@ -1804,43 +1579,36 @@ angular.module('zmApp', [ }); } - function continueRestOfInit() - { + function continueRestOfInit() { - if ($rootScope.platformOS == 'desktop') - { + if ($rootScope.platformOS == 'desktop') { $rootScope.lastState = ""; $rootScope.lastStateParam = {}; localforage.getItem('last-desktop-state') - .then(function(succ) - { + .then(function (succ) { // console.log ("FOUND " + JSON.stringify(succ) + ":"+succ); - if (succ) - { + if (succ) { $rootScope.lastState = succ.name; $rootScope.lastStateParam = succ.params; } loadServices(); - }, function(err) - { + }, function (err) { console.log("ERR " + JSON.stringify(err)); loadServices(); }); - } - else + } else { loadServices(); } - function loadServices() - { + function loadServices() { NVRDataModel.log("Language file loaded, continuing with rest"); NVRDataModel.init(); - + // now do SSL check //setSSLCerts(); @@ -1856,63 +1624,53 @@ angular.module('zmApp', [ } - - function setupPauseAndResume() - { + + function setupPauseAndResume() { NVRDataModel.log("Setting up pause and resume handler AFTER language is loaded..."); //--------------------------------------------------------------------------- // resume handler //---------------------------------------------------------------------------- - document.addEventListener("resume", function() - { + document.addEventListener("resume", function () { NVRDataModel.log("App is resuming from background"); $rootScope.isDownloading = false; var forceDelay = NVRDataModel.getLogin().resumeDelay; NVRDataModel.log(">>> Resume delayed for " + forceDelay + " ms, to wait for network stack..."); - $timeout(function() - { + $timeout(function () { var ld = NVRDataModel.getLogin(); NVRDataModel.setBackground(false); // don't animate - $ionicHistory.nextViewOptions( - { + $ionicHistory.nextViewOptions({ disableAnimate: true, disableBack: true }); // remember the last state so we can // go back there after auth - if ($ionicHistory.currentView()) - { + if ($ionicHistory.currentView()) { $rootScope.lastState = $ionicHistory.currentView().stateName; $rootScope.lastStateParam = $ionicHistory.currentView().stateParams; NVRDataModel.debug("Last State recorded:" + JSON.stringify($ionicHistory.currentView())); - if ($rootScope.lastState == "zm-portal-login") - { + if ($rootScope.lastState == "zm-portal-login") { NVRDataModel.debug("Last state was portal-login, so forcing montage"); $rootScope.lastState = "montage"; } NVRDataModel.debug("going to portal login"); - $ionicHistory.nextViewOptions( - { + $ionicHistory.nextViewOptions({ disableAnimate: true }); $state.go("zm-portal-login"); return; - } - else - { + } else { $rootScope.lastState = ""; $rootScope.lastStateParam = ""; NVRDataModel.debug("reset lastState to null"); - $ionicHistory.nextViewOptions( - { + $ionicHistory.nextViewOptions({ disableAnimate: true }); $state.go("zm-portal-login"); @@ -1926,8 +1684,7 @@ angular.module('zmApp', [ //--------------------------------------------------------------------------- // background handler //---------------------------------------------------------------------------- - document.addEventListener("pause", function() - { + document.addEventListener("pause", function () { NVRDataModel.setBackground(true); NVRDataModel.setJustResumed(true); // used for window stop @@ -1941,8 +1698,7 @@ angular.module('zmApp', [ var ld = NVRDataModel.getLogin(); - if (ld.exitOnSleep && $rootScope.platformOS == "android") - { + if (ld.exitOnSleep && $rootScope.platformOS == "android") { NVRDataModel.log("user exited app"); ionic.Platform.exitApp(); } @@ -1962,421 +1718,359 @@ angular.module('zmApp', [ }) //run -//------------------------------------------------------------------ -// Route configuration -//------------------------------------------------------------------ + //------------------------------------------------------------------ + // Route configuration + //------------------------------------------------------------------ -// My route map connecting menu options to their respective templates and controllers -.config(function($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, $ionicNativeTransitionsProvider, $logProvider, $translateProvider) -{ + // My route map connecting menu options to their respective templates and controllers + .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, $ionicNativeTransitionsProvider, $logProvider, $translateProvider) { - //$logProvider.debugEnabled(false); - //$compileProvider.debugInfoEnabled(false); + //$logProvider.debugEnabled(false); + //$compileProvider.debugInfoEnabled(false); - // This is an exception interceptor so it can show up in app logs - // if they occur. I suspect digest and other errors will be useful - // for me to see - //$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/); + // This is an exception interceptor so it can show up in app logs + // if they occur. I suspect digest and other errors will be useful + // for me to see + //$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/); - $provide.decorator("$exceptionHandler", ['$delegate', '$injector', function($delegate, $injector) - { - return function(exception, cause) - { + $provide.decorator("$exceptionHandler", ['$delegate', '$injector', function ($delegate, $injector) { + return function (exception, cause) { - var $rootScope = $injector.get("$rootScope"); - $rootScope.exceptionMessage( - { - reason: exception, - cause: cause - }); + var $rootScope = $injector.get("$rootScope"); + $rootScope.exceptionMessage({ + reason: exception, + cause: cause + }); - $delegate(exception, cause); + $delegate(exception, cause); - }; - }]); - - // If you do this, Allow Origin can't be * - //$httpProvider.defaults.withCredentials = true; - $httpProvider.interceptors.push('timeoutHttpIntercept'); - $ionicConfigProvider.navBar.alignTitle('center'); - //$ionicConfigProvider.backButton.text('').icon('ion-chevron-left'); - //$ionicConfigProvider.backButton.text('').icon('ion-chevron-left').previousTitleText(false); - // use overflow-scroll=false in ion-content - // removing it here doesn't allow you to enable it per view - // so it messes up scrolldelegate zoom and possibly others - //$ionicConfigProvider.scrolling.jsScrolling(false); - $compileProvider.debugInfoEnabled(false); - - $ionicNativeTransitionsProvider.setDefaultOptions( - { - duration: 250, - }); - - $translateProvider.useStaticFilesLoader( - { - prefix: 'lang/locale-', - suffix: '.json' - }); - - //$translateProvider.useLocalStorage(); - - $translateProvider.registerAvailableLanguageKeys(['en', 'de', 'es', 'fr', 'it', 'ru', 'ja', 'ko', 'nl', 'pl', 'zh', 'zh_CN', 'zh_TW', 'pt', 'ar', 'hi'], - { - 'en_*': 'en', - 'de_*': 'de', - 'es_*': 'es', - 'fr_*': 'fr', - 'it_*': 'it', - 'ru_*': 'ru', - 'ja_*': 'ja', - 'ko_*': 'ko', - 'nl_*': 'nl', - 'pt_*': 'pt', - 'pl_*': 'pl', - 'ar_*': 'ar', - 'hi_*': 'hi', - '*': 'en' // must be last - }); - - //$translateProvider.determinePreferredLanguage(); - //$translateProvider.preferredLanguage("en"); - $translateProvider.fallbackLanguage("en"); - $translateProvider.useSanitizeValueStrategy('escape'); - - $stateProvider - .state('app', - { - url: '/', - abstract: true, - templateUrl: 'index.html', - cache: false, - - //controller: 'AppCtrl' - }) - - .state('login', - { - data: - { - requireLogin: false - }, - url: "/login/:wizard", - cache: false, - templateUrl: "templates/login.html", - controller: 'zmApp.LoginCtrl', + }; + }]); + + // If you do this, Allow Origin can't be * + //$httpProvider.defaults.withCredentials = true; + $httpProvider.interceptors.push('timeoutHttpIntercept'); + $ionicConfigProvider.navBar.alignTitle('center'); + //$ionicConfigProvider.backButton.text('').icon('ion-chevron-left'); + //$ionicConfigProvider.backButton.text('').icon('ion-chevron-left').previousTitleText(false); + // use overflow-scroll=false in ion-content + // removing it here doesn't allow you to enable it per view + // so it messes up scrolldelegate zoom and possibly others + //$ionicConfigProvider.scrolling.jsScrolling(false); + $compileProvider.debugInfoEnabled(false); + + $ionicNativeTransitionsProvider.setDefaultOptions({ + duration: 250, + }); - }) + $translateProvider.useStaticFilesLoader({ + prefix: 'lang/locale-', + suffix: '.json' + }); - .state('help', - { - data: - { - requireLogin: false - }, - url: "/help", - cache: false, - templateUrl: "templates/help.html", - controller: 'zmApp.HelpCtrl', + //$translateProvider.useLocalStorage(); + + $translateProvider.registerAvailableLanguageKeys(['en', 'de', 'es', 'fr', 'it', 'ru', 'ja', 'ko', 'nl', 'pl', 'zh', 'zh_CN', 'zh_TW', 'pt', 'ar', 'hi'], { + 'en_*': 'en', + 'de_*': 'de', + 'es_*': 'es', + 'fr_*': 'fr', + 'it_*': 'it', + 'ru_*': 'ru', + 'ja_*': 'ja', + 'ko_*': 'ko', + 'nl_*': 'nl', + 'pt_*': 'pt', + 'pl_*': 'pl', + 'ar_*': 'ar', + 'hi_*': 'hi', + '*': 'en' // must be last + }); - }) + //$translateProvider.determinePreferredLanguage(); + //$translateProvider.preferredLanguage("en"); + $translateProvider.fallbackLanguage("en"); + $translateProvider.useSanitizeValueStrategy('escape'); - .state('news', - { - data: - { - requireLogin: false - }, - url: "/news", - cache: false, - templateUrl: "templates/news.html", - controller: 'zmApp.NewsCtrl', + $stateProvider + .state('app', { + url: '/', + abstract: true, + templateUrl: 'index.html', + cache: false, - }) + //controller: 'AppCtrl' + }) - .state('monitors', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - // console.log("Inside app.montage resolve"); - return NVRDataModel.getMonitors(0); - } - }, - url: "/monitors", - cache: false, - templateUrl: "templates/monitors.html", - controller: 'zmApp.MonitorCtrl', + .state('login', { + data: { + requireLogin: false + }, + url: "/login/:wizard", + cache: false, + templateUrl: "templates/login.html", + controller: 'zmApp.LoginCtrl', - }) + }) - .state('events', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - //console.log("Inside app.events resolve"); - return NVRDataModel.getMonitors(0); - } - }, - cache: false, - url: "/events/:id/:playEvent", - templateUrl: "templates/events.html", - controller: 'zmApp.EventCtrl', + .state('help', { + data: { + requireLogin: false + }, + url: "/help", + cache: false, + templateUrl: "templates/help.html", + controller: 'zmApp.HelpCtrl', - }) + }) - .state('lowversion', - { - data: - { - requireLogin: false - }, + .state('news', { + data: { + requireLogin: false + }, + url: "/news", + cache: false, + templateUrl: "templates/news.html", + controller: 'zmApp.NewsCtrl', - url: "/lowversion/:ver", - cache: false, - templateUrl: "templates/lowversion.html", - controller: 'zmApp.LowVersionCtrl', + }) - }) + .state('monitors', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + // console.log("Inside app.montage resolve"); + return NVRDataModel.getMonitors(0); + } + }, + url: "/monitors", + cache: false, + templateUrl: "templates/monitors.html", + controller: 'zmApp.MonitorCtrl', - .state('importantmessage', - { - data: - { - requireLogin: false - }, + }) - cache: false, - url: "/importantmessage/:ver", - templateUrl: "templates/important_message.html", - controller: 'zmApp.ImportantMessageCtrl', + .state('events', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + //console.log("Inside app.events resolve"); + return NVRDataModel.getMonitors(0); + } + }, + cache: false, + url: "/events/:id/:playEvent", + templateUrl: "templates/events.html", + controller: 'zmApp.EventCtrl', - }) + }) - .state('invalidapi', - { - data: - { - requireLogin: false - }, + .state('lowversion', { + data: { + requireLogin: false + }, - cache: false, - url: "/invalidapi", - templateUrl: "templates/invalidapi.html", - controller: 'zmApp.InvalidApiCtrl', + url: "/lowversion/:ver", + cache: false, + templateUrl: "templates/lowversion.html", + controller: 'zmApp.LowVersionCtrl', - }) + }) - .state('events-graphs', - { - data: - { - requireLogin: true - }, - cache: false, - url: "/events-graphs", - templateUrl: "templates/events-graphs.html", - controller: 'zmApp.EventsGraphsCtrl', + .state('importantmessage', { + data: { + requireLogin: false + }, - }) + cache: false, + url: "/importantmessage/:ver", + templateUrl: "templates/important_message.html", + controller: 'zmApp.ImportantMessageCtrl', - .state('events-date-time-filter', - { - data: - { - requireLogin: true - }, - cache: false, - url: "/events-date-time-filter", - templateUrl: "templates/events-date-time-filter.html", - controller: 'zmApp.EventDateTimeFilterCtrl', + }) - }) + .state('invalidapi', { + data: { + requireLogin: false + }, - .state('state', - { - data: - { - requireLogin: true - }, - cache: false, - url: "/state", - templateUrl: "templates/state.html", - controller: 'zmApp.StateCtrl', + cache: false, + url: "/invalidapi", + templateUrl: "templates/invalidapi.html", + controller: 'zmApp.InvalidApiCtrl', - }) + }) - .state('devoptions', - { - data: - { - requireLogin: false - }, - url: "/devoptions", - cache: false, - templateUrl: "templates/devoptions.html", - controller: 'zmApp.DevOptionsCtrl', - }) + .state('events-graphs', { + data: { + requireLogin: true + }, + cache: false, + url: "/events-graphs", + templateUrl: "templates/events-graphs.html", + controller: 'zmApp.EventsGraphsCtrl', - .state('timeline', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - //console.log("Inside app.events resolve"); - return NVRDataModel.getMonitors(0); - } - }, - url: "/timeline", - cache: false, - templateUrl: "templates/timeline.html", - controller: 'zmApp.TimelineCtrl', + }) - }) + .state('events-date-time-filter', { + data: { + requireLogin: true + }, + cache: false, + url: "/events-date-time-filter", + templateUrl: "templates/events-date-time-filter.html", + controller: 'zmApp.EventDateTimeFilterCtrl', - .state('eventserversettings', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - return NVRDataModel.getMonitors(0); - } - }, - url: "/eventserversettings", - cache: false, - templateUrl: "templates/eventserversettings.html", - controller: 'zmApp.EventServerSettingsCtrl', + }) - }) + .state('state', { + data: { + requireLogin: true + }, + cache: false, + url: "/state", + templateUrl: "templates/state.html", + controller: 'zmApp.StateCtrl', - .state('log', - { - data: - { - requireLogin: false - }, - url: "/log", - cache: false, - templateUrl: "templates/log.html", - controller: 'zmApp.LogCtrl', + }) - }) + .state('devoptions', { + data: { + requireLogin: false + }, + url: "/devoptions", + cache: false, + templateUrl: "templates/devoptions.html", + controller: 'zmApp.DevOptionsCtrl', + }) + + .state('timeline', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + //console.log("Inside app.events resolve"); + return NVRDataModel.getMonitors(0); + } + }, + url: "/timeline", + cache: false, + templateUrl: "templates/timeline.html", + controller: 'zmApp.TimelineCtrl', - .state('wizard', - { - data: - { - requireLogin: false - }, - url: "/wizard", - cache: false, - templateUrl: "templates/wizard.html", - controller: 'zmApp.WizardCtrl', + }) - }) + .state('eventserversettings', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + return NVRDataModel.getMonitors(0); + } + }, + url: "/eventserversettings", + cache: false, + templateUrl: "templates/eventserversettings.html", + controller: 'zmApp.EventServerSettingsCtrl', - .state('zm-portal-login', - { - data: - { - requireLogin: false - }, - url: "/zm-portal-login", - cache: false, - templateUrl: "templates/zm-portal-login.html", - controller: 'zmApp.PortalLoginCtrl', - nativeTransitions: null // disable for speed + }) - }) + .state('log', { + data: { + requireLogin: false + }, + url: "/log", + cache: false, + templateUrl: "templates/log.html", + controller: 'zmApp.LogCtrl', - .state('first-use', - { - data: - { - requireLogin: false - }, - url: "/first-use", - cache: false, - templateUrl: "templates/first-use.html", - controller: 'zmApp.FirstUseCtrl', + }) - }) + .state('wizard', { + data: { + requireLogin: false + }, + url: "/wizard", + cache: false, + templateUrl: "templates/wizard.html", + controller: 'zmApp.WizardCtrl', - .state('montage-history', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - //console.log("Inside app.events resolve"); - return NVRDataModel.getMonitors(0); - } + }) - }, - cache: false, - url: "/montage-history", - templateUrl: "templates/montage-history.html", - controller: 'zmApp.MontageHistoryCtrl', - params: - { - minimal: false, - isRefresh: false - }, + .state('zm-portal-login', { + data: { + requireLogin: false + }, + url: "/zm-portal-login", + cache: false, + templateUrl: "templates/zm-portal-login.html", + controller: 'zmApp.PortalLoginCtrl', + nativeTransitions: null // disable for speed - }) + }) - .state('montage', - { - data: - { - requireLogin: true - }, - resolve: - { - message: function(NVRDataModel) - { - //console.log("Inside app.events resolve"); - return NVRDataModel.getMonitors(0); - } + .state('first-use', { + data: { + requireLogin: false + }, + url: "/first-use", + cache: false, + templateUrl: "templates/first-use.html", + controller: 'zmApp.FirstUseCtrl', - }, - url: "/montage", - cache: false, - templateUrl: "templates/montage.html", - controller: 'zmApp.MontageCtrl', - params: - { - minimal: false, - isRefresh: false - }, + }) - }); + .state('montage-history', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + //console.log("Inside app.events resolve"); + return NVRDataModel.getMonitors(0); + } + + }, + cache: false, + url: "/montage-history", + templateUrl: "templates/montage-history.html", + controller: 'zmApp.MontageHistoryCtrl', + params: { + minimal: false, + isRefresh: false + }, + + }) + + .state('montage', { + data: { + requireLogin: true + }, + resolve: { + message: function (NVRDataModel) { + //console.log("Inside app.events resolve"); + return NVRDataModel.getMonitors(0); + } + + }, + url: "/montage", + cache: false, + templateUrl: "templates/montage.html", + controller: 'zmApp.MontageCtrl', + params: { + minimal: false, + isRefresh: false + }, + + }); - // We are NOT going to default route. Routing to a view will start on - // a broadcast of "init-complete" + // We are NOT going to default route. Routing to a view will start on + // a broadcast of "init-complete" -}); //config + }); //config
\ No newline at end of file |
