summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorARC <arjunrc@gmail.com>2015-04-25 15:11:33 -0400
committerARC <arjunrc@gmail.com>2015-04-25 15:11:33 -0400
commit18b05289d8042b602054a46a8b7f78667e15a1df (patch)
treecf80d1183b5f12e35ebd15158e3d947041584519
parentcd467c329d6c7f97b549bad965f69f95a8b487af (diff)
Comments added
-rw-r--r--www/index.html107
-rw-r--r--www/js/DataModel.js167
-rw-r--r--www/js/EventCtrl.js18
-rw-r--r--www/js/EventsGraphsCtrl.js125
-rw-r--r--www/js/HttpFactory.js4
-rw-r--r--www/js/MonitorCtrl.js4
-rw-r--r--www/js/MontageCtrl.js23
-rw-r--r--www/js/app.js112
-rw-r--r--www/templates/events-graphs.html32
-rw-r--r--www/templates/events.html96
-rw-r--r--www/templates/montage.html17
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}} &nbsp;
- <i class="ion-ios-bell-outline"></i> {{event.Event.AlarmFrames}} &nbsp;
- <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}} &nbsp;
+ <i class="ion-ios-bell-outline"></i> {{event.Event.AlarmFrames}} &nbsp;
+ <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>&nbsp;{{event.Event.StartTime}}
- <br/>
- <i class="ion-clipboard"></i>&nbsp; {{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>&nbsp;{{event.Event.StartTime}}
+ <br/>
+ <i class="ion-clipboard"></i>&nbsp; {{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">&nbsp;<i class="ion-monitor"></i> {{monitor.Monitor.Name}}&nbsp;</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&amp;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>