diff options
| -rw-r--r-- | www/index.html | 107 | ||||
| -rw-r--r-- | www/js/DataModel.js | 167 | ||||
| -rw-r--r-- | www/js/EventCtrl.js | 18 | ||||
| -rw-r--r-- | www/js/EventsGraphsCtrl.js | 125 | ||||
| -rw-r--r-- | www/js/HttpFactory.js | 4 | ||||
| -rw-r--r-- | www/js/MonitorCtrl.js | 4 | ||||
| -rw-r--r-- | www/js/MontageCtrl.js | 23 | ||||
| -rw-r--r-- | www/js/app.js | 112 | ||||
| -rw-r--r-- | www/templates/events-graphs.html | 32 | ||||
| -rw-r--r-- | www/templates/events.html | 96 | ||||
| -rw-r--r-- | www/templates/montage.html | 17 |
11 files changed, 383 insertions, 322 deletions
diff --git a/www/index.html b/www/index.html index d93da40a..30f5225e 100644 --- a/www/index.html +++ b/www/index.html @@ -1,13 +1,14 @@ <!DOCTYPE html> <html> - <head> + +<head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title></title> <link href="lib/ionic/css/ionic.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> - <link href="lib/nvd3/nv.d3.min.css" rel="stylesheet"> + <link href="lib/nvd3/nv.d3.min.css" rel="stylesheet"> <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above <link href="css/ionic.app.css" rel="stylesheet"> @@ -15,47 +16,44 @@ <!-- ionic/angularjs js --> - <script src="lib/ionic/js/ionic.bundle.js"></script> + <script src="lib/ionic/js/ionic.bundle.js"></script> <!-- cordova script (this will be a 404 during development) --> <script src="cordova.js"></script> <!-- your app's js --> - + <script src="js/app.js"></script> <script src="js/controllers.js"></script> - - - <!-- <script src="js/CentralObjectModel.js"></script> --> - <script src="js/DataModel.js"></script> - <!-- <script src="js/HttpFactory.js"></script> --> + + <script src="js/DataModel.js"></script> <script src="js/LoginCtrl.js"></script> - + <script src="js/MontageCtrl.js"></script> <script src="js/EventCtrl.js"></script> <script src="js/EventsGraphsCtrl.js"></script> <script src="js/MonitorCtrl.js"></script> - - <!-- <script src="lib/Chart.js/Chart.js"></script>--> - <!-- <script src="lib/angular/angular.min.js"></script> --> - <script src="lib/angular-google-chart/ng-google-chart.js"></script> - - -<!-- -<script src="lib/tc-angular-chartjs/dist/tc-angular-chartjs.js"></script> -<script src="lib/angular-charts/dist/angular-charts.min.js"></script>--> - - - - - - </head> - - - <!-- <body ng-app="starter" > --> - <body> - <ion-side-menus> + + <script src="lib/angular-google-chart/ng-google-chart.js"></script> + + +</head> + + +<!-- <body ng-app="starter" > --> +<!-- I want to start angular only after cordova device is ready, so I'll tag it on device ready --> + +<body> + + <!-- For some reason - which I haven't debugged yet, when I was using the ionic side menu template + I was having problems with tabs/sliders in views, I think its to do with controls being alive in + the menu. this approach puts controls in each page and that works well, except that it looks lie + parts of this body are rendered upon index.html load result in a few odd icons before angular kicks + in. I'll eventually get to fixing this --> + + <!-- This is the Side menu options --> + <ion-side-menus> <ion-pane ion-side-menu-content> <ion-nav-bar class="bar-stable nav-title-slide-ios7"> <ion-nav-back-button class="button-icon"><span class="icon ion-ios7-arrow-left"></span> @@ -65,7 +63,9 @@ </ion-pane> <ion-side-menu side="left"> - <ion-header-bar class="bar bar-header bar-dark"><h1 class="title">Options</h1></ion-header-bar> + <ion-header-bar class="bar bar-header bar-dark"> + <h1 class="title">Options</h1> + </ion-header-bar> <ion-content has-header="true"> <ion-list> <ion-item href="#/monitors" menu-close><span class=" item-icon-left"> @@ -75,40 +75,39 @@ <i class="icon ion-ios-eye"></i> </span>View</ion-item> - + <ion-item href="#/events/0" menu-close><span class=" item-icon-left"> <i class="icon ion-ios-calendar-outline"></i> </span>Events</ion-item> - - <!-- <ion-item href="#/events-graphs" menu-close>Graphs</ion-item> --> - -<ion-item nav-clear menu-close href="#/login"> - <span class=" item-icon-left"> + + <!-- <ion-item href="#/events-graphs" menu-close>Graphs</ion-item> --> + + <ion-item nav-clear menu-close href="#/login"> + <span class=" item-icon-left"> <i class="icon ion-ios-gear-outline"></i> - </span> - Settings - </ion-item> - + </span> Settings + </ion-item> + </ion-list> </ion-content> </ion-side-menu> </ion-side-menus> - - - - + + + + <!-- This is where is bootstrap angular - if I don't do this, then the window jumps around + after the status bar comes on - because the window kicked in before phonegap got ready --> + <script> - - window.ionic.Platform.ready(function() - { - console.log ("******* PLATFORM READY ****"); - angular.bootstrap(document, ['zmApp']); + window.ionic.Platform.ready(function () { + console.log("******* PLATFORM READY ****"); + angular.bootstrap(document, ['zmApp']); }); - </script> - - - </body> + + +</body> + </html> diff --git a/www/js/DataModel.js b/www/js/DataModel.js index cd5e411f..3935de06 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -1,56 +1,67 @@ +// This is my central data respository and common functions +// that many other controllers use +// It's grown over time. I guess I may have to split this into multiple services in the future + angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ionicLoading', function ($http, $q, $ionicLoading) { // var deferred=''; var monitorsLoaded = 0; var simulationMode = 0; // make 1 for simulation - var simSize = 30; + var simSize = 30; // how many monitors to simulate var montageSize = 3; var monitors = []; var oldevents = []; var loginData = { 'username': '', 'password': '', - 'url': '', - 'apiurl': '' + 'url': '', // This is ZM portal API (Don't add /zm) + 'apiurl': '' // This is the API path + }; + + // This is really a test mode. This is how I am validating + // how my app behaves if you have many monitors. If you set simulationMode above to 1 + // then this is the function that getMonitors and getEvents (not yet) calls + + var simulation = { + fillSimulatedMonitors: function (cnt) { + var simmonitors = []; + console.log("*** Returning " + cnt + " simulated monitors"); + for (var i = 0; i < cnt; i++) { + + + simmonitors.push({ + "Monitor": { + // Obviously this is dummy data + "Id": i.toString(), + "Name": "Monitor Simulation " + i.toString(), + "Type": "Remote", + "Function": "Modect", + "Enabled": "1", + "Width": "1280", + "Height": "960", + "Colours": "4", + "MaxFPS": "10.00", + "AlarmMaxFPS": "10.00", + "AlarmFrameCount": "10.00" + } + }); + + } + // console.log ("Simulated: "+JSON.stringify(simmonitors)); + return simmonitors; + }, }; - //greeas - - var simulation = - { - fillSimulatedMonitors: function(cnt) - { - var simmonitors = []; - console.log ("*** Returning "+cnt+" simulated monitors"); - for (var i=0; i < cnt; i++) - { - - - simmonitors.push( - { - "Monitor": - { - "Id":i.toString(), - "Name":"Monitor Simulation "+i.toString(), - "Type":"Remote", - "Function":"Modect", - "Enabled":"1", - "Width":"1280", - "Height":"960", - "Colours":"4", - "MaxFPS":"10.00", - "AlarmMaxFPS":"10.00", - "AlarmFrameCount":"10.00" - } - } - ); - - } - console.log ("Simulated: "+JSON.stringify(simmonitors)); - return simmonitors; - }, - }; return { + // This function is called when the app is ready to run + // sets up various variables + // including persistent login data for the ZM apis and portal + // The reason I need both is because as of today, there is no way + // to access images using the API and they are authenticated via + // the ZM portal authentication, which is pretty messy. But unless + // the ZM authors fix this and streamline the access of images + // from APIs, I don't have an option + init: function () { console.log("****** DATAMODEL INIT SERVICE CALLED ********"); var montageSize = 2; @@ -71,7 +82,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion window.localStorage.getItem("url"); } - + if (window.localStorage.getItem("apiurl") != undefined) { loginData.apiurl = window.localStorage.getItem("apiurl"); @@ -82,9 +93,9 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion console.log("Getting out of ZMDataModel init"); }, - - - + + + getLogin: function () { return loginData; }, @@ -97,17 +108,26 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion }, + // This function returns a list of monitors + // if forceReload == 1 then it will force an HTTP API request to get a list of monitors + // if 0. then it will return back the previously loaded monitor list if one exists, else + // will issue a new HTTP API to get it + + // I've wrapped this function in my own promise even though http returns a promise. This is because + // depending on forceReload and simulation mode, http may or may not be called. So I'm promisifying + // the non http stuff too to keep it consistent to the calling function. + getMonitors: function (forceReload) { console.log("** Inside ZMData getMonitors with forceReload=" + forceReload); var d = $q.defer(); - if (((monitorsLoaded == 0) || (forceReload == 1)) && (simulationMode !=1) ) // monitors are empty or force reload + if (((monitorsLoaded == 0) || (forceReload == 1)) && (simulationMode != 1)) // monitors are empty or force reload { - console.log("ZMDataModel: Invoking HTTP Factory to load monitors"); + console.log("ZMDataModel: Invoking HTTP get to load monitors"); var apiurl = loginData.apiurl; var myurl = apiurl + "/monitors.json"; $http.get(myurl) .success(function (data) { - console.log ("HTTP success got " + JSON.stringify(data.monitors)); + console.log("HTTP success got " + JSON.stringify(data.monitors)); monitors = data.monitors; console.log("promise resolved inside HTTP success"); monitorsLoaded = 1; @@ -115,6 +135,8 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion }) .error(function (err) { console.log("HTTP Error " + err); + // To keep it simple for now, I'm translating an error + // to imply no monitors could be loaded. FIXME: conver to proper error monitors = []; console.log("promise resolved inside HTTP fail"); d.resolve(monitors); @@ -123,8 +145,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion } else // monitors are loaded { - if (simulationMode == 1) - { + if (simulationMode == 1) { monitors = simulation.fillSimulatedMonitors(simSize); //fillSimulatedMonitors } @@ -138,14 +159,18 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion console.log("ZMData setMonitors called with " + mon.length + " monitors"); monitors = mon; }, - - getAllPreexistingEvents: function() - { - console.log ("returning "+oldevents.length+" preexisting events"); + // Not sure if I am using this anymore. I was using this for graphs, but I + // don't think I am now + getAllPreexistingEvents: function () { + console.log("returning " + oldevents.length + " preexisting events"); return oldevents; }, - - + + // This function returns events for specific monitor or all monitors + // You get here by tapping on events in the monitor screen or from + // the menu events option + // monitorId == 0 means all monitors (ZM starts from 1) + getEvents: function (monitorId) { $ionicLoading.show({ @@ -156,18 +181,20 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion showDelay: 0 }); - console.log("ZMData getEvents called with ID="+monitorId); + console.log("ZMData getEvents called with ID=" + monitorId); var d = $q.defer(); var myevents = []; var apiurl = loginData.apiurl; - var myurl = (monitorId == 0) ? apiurl + "/events.json" : apiurl + "/events/index/MonitorId:"+monitorId+".json"; - console.log ("Constructed URL is " + myurl); + var myurl = (monitorId == 0) ? apiurl + "/events.json" : apiurl + "/events/index/MonitorId:" + monitorId + ".json"; + console.log("Constructed URL is " + myurl); + // FIXME: When retrieving lots of events, I really need to do pagination here - more complex + // as I have to do that in list scrolling too. For now, I hope your events don't kill the phone + // memory $http.get(myurl) .success(function (data) { $ionicLoading.hide(); myevents = data.events.reverse(); - if (monitorId == 0) - { + if (monitorId == 0) { oldevents = myevents; } //console.log (JSON.stringify(data)); @@ -180,11 +207,11 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion $ionicLoading.hide(); console.log("HTTP Events error " + err); d.resolve(myevents); - if (monitorId ==0) - { + if (monitorId == 0) { + // FIXME: make this into a proper error oldevents = []; } - return d.promise; + return d.promise; }) return d.promise; @@ -211,15 +238,11 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion monitorsLoaded = loaded; }, + // Given a monitor Id it returns the monitor name + // FIXME: Can I do a better job with associative arrays? getMonitorName: function (id) { var idnum = parseInt(id); - // console.log ("I have " + monitors.length + " monitors to match"); - - //console.log (JSON.stringify(monitors)); for (var i = 0; i < monitors.length; i++) { - // console.log ("Searching for:"+idnum+"& got:"+monitors[i].Monitor.Id); - //console.log ("Searching for monitors id:"+monitors[i].Mo - // console.log ("Iteration #"+i+" " +monitors[i].Monitor.Id + " " + monitors[i].Monitor.Name); if (parseInt(monitors[i].Monitor.Id) == idnum) { // console.log ("Matched, exiting getMonitorname"); return monitors[i].Monitor.Name; @@ -228,8 +251,8 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion } return "(Unknown)"; }, - - - + + + }; -}]);
\ No newline at end of file +}]); diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 8c0ea8ba..69fd0222 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,3 +1,7 @@ +// This is the controller for Event view. StateParams is if I recall the monitor ID. +// This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it +// and whether the new API has a better mechanism + angular.module('zmApp.controllers').controller('zmApp.EventCtrl', function ($ionicPlatform, $scope, $stateParams, message, ZMDataModel,$ionicSideMenuDelegate) { console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id,10); @@ -20,13 +24,10 @@ $scope.openMenu = function () { myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); } - //for (var i = 0; i< myevents.length; i++) - // { - // console.log ("I got Name as " + myevents[i].Event.MonitorName); - // } + $scope.events = myevents; }); - //ZMDataModel.getEvents(); + $scope.doRefresh = function () { @@ -42,13 +43,10 @@ $scope.openMenu = function () { myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); } - //for (var i = 0; i< myevents.length; i++) - // { - // console.log ("I got Name as " + myevents[i].Event.MonitorName); - // } + $scope.events = myevents; $scope.$broadcast('scroll.refreshComplete'); }); }; //dorefresh -});
\ No newline at end of file +}); diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js index 9dbf3efb..92cd525e 100644 --- a/www/js/EventsGraphsCtrl.js +++ b/www/js/EventsGraphsCtrl.js @@ -1,10 +1,14 @@ +// This controller generates a graph for events +// the main function is generateChart. I call generate chart with required parameters +// from the template file + angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', function ($ionicPlatform, $scope, ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http) { - console.log("Inside Graphs controller"); + console.log("Inside Graphs controller"); $scope.openMenu = function () { $ionicSideMenuDelegate.toggleLeft(); } - $scope.navTitle = 'Tab Page'; + $scope.navTitle = 'Tab Page'; $scope.leftButtons = [{ type: 'button-icon icon ion-navicon', tap: function (e) { @@ -12,80 +16,81 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', functio } }]; - $scope.generateChart = function(chartTitle) - { - //alert ("Well I got called!"); - $scope.chartObject = {}; //test - $scope.chartObject.data = [ + $scope.generateChart = function (chartTitle) { + + $scope.chartObject = {}; + $scope.chartObject.data = [ ['Monitor', 'Events', { - role: 'style' + role: 'style' }, { - role: 'annotation' + role: 'annotation' }], ['', 0, '', ''] // needed to get rid of the initial error of charts + // FIXME: does it really work? I noticed the red warning + // coming up on the device ]; - $scope.chartObject.type = "BarChart"; - $scope.chartObject.options = { - title: chartTitle, - height: $rootScope.devHeight, - animation: { - duration: 700, - easing: 'out', - startup: 'false', - }, + $scope.chartObject.type = "BarChart"; + $scope.chartObject.options = { + title: chartTitle, + height: $rootScope.devHeight, // FIXME: I need to make this dynamic depending on + // # of bars + legend: 'none', + animation: { + duration: 700, + easing: 'out', + startup: 'false', + }, - } - - var monitors = []; - console.log("*** Grabbing lists of events and monitors "); - ZMDataModel.getMonitors(0).then(function (data) { + } - monitors = data; + var monitors = []; var loginData = ZMDataModel.getLogin(); - //var events = ZMDataModel.getAllPreexistingEvents(); - // lets get the event count for all - for (var i = 0; i < monitors.length; i++) { - (function (j) { - //monevents[monitors[j].Monitor.Id].monName = monitors[j].Monitor.Name; - - var url = loginData.apiurl + - "/events/index/MonitorId:" + monitors[j].Monitor.Id + - ".json?page=1"; - console.log("Monitor event URL:" + url); - $http.get(url) - .success(function (data) { - console.log("**** EVENT COUNT FOR MONITOR " + - monitors[j].Monitor.Id + " IS " + data.pagination.count); - - console.log("Pushing " + monitors[j].Monitor.Name + - " AND " + data.pagination.count); - - $scope.chartObject.data.push - ([monitors[j].Monitor.Name, data.pagination.count, - 'opacity: 0.4', data.pagination.count]); - - }) - .error(function (data) { - console.log("**** EVENT COUNT FOR MONITOR " + - monitors[i].Monitor.Id + " IS ERROR "); - $scope.chartObject.data.push([monitors[j].Monitor.Name, + console.log("*** Grabbing lists of events and monitors "); + ZMDataModel.getMonitors(0).then(function (data) { + + monitors = data; + + for (var i = 0; i < monitors.length; i++) { + (function (j) { // loop closure - http is async, so success returns after i goes out of scope + // so we need to bind j to i when http returns so its not out of scope. Gak. + // I much prefer the old days of passing context data from request to response + + var url = loginData.apiurl + + "/events/index/MonitorId:" + monitors[j].Monitor.Id + // FIXME: need to add hr/week + ".json?page=1"; + console.log("Monitor event URL:" + url); + $http.get(url) + .success(function (data) { + console.log("**** EVENT COUNT FOR MONITOR " + + monitors[j].Monitor.Id + " IS " + data.pagination.count); + + console.log("Pushing " + monitors[j].Monitor.Name + + " AND " + data.pagination.count); + + $scope.chartObject.data.push([monitors[j].Monitor.Name, data.pagination.count, + 'opacity: 0.4', data.pagination.count]); + + }) + .error(function (data) { + // ideally I should be treating it as an error + // but what I am really doing now is treating it like no events + // works but TBD: make this into a proper error handler + console.log("**** EVENT COUNT FOR MONITOR " + + monitors[i].Monitor.Id + " IS ERROR "); + $scope.chartObject.data.push([monitors[j].Monitor.Name, 0, 'opacity: 0.4', 0]); - - }); - })(i); // j - - } //for - - }); - - }; // scope function + }); + })(i); // j + } //for + }); + }; // scope function }); diff --git a/www/js/HttpFactory.js b/www/js/HttpFactory.js index c11daba1..b869e809 100644 --- a/www/js/HttpFactory.js +++ b/www/js/HttpFactory.js @@ -1,3 +1,5 @@ +// NOT USED ANYMORE. FIXME: DELETE THIS FILE + angular.module('zmApp.controllers').factory('ZMHttpFactory', ['$http', '$rootScope','$ionicLoading', '$ionicPopup','$timeout' function($http, $rootScope, $ionicLoading, $ionicPopup, $timeout) { @@ -91,4 +93,4 @@ angular.module('zmApp.controllers').factory('ZMHttpFactory', ['$http', '$rootSco }, //getEvents } } -]);
\ No newline at end of file +]); diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js index 300f5538..2db85aa5 100644 --- a/www/js/MonitorCtrl.js +++ b/www/js/MonitorCtrl.js @@ -1,3 +1,5 @@ +// controller for Monitor View + angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', function ($scope, ZMDataModel, message,$ionicSideMenuDelegate) { $scope.monitors = []; @@ -25,4 +27,4 @@ $scope.openMenu = function () { }; -});
\ No newline at end of file +}); diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index 115bd513..8a189dfb 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -1,3 +1,5 @@ +// Controller for the montage view + angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', function ($scope, $rootScope, ZMDataModel, message,$ionicSideMenuDelegate) { @@ -8,24 +10,26 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', function ($s //var monsize =3; console.log("********* Inside Montage Ctrl"); $scope.LoginData = ZMDataModel.getLogin(); + + // slider is tied to the view slider for montage + //Remember not to use a variable. I'm using an object + // so it's passed as a reference - otherwise it makes + // a copy and the value never changes $scope.slider = {}; $scope.slider.monsize = ZMDataModel.getMontageSize(); $scope.$on('$ionicView.afterEnter', function () { + // This rand is really used to reload the monitor image in img-src so it is not cached + // I am making sure the image in montage view is always fresh $rootScope.rand = Math.floor((Math.random() * 100000) + 1); - //console.log("*********IN VIEW, generated " + $rootScope.rand); - console.log("Rootscoxxpe Montage is " + ZMDataModel.getMontageSize() + " and slider montage is " + $scope.slider.monsize); }); - - - $scope.$watch('slider.monsize', function () { console.log('Slider has changed'); ZMDataModel.setMontageSize($scope.slider.monsize); console.log("Rootscope Montage is " + ZMDataModel.getMontageSize() + " and slider montage is " + $scope.slider.monsize); - //$rootScope.montageSize = $scope.slider.monsize; + }); $scope.monitors = []; @@ -33,11 +37,6 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', function ($s $scope.monitors = message; console.log("I have received the monitors inside Montage and there are " + $scope.monitors.length); - // console.log("***CALLING FACTORY"); - //ZMHttpFactory.getMonitors().then(function(data) //{ - // $scope.monitors = data; - // console.log("I GOT " + $scope.monitors); - // }); $scope.doRefresh = function () { console.log("***Pull to Refresh"); @@ -50,4 +49,4 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', function ($s }); }; -});
\ No newline at end of file +}); diff --git a/www/js/app.js b/www/js/app.js index a5f58a6b..d6d1012b 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -1,4 +1,3 @@ - // core app start stuff angular.module('zmApp', [ 'ionic', @@ -17,14 +16,20 @@ angular.module('zmApp', [ } - window.onorientationchange = function() { - console.log ("**ORIENTATION CHANGE**"); + // This routine is called whenever the orientation changes + // so I can recompute my width and height. I use them + // for scoping graphs as well as figuring out how many thumbnails + // to show for montages + window.onorientationchange = function () { + console.log("**ORIENTATION CHANGE**"); var pixelRatio = window.devicePixelRatio || 1; $rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width); $rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height); - console.log("********Computed Dev Width & Height as" + $rootScope.devWidth+"*"+$rootScope.devHeight); + console.log("********Computed Dev Width & Height as" + $rootScope.devWidth + "*" + $rootScope.devHeight); } - + + // This is a skeleton for now. Eventually I am going to prohibit + // certain views to load unless you've logged in $rootScope.$on('$stateChangeStart', function (event, toState, toParams) { // console.log ("***** STATE CHANGE CHECK ****"); var requireLogin = toState.data.requireLogin; @@ -43,9 +48,14 @@ angular.module('zmApp', [ var pixelRatio = window.devicePixelRatio || 1; $rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width); $rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height); - - console.log("********Computed Dev Width & Height as" + $rootScope.devWidth+"*"+$rootScope.devHeight); + console.log("********Computed Dev Width & Height as" + $rootScope.devWidth + "*" + $rootScope.devHeight); + + // What I noticed is when I moved the app to the device + // the montage screens were not redrawn after resuming from background mode + // Everything was fine if I switched back to the montage screen + // so as a global hack I'm just reloading the current state if you switch + // from foreground to background and back document.addEventListener("resume", function () { console.log("****The application is resuming from the background"); $rootScope.rand = Math.floor((Math.random() * 100000) + 1); @@ -68,13 +78,13 @@ angular.module('zmApp', [ }); }) - +// My route map connecting menu options to their respective templates and controllers .config(function ($stateProvider, $urlRouterProvider) { $stateProvider - /*.state('app', { + /*.state('app', { data: { requireLogin: false }, @@ -86,15 +96,15 @@ angular.module('zmApp', [ })*/ - .state('login', { + .state('login', { data: { requireLogin: false }, url: "/login", templateUrl: "templates/login.html", controller: 'zmApp.LoginCtrl', - - + + }) .state('monitors', { @@ -112,56 +122,54 @@ angular.module('zmApp', [ controller: 'zmApp.MonitorCtrl', }) - - - + .state('events', { - data: { - requireLogin: false - }, - resolve: { - message: function (ZMDataModel) { - console.log("Inside app.events resolve"); - return ZMDataModel.getMonitors(0); - } - }, - url: "/events/:id", - templateUrl: "templates/events.html", - controller: 'zmApp.EventCtrl', - - }) - -//n + data: { + requireLogin: false + }, + resolve: { + message: function (ZMDataModel) { + console.log("Inside app.events resolve"); + return ZMDataModel.getMonitors(0); + } + }, + url: "/events/:id", + templateUrl: "templates/events.html", + controller: 'zmApp.EventCtrl', + + }) + + //n .state('events-graphs', { - data: { - requireLogin: false - }, - url: "/events-graphs", - templateUrl: "templates/events-graphs.html", - controller: 'zmApp.EventsGraphsCtrl', - }) - - + data: { + requireLogin: false + }, + url: "/events-graphs", + templateUrl: "templates/events-graphs.html", + controller: 'zmApp.EventsGraphsCtrl', + }) + + .state('montage', { data: { requireLogin: false - }, - resolve: { - message: function (ZMDataModel) { - console.log("Inside app.montage resolve"); - return ZMDataModel.getMonitors(0); - } - }, - url: "/montage", - templateUrl: "templates/montage.html", - controller: 'zmApp.MontageCtrl', + }, + resolve: { + message: function (ZMDataModel) { + console.log("Inside app.montage resolve"); + return ZMDataModel.getMonitors(0); + } + }, + url: "/montage", + templateUrl: "templates/montage.html", + controller: 'zmApp.MontageCtrl', -}); + }); // if none of the above states are matched, use this as the fallback var defaultState = "/monitors"; //var defaultState = "/app/montage"; $urlRouterProvider.otherwise(defaultState); -});
\ No newline at end of file +}); diff --git a/www/templates/events-graphs.html b/www/templates/events-graphs.html index 2c1ce641..1571cdf3 100644 --- a/www/templates/events-graphs.html +++ b/www/templates/events-graphs.html @@ -3,8 +3,11 @@ <ion-nav-buttons side="left"> <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> </ion-nav-buttons> + + <!-- I'm calling the same controller function but with different parameters when + you switch between tabs --> <ion-tabs class="tabs-icon-top tabs-stable"> - <ion-tab title="All Events" icon="ion-stats-bars" on-select="generateChart('All Events')"> + <ion-tab title="All" icon="ion-stats-bars" on-select="generateChart('All Events')"> <ion-nav-view> <ion-content class="has-header"> @@ -15,7 +18,19 @@ </ion-nav-view> </ion-tab> - <ion-tab title="Events in last hour" icon="ion-stats-bars" on-select="generateChart('Events in the last hour')"> + <ion-tab title="Last Hour" icon="ion-stats-bars" on-select="generateChart('Events in the last hour')"> + <ion-nav-view> + + <ion-content> + <span></span> + <div google-chart chart="chartObject"></div> + + + </ion-content> + </ion-nav-view> + </ion-tab> + + <ion-tab title="Day" icon="ion-stats-bars" on-select="generateChart('Events in the last day')"> <ion-nav-view> <ion-content> @@ -26,13 +41,18 @@ </ion-content> </ion-nav-view> </ion-tab> + <ion-tab title="Week" icon="ion-stats-bars" on-select="generateChart('Events in the last week')"> + <ion-nav-view> + + <ion-content> + <span></span> + <div google-chart chart="chartObject"></div> - <ion-tab title="Settings" icon="ion-ios-information"> - <ion-content> - Tab 3 - </ion-content> + </ion-content> + </ion-nav-view> </ion-tab> + </ion-tabs> <!-- diff --git a/www/templates/events.html b/www/templates/events.html index 90d79498..bf721499 100644 --- a/www/templates/events.html +++ b/www/templates/events.html @@ -1,11 +1,11 @@ <ion-view view-title="Events" cache-view="false"> - - <ion-nav-buttons side="left"> - <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> - </ion-nav-buttons> - - <ion-nav-buttons side="right"> - <a style="" class="button button-icon icon ion-stats-bars" ng-href="#events-graphs"> </a> + + <ion-nav-buttons side="left"> + <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> + </ion-nav-buttons> + + <ion-nav-buttons side="right"> + <a style="" class="button button-icon icon ion-stats-bars" ng-href="#events-graphs"> </a> <!--<a ui-sref="app.events-graphs" class="item" ng-click="toggleMenu()">Tabs</a>--> </ion-nav-buttons> @@ -14,59 +14,61 @@ <ion-refresher pulling-text="Pull to reload Events..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher> <ion-list> <div ng-repeat="event in events"> - - <ion-item> - <div class="row"> - <div class="col col-left"> - <div ng-switch on="event.Event.Cause"> - <div ng-switch-when="Motion"> - <i class="ion-android-walk" style="float:left; font-size:200%;"></i> - <br/> - </div> - <div ng-switch-when="Signal"> - <i class="ion-wifi" style="float:left; font-size:200%;"></i> - <br/> - </div> - <div ng-switch-default> - <i class="ion-ionic" style="float:left; font-size:200%;"></i> - <br/> - </div> - </div> - <!-- ng switch --> - <!-- {{event.Event.Cause}} --> + <ion-item> - <br/> <span style="font-size:80%; color:rgb(110,110,110)">{{event.Event.Length}}s</span> + <div class="row"> + <div class="col col-left"> + <!-- this ngswitch displays different icons + depending on the cause of the event --> + <div ng-switch on="event.Event.Cause"> + <div ng-switch-when="Motion"> + <i class="ion-android-walk" style="float:left; font-size:200%;"></i> + <br/> + </div> + <div ng-switch-when="Signal"> + <i class="ion-wifi" style="float:left; font-size:200%;"></i> + <br/> + </div> + <div ng-switch-default> + <i class="ion-ionic" style="float:left; font-size:200%;"></i> + <br/> + </div> </div> - <!-- col col left--> + <!-- ng switch --> + <!-- {{event.Event.Cause}} --> - <div class="col col-80"> - <div class="item-text-wrap"><i class="ion-monitor"></i> <b>{{event.Event.MonitorName}}</b> ({{event.Event.Name}})</div> + <br/> <span style="font-size:80%; color:rgb(110,110,110)">{{event.Event.Length}}s</span> + </div> + <!-- col col left--> - <i class="ion-images"></i> {{event.Event.Frames}} - <i class="ion-ios-bell-outline"></i> {{event.Event.AlarmFrames}} - <i class="ion-arrow-graph-up-right"></i> {{event.Event.TotScore}} - <br/> - </div> + <div class="col col-80"> + <div class="item-text-wrap"><i class="ion-monitor"></i> <b>{{event.Event.MonitorName}}</b> ({{event.Event.Name}})</div> + + <i class="ion-images"></i> {{event.Event.Frames}} + <i class="ion-ios-bell-outline"></i> {{event.Event.AlarmFrames}} + <i class="ion-arrow-graph-up-right"></i> {{event.Event.TotScore}} + <br/> + </div> - <!--<div class="col"> + <!--<div class="col"> <img ng-src="{{event.image}}" style="float:right; height:40px;" /> </div> --> - </div> + </div> - <div class="row" style="font-size:80%; color:rgb(110,110,110)"> - <div class="item-text-wrap"><i class="ion-calendar"></i> {{event.Event.StartTime}} - <br/> - <i class="ion-clipboard"></i> {{event.Event.Notes}} - <br/> - </div> + <div class="row" style="font-size:80%; color:rgb(110,110,110)"> + <div class="item-text-wrap"><i class="ion-calendar"></i> {{event.Event.StartTime}} + <br/> + <i class="ion-clipboard"></i> {{event.Event.Notes}} + <br/> </div> + </div> + + </ion-item> - </ion-item> - </div> </ion-list> </ion-content> -</ion-view>
\ No newline at end of file +</ion-view> diff --git a/www/templates/montage.html b/www/templates/montage.html index 6eab4f58..3ef1885b 100644 --- a/www/templates/montage.html +++ b/www/templates/montage.html @@ -1,10 +1,10 @@ <ion-view title="Montage View" class="bar-stable" cache-view="false"> -<ion-nav-buttons side="left"> - <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> - </ion-nav-buttons> - + <ion-nav-buttons side="left"> + <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> + </ion-nav-buttons> + <ion-content padding="true"> - + <ion-refresher pulling-text="Pull to reload Monitors..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher> <!-- Hi:ROOT: {{montageSize}} LOCAL {{slider.monsize}} --> <div class=" range range-positive"> @@ -12,7 +12,7 @@ <input type="range" ng-model="slider.monsize" min="1" max="6"> <i class="icon ion-arrow-expand"></i> - + </div> <!-- Hi:{{slider.monsize}} {{devWidth}} --> <div class="wrapper"> @@ -22,6 +22,9 @@ <header class="header"> <i class="ion-monitor"></i> {{monitor.Monitor.Name}} </header> <article class="main"> + <!-- does not route via APIs. As of today, there is no way to do this via apis. + FIXME: I should probably not pass username and password here - instead go the http interceptor + and auth token mode --> <img ng-src="{{LoginData.url}}/cgi-bin/nph-zms?mode=jpeg&monitor={{monitor.Monitor.Id}}&scale=100&maxfps=3&buffer=1000&user={{LoginData.username}}&pass={{LoginData.password}}&rand={{rand}}" width="{{((devWidth-30)/(7-slider.monsize))}}px;" /> <!-- <br/><i class="ion-monitor"></i> Hello --> @@ -43,4 +46,4 @@ </div> </ion-content> -</ion-view>
\ No newline at end of file +</ion-view> |
