summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
authorPliablePixels <pliablepixels@gmail.com>2015-06-24 18:47:42 -0400
committerPliablePixels <pliablepixels@gmail.com>2015-06-24 18:47:42 -0400
commit855a0e8ddc273b58066530a1b55a946021dfc56e (patch)
tree26550033e855a31a265fc2da4da3df0cc2733dc1 /www
parentd442629aa825aab6bc55ab6be19e3aba060867fe (diff)
Cleaned up code, commented, preparing for HTTPS via CordovaHTTP
Diffstat (limited to 'www')
-rw-r--r--www/index.html72
-rw-r--r--www/js/DataModel.js56
-rw-r--r--www/js/DevOptionsCtrl.js45
-rw-r--r--www/js/EventCtrl.js196
-rw-r--r--www/js/EventsGraphsCtrl.js14
-rw-r--r--www/js/LoginCtrl.js40
-rw-r--r--www/js/ModalCtrl.js40
-rw-r--r--www/js/MonitorCtrl.js122
-rw-r--r--www/js/MonitorModalCtrl.js2
-rw-r--r--www/js/MontageCtrl.js239
-rw-r--r--www/js/StateCtrl.js55
-rw-r--r--www/js/app.js19
-rw-r--r--www/js/controllers.js1
-rw-r--r--www/templates/devoptions.html14
-rw-r--r--www/templates/events-graphs.html53
-rw-r--r--www/templates/events-modal.html22
-rw-r--r--www/templates/events.html2
-rw-r--r--www/templates/login.html7
18 files changed, 531 insertions, 468 deletions
diff --git a/www/index.html b/www/index.html
index a4a2d47b..1db134e8 100644
--- a/www/index.html
+++ b/www/index.html
@@ -4,15 +4,15 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
- <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.google.com 'unsafe-inline' 'unsafe-eval'">
+ <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.google.com 'unsafe-inline' 'unsafe-eval'">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href="lib/ng-mfb/mfb/src/mfb.css" rel="stylesheet">
- <link rel="stylesheet" href="lib/angular-circular-navigation/angular-circular-navigation.css">
- <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.min.css">
+ <link rel="stylesheet" href="lib/angular-circular-navigation/angular-circular-navigation.css">
+ <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.min.css">
@@ -26,7 +26,7 @@
<!-- we need the full JQuery for the global img src
error interceptor in app.js -->
- <script src="lib/ionic/js/ionic.bundle.min.js"></script>
+ <script src="lib/ionic/js/ionic.bundle.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
@@ -40,17 +40,17 @@
<script src="js/DataModel.js"></script>
<script src="js/LoginCtrl.js"></script>
- <script src="js/ModalCtrl.js"></script>
+ <script src="js/ModalCtrl.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="js/HelpCtrl.js"></script>
<script src="js/StateCtrl.js"></script>
- <script src="js/DevOptionsCtrl.js"></script>
+ <script src="js/DevOptionsCtrl.js"></script>
-<script src="lib/angular-circular-navigation/angular-circular-navigation.js"></script>
+ <script src="lib/angular-circular-navigation/angular-circular-navigation.js"></script>
<script src="lib/Chart.js/Chart.js"></script>
<script src="lib/tc-angular-chartjs/dist/tc-angular-chartjs.min.js"></script>
@@ -76,7 +76,8 @@
<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>
+ <ion-nav-back-button class="button-icon">
+ <span class="icon ion-ios7-arrow-left"></span>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
@@ -88,46 +89,53 @@
</ion-header-bar>
<ion-content has-header="true">
<ion-list>
- <ion-item href="#/monitors" menu-close><span class=" item-icon-left">
- <i class="icon ion-ios-monitor-outline"></i>
- </span>Monitors</ion-item>
- <ion-item href="#/montage" menu-close><span class=" item-icon-left">
-
- <i class="icon ion-ios-eye"></i>
- </span>Montage 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="#/monitors" menu-close>
+ <span class=" item-icon-left">
+ <i class="icon ion-ios-monitor-outline"></i>
+ </span>Monitors
+ </ion-item>
- <ion-item href="#/state" menu-close><span class=" item-icon-left">
- <i class="icon ion-information-circled"></i>
- </span>System Status</ion-item>
+ <ion-item href="#/montage" menu-close>
+ <span class=" item-icon-left">
+ <i class="icon ion-ios-eye"></i>
+ </span>Montage View
+ </ion-item>
- <!-- <ion-item href="#/events-graphs" menu-close>Graphs</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="#/state" menu-close>
+ <span class=" item-icon-left">
+ <i class="icon ion-information-circled"></i>
+ </span>
+ System Status
+ </ion-item>
<ion-item nav-clear menu-close href="#/login">
<span class=" item-icon-left">
- <i class="icon ion-person"></i>
- </span> ZM Settings
+ <i class="icon ion-person"></i>
+ </span>
+ ZM Settings
</ion-item>
- <ion-item nav-clear menu-close href="#/devoptions">
+ <ion-item nav-clear menu-close href="#/devoptions">
<span class=" item-icon-left">
- <i class="icon ion-settings"></i>
- </span> Developer Settings
+ <i class="icon ion-settings"></i>
+ </span> Developer Settings
</ion-item>
<ion-item nav-clear menu-close href="#/help">
<span class=" item-icon-left">
- <i class="icon ion-help"></i>
- </span> Help
+ <i class="icon ion-help"></i>
+ </span> Help
</ion-item>
-
</ion-list>
</ion-content>
</ion-side-menu>
-
</ion-side-menus>
@@ -137,7 +145,7 @@
after the status bar comes on - because the window kicked in before phonegap got ready -->
<script>
- window.ionic.Platform.ready(function () {
+ window.ionic.Platform.ready(function() {
console.log("******* PLATFORM READY ****");
angular.bootstrap(document, ['zmApp']);
});
diff --git a/www/js/DataModel.js b/www/js/DataModel.js
index ec2deeb3..1c19948d 100644
--- a/www/js/DataModel.js
+++ b/www/js/DataModel.js
@@ -8,7 +8,7 @@
// 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', '$ionicBackdrop', function ($http, $q, $ionicLoading, $ionicBackdrop) {
- // var deferred='';
+
var monitorsLoaded = 0;
var montageSize = 3;
var monitors = [];
@@ -22,6 +22,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
'streamingurl': "",
'maxFPS': "3", // image streaming FPS
'montageQuality': "50", // montage streaming quality in %
+ 'useSSL':false // "1" if HTTPS
};
return {
@@ -37,7 +38,6 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
init: function () {
console.log("****** DATAMODEL INIT SERVICE CALLED ********");
- var montageSize = 2;
if (window.localStorage.getItem("username") != undefined) {
loginData.username =
@@ -96,7 +96,12 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
console.log("montageQuality " + loginData.montageQuality);
}
+ if (window.localStorage.getItem("useSSL") != undefined) {
+ var sslvalue = window.localStorage.getItem("useSSL");
+ loginData.useSSL = (sslvalue == "1") ? true:false;
+ console.log("useSSL " + loginData.useSSL);
+ }
monitorsLoaded = 0;
@@ -122,6 +127,10 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
window.localStorage.setItem("url", loginData.url);
window.localStorage.setItem("apiurl", loginData.apiurl);
window.localStorage.setItem("streamingurl", loginData.streamingurl);
+ window.localStorage.setItem("useSSL", loginData.useSSL?"1":"0");
+ window.localStorage.setItem("maxMontage", loginData.maxMontage);
+ window.localStorage.setItem("montageQuality", loginData.montageQuality);
+
if (loginData.maxFPS > 30) {
console.log("MAXFPS Too high, maxing to 30");
@@ -129,8 +138,6 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
}
window.localStorage.setItem("maxFPS", loginData.maxFPS);
-
-
if (!loginData.maxMontage) {
console.log("INVALID MONTAGE NUM");
loginData.maxMontage = "10";
@@ -140,21 +147,16 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
console.log("*** MAXMONTAGE TOO LOW ***");
loginData.maxMontage = 1;
}
-
-
- window.localStorage.setItem("maxMontage", loginData.maxMontage);
-
- window.localStorage.setItem("montageQuality", loginData.montageQuality);
-
-
},
+ //-----------------------------------------------------------------------------
// 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.
+ //-----------------------------------------------------------------------------
getMonitors: function (forceReload) {
console.log("** Inside ZMData getMonitors with forceReload=" + forceReload);
@@ -189,6 +191,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
console.log("promise resolved inside HTTP fail");
d.resolve(monitors);
$ionicLoading.hide();
+ monitorsLoaded = 0 ;
});
return d.promise;
@@ -201,22 +204,22 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
}
},
+
+ //-----------------------------------------------------------------------------
+ //
+ //-----------------------------------------------------------------------------
setMonitors: function (mon) {
console.log("ZMData setMonitors called with " + mon.length + " monitors");
monitors = mon;
},
- // 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;
- },
+ //-----------------------------------------------------------------------------
// When I display events in the event controller, this is the first function I call
// This returns the total number of pages
// I then proceed to display pages in reverse order to display the latest events first
// I also reverse sort them in ZMDataModel to sort by date
// All this effort because the ZM APIs return events in sorted order, oldest first. Yeesh.
+ //-----------------------------------------------------------------------------
getEventsPages: function (monitorId) {
console.log("********** INSIDE EVENTS PAGES ");
@@ -239,10 +242,12 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
},
+ //-----------------------------------------------------------------------------
// 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, pageId, loadingStr) {
@@ -263,7 +268,6 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
duration: 15000, //specifically for Android - http seems to get stuck at times
});
}
- //$ionicBackdrop.retain();
var d = $q.defer();
var myevents = [];
@@ -311,13 +315,23 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
return d.promise;
},
+ //-----------------------------------------------------------------------------
+ //
+ //-----------------------------------------------------------------------------
getMontageSize: function () {
return montageSize;
},
+
+ //-----------------------------------------------------------------------------
+ //
+ //-----------------------------------------------------------------------------
setMontageSize: function (montage) {
montageSize = montage;
},
+ //-----------------------------------------------------------------------------
+ //
+ //-----------------------------------------------------------------------------
getMonitorsLoaded: function () {
console.log("**** Inside promise function ");
var deferred = $q.defer();
@@ -327,13 +341,19 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion
return deferred.promise;
},
+
+ //-----------------------------------------------------------------------------
+ //
+ //-----------------------------------------------------------------------------
setMonitorsLoaded: function (loaded) {
console.log("ZMData.setMonitorsLoaded=" + loaded);
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);
for (var i = 0; i < monitors.length; i++) {
diff --git a/www/js/DevOptionsCtrl.js b/www/js/DevOptionsCtrl.js
index 7c9cfce7..f332bc50 100644
--- a/www/js/DevOptionsCtrl.js
+++ b/www/js/DevOptionsCtrl.js
@@ -3,41 +3,46 @@
/* global cordova,StatusBar,angular,console */
angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope', '$rootScope', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', function ($scope, $rootScope, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading) {
+
+
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
- $scope.loginData = ZMDataModel.getLogin();
+//------------------------------------------------------------------
+// Perform the login action when the user submits the login form
+//------------------------------------------------------------------
+ $scope.saveDevOptions = function () {
+ console.log('Saving Dev Options');
+ if (parseInt($scope.loginData.maxMontage) > 10) {
+ $ionicPopup.alert({
+ title: 'Note',
+ template: 'You have selected to view more than 10 monitors in the Montage screen. Note that this is very resource intensive and may load the server or cause issues in the application. If you are not sure, please consider limiting this value to 10'
+ });
+ }
- // Perform the login action when the user submits the login form
- $scope.saveDevOptions = function () {
- console.log('Saving Dev Options');
+ if ((parseInt($scope.loginData.maxFPS) < 0) || (parseInt($scope.loginData.maxFPS) > 30)) {
+ $scope.loginData.maxFPS = '3';
+ }
- if (parseInt($scope.loginData.maxMontage) > 10) {
- $ionicPopup.alert({
- title: 'Note',
- template: 'You have selected to view more than 10 monitors in the Montage screen. Note that this is very resource intensive and may load the server or cause issues in the application. If you are not sure, please consider limiting this value to 10'
- });
- }
+ if ((parseInt($scope.loginData.montageQuality) < 10) || (parseInt($scope.loginData.montageQuality) > 70)) {
+ $scope.loginData.montageQuality = '50';
+ }
- if ((parseInt($scope.loginData.maxFPS) <0) || (parseInt($scope.loginData.maxFPS)>30))
- {
- $scope.loginData.maxFPS='3';
- }
- if ((parseInt($scope.loginData.montageQuality) <10) || (parseInt($scope.loginData.montageQuality)>70))
- {
- $scope.loginData.montageQuality='50';
- }
+ ZMDataModel.setLogin($scope.loginData);
+};
+ //------------------------------------------------------------------
+ // controller main
+ //------------------------------------------------------------------
+ $scope.loginData = ZMDataModel.getLogin();
- ZMDataModel.setLogin($scope.loginData);
- };
}]);
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index 2cda31bf..fc29610e 100644
--- a/www/js/EventCtrl.js
+++ b/www/js/EventCtrl.js
@@ -6,10 +6,17 @@
// 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', ['$ionicPlatform', '$scope', '$stateParams', 'message', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicModal', '$ionicLoading', '$http', '$state', '$window',function ($ionicPlatform, $scope, $stateParams, message, ZMDataModel, $ionicSideMenuDelegate, $ionicModal, $ionicLoading, $http, $state, $window, $rootScope) {
+angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatform', '$scope', '$stateParams', 'message', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicModal', '$ionicLoading', '$http', '$state', '$window', '$interval', function ($ionicPlatform, $scope, $stateParams, message, ZMDataModel, $ionicSideMenuDelegate, $ionicModal, $ionicLoading, $http, $state, $window, $rootScope,$interval) {
+
+ //---------------------------------------------------
+ // Controller main
+ //---------------------------------------------------
+
console.log("I got STATE PARAM " + $stateParams.id);
$scope.id = parseInt($stateParams.id, 10);
$scope.connKey = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
+
+
// These are the commands ZM uses to move around
// in ZMS
var eventCommands = {
@@ -30,7 +37,7 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
};
$scope.search = {text:""};
$scope.myfilter="";
-
+ $scope.eventCommands = eventCommands;
// for some reason inifinite scroll is invoked
@@ -52,12 +59,55 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
// monitor modal is loaded, I show an ionic loading. And then when the first frame
// finishes loading, I take it away
+ console.log("***CALLING EVENTS FACTORY");
+ var lData = ZMDataModel.getLogin();
+ $scope.monitors = message;
+
+ // I am converting monitor ID to monitor Name
+ // so I can display it along with Events
+ // Is there a better way?
+
+ $scope.events = [];
+
+ // First get total pages and then
+ // start from the latest. If this fails, nothing displays
+ // FIXME: clean up error handling
+
+ // FIXME: call loadMore once -- to fill up page. Its possible
+ // last event page only has a few records
+
+ ZMDataModel.getEventsPages($scope.id)
+ .then(function (data) {
+ eventsPage = data.pageCount;
+ console.log("TOTAL EVENT PAGES IS " + eventsPage);
+ pageLoaded = true;
+ $scope.viewTitle.title = data.count;
+ ZMDataModel.getEvents($scope.id, eventsPage,"")
+
+ .then(function (data) {
+ console.log("EventCtrl Got events");
+ //var events = [];
+ var myevents = data;
+ for (var i = 0; i < myevents.length; i++) {
+
+ myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId);
+ }
+
+
+ $scope.events = myevents;
+ });
+
+ });
+
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
+ //---------------------------------------------------
+ // reload view
+ //---------------------------------------------------
$scope.reloadView = function () {
// All we really need to do here is change the random token
// in the image src and it will refresh. No need to reload the view
@@ -74,6 +124,9 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
};
+ //---------------------------------------------------
+ // when you tap a list entry - to break search loop
+ //---------------------------------------------------
$scope.tapped = function()
{
console.log ("*** TAPPED ****");
@@ -107,19 +160,25 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
});
-
-
+ //---------------------------------------------------
+ // used to hide loading image toast
+ //---------------------------------------------------
$scope.finishedLoadingImage = function () {
console.log("*** Events image FINISHED loading ***");
$ionicLoading.hide();
};
+ //---------------------------------------------------
+ //
+ //---------------------------------------------------
$scope.clearSearch = function()
{
$scope.search.text="";
- console.log ("CLEAR");
};
+ //---------------------------------------------------
+ // Called when user toggles search
+ //---------------------------------------------------
$scope.searchClicked = function()
{
$scope.showSearch = !$scope.showSearch;
@@ -136,14 +195,20 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
}
};
+ //--------------------------------------------------------
+ // Not used - plan to use it to show event progress
+ //--------------------------------------------------------
+ this.pollEventsProgress = function()
+ {
+ console.log ("**************");
+ };
- $scope.eventCommands = eventCommands;
-
-
-
+ //--------------------------------------------------------
// this routine handles skipping through events
// in different event views
- $scope.controlEventStream = function (cmd) {
+ //--------------------------------------------------------
+ $scope.controlEventStream = function (cmd)
+ {
console.log("Command value " + cmd);
$ionicLoading.hide();
@@ -154,7 +219,26 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
});
var loginData = ZMDataModel.getLogin();
-
+ // FIXME: CMD_SLOWFWD CMD_FASTFWD and REVs
+ // Also read up CMD_QUERY as the stream is playing
+ /*
+ var CMD_NONE = 0;
+ var CMD_PAUSE = 1;
+ var CMD_PLAY = 2;
+ var CMD_STOP = 3;
+ var CMD_FASTFWD = 4;
+ var CMD_SLOWFWD = 5;
+ var CMD_SLOWREV = 6;
+ var CMD_FASTREV = 7;
+ var CMD_ZOOMIN = 8;
+ var CMD_ZOOMOUT = 9;
+ var CMD_PAN = 10;
+ var CMD_SCALE = 11;
+ var CMD_PREV = 12;
+ var CMD_NEXT = 13;
+ var CMD_SEEK = 14;
+ var CMD_QUERY = 99;
+ */
var toast_blurb = "";
switch (cmd) {
case "13":
@@ -233,13 +317,15 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
});
};
- // This is called when we first tap on an event to see
+ //--------------------------------------------------------
+ //This is called when we first tap on an event to see
// the feed. It's important to instantiate ionicModal here
// as otherwise you'd instantiate it when the view loads
// and our "Please wait loading" technique I explained
//earlier won't work
+ //--------------------------------------------------------
- $scope.openModal = function (eid, ename, edur) {
+ $scope.openModal = function (eid, ename, edur,eframes) {
console.log("Open Modal");
$scope.eventName = ename;
$scope.eventId = eid;
@@ -263,19 +349,26 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
$scope.modal.show();
});
- };
- // We need to destroy because we are instantiating
+ };
+
+ //--------------------------------------------------------
+ //We need to destroy because we are instantiating
// it on open
+ //--------------------------------------------------------
$scope.closeModal = function () {
+ // $interval.cancel(eventsInterval);
console.log("Close & Destroy Modal");
if ($scope.modal !== undefined) {
$scope.modal.remove();
}
};
+
+ //--------------------------------------------------------
//Cleanup the modal when we're done with it
// I Don't think it ever comes here
+ //--------------------------------------------------------
$scope.$on('$destroy', function () {
console.log("Destroy Modal");
if ($scope.modal !== undefined) {
@@ -283,53 +376,17 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
}
});
- console.log("***CALLING EVENTS FACTORY");
- var lData = ZMDataModel.getLogin();
- $scope.monitors = message;
-
- // I am converting monitor ID to monitor Name
- // so I can display it along with Events
- // Is there a better way?
-
- $scope.events = [];
-
- // First get total pages and then
- // start from the latest. If this fails, nothing displays
- // FIXME: clean up error handling
-
- // FIXME: call loadMore once -- to fill up page. Its possible
- // last event page only has a few records
-
- ZMDataModel.getEventsPages($scope.id)
- .then(function (data) {
- eventsPage = data.pageCount;
- console.log("TOTAL EVENT PAGES IS " + eventsPage);
- pageLoaded = true;
- $scope.viewTitle.title = data.count;
- ZMDataModel.getEvents($scope.id, eventsPage,"")
-
- .then(function (data) {
- console.log("EventCtrl Got events");
- //var events = [];
- var myevents = data;
- for (var i = 0; i < myevents.length; i++) {
-
- myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId);
- }
-
-
- $scope.events = myevents;
- });
-
- });
-
-
-
+ //--------------------------------------------------------
+ // used by infinite scrolling to see if we can get more
+ //--------------------------------------------------------
$scope.moreDataCanBeLoaded = function () {
return moreEvents;
};
+ //--------------------------------------------------------
+ // stop searching for more data
+ //--------------------------------------------------------
$scope.cancelSearch = function()
{
$ionicLoading.hide(); //Or whatever action you want to preform
@@ -347,6 +404,9 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
};
+ //--------------------------------------------------------
+ // loads next page of events
+ //--------------------------------------------------------
$scope.loadMore = function () {
// the events API does not return an error for anything
@@ -362,7 +422,7 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
if (!enableLoadMore)
{
- moreEvents=false; // Dont ion-scroll till enableLoadMore is true;
+ moreEvents=false; // Don't ion-scroll till enableLoadMore is true;
$scope.$broadcast('scroll.infiniteScrollComplete');
console.log ("**** LOADMORE ARTIFICALLY DISABLED");
@@ -373,16 +433,9 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$ionicPlatfo
if ($scope.search.text != "")
{
var toastStr="Searching page "+eventsPage;
+ $ionicLoading.show({ maxwidth:100, scope:$scope,
+ template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >'+toastStr+'</button>' });
-
-
-$ionicLoading.show({ maxwidth:100, scope:$scope, template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >'+toastStr+'</button>' });
-
- // toastr.info(toastStr,{"positionClass": "toast-bottom-full-width",
- // "showMethod": "fadeIn",
- // "hideMethod": "fadeOut",
- // "closeButton": false,
- // });
loadingStr="none";
}
ZMDataModel.getEvents($scope.id, eventsPage,loadingStr)
@@ -397,26 +450,23 @@ $ionicLoading.show({ maxwidth:100, scope:$scope, template: '<button class="butto
console.log("Got new page of events");
moreEvents = true;
$scope.$broadcast('scroll.infiniteScrollComplete');
- //toastr.clear();
},
function (error) {
console.log("*** No More Events to Load, Stop Infinite Scroll ****");
moreEvents = false;
$scope.$broadcast('scroll.infiniteScrollComplete');
- // toastr.clear();
});
- // $scope.$broadcast('scroll.infiniteScrollComplete');
-
};
-
+ //--------------------------------------------------------
// For consistency we are keeping the refresher list
// but its a dummy. The reason I deviated is because
// refresh with infinite scroll is a UX problem - its
// easy to pull to refresh when scrolling up with
// a large list
+ //--------------------------------------------------------
$scope.dummyDoRefresh= function()
{
@@ -443,8 +493,6 @@ $ionicLoading.show({ maxwidth:100, scope:$scope, template: '<button class="butto
myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId);
}
-
-
$scope.events = myevents;
});
diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js
index 21d67f56..e6238084 100644
--- a/www/js/EventsGraphsCtrl.js
+++ b/www/js/EventsGraphsCtrl.js
@@ -8,9 +8,6 @@
// the main function is generateChart. I call generate chart with required parameters
// from the template file
-// FIXME: I need to clean this up, the animation is stupid because the data loads
-// dynamically. I think I should really be using $q.all to animate after we get everything
-
angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ionicPlatform', '$scope', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', function ($ionicPlatform, $scope, ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http, $element) {
console.log("Inside Graphs controller");
$scope.openMenu = function () {
@@ -34,6 +31,10 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni
});
+ //-------------------------------------------------
+ // Controller main
+ //-------------------------------------------------
+
$scope.navTitle = 'Tab Page';
// $scope.chart="";
$scope.leftButtons = [{
@@ -43,8 +44,6 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni
}
}];
- // $scope.chartObject=[{},{},{},{}];
-
angular.element(document).ready(function () {
console.log('****DOCUMENT READY******');
@@ -58,6 +57,9 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni
};
+ //-------------------------------------------------
+ // Generates a bar graph with data provided
+ //-------------------------------------------------
$scope.generateTCChart = function (id, chartTitle, hrs) {
var monitors = [];
var dateRange = "";
@@ -150,5 +152,5 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni
//String - A legend template
// legendTemplate : '<ul class="tc-chart-js-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].fillColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'
};
- };
+ }; //generateTCChart
}]);
diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js
index b787f509..e014500b 100644
--- a/www/js/LoginCtrl.js
+++ b/www/js/LoginCtrl.js
@@ -9,10 +9,21 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
$scope.loginData = ZMDataModel.getLogin();
-
-
+//-------------------------------------------------------------------------------
+// Adds http to url if not present
+// http://stackoverflow.com/questions/11300906/check-if-a-string-starts-with-http-using-javascript
+//-------------------------------------------------------------------------------
+function addhttp(url) {
+ if (!/^(f|ht)tps?:\/\//i.test(url)) {
+ url = "http://" + url;
+ }
+ return url;
+}
+
+ //-----------------------------------------------------------------------------
// Perform the login action when the user submits the login form
- $scope.login = function () {
+ //-----------------------------------------------------------------------------
+ $scope.save = function () {
console.log('Saving login');
if (parseInt($scope.loginData.maxMontage) > 10) {
@@ -55,6 +66,29 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
$scope.loginData.streamingurl = $scope.loginData.streamingurl.slice(0, -7);
}
+ // check for protocol and if not put it in
+
+ $scope.loginData.url = addhttp($scope.loginData.url);
+ $scope.loginData.apiurl = addhttp($scope.loginData.apiurl);
+ $scope.loginData.streamingurl = addhttp($scope.loginData.streamingurl);
+
+ if ($scope.loginData.useSSL)
+ {
+ // replace all http with https
+ $scope.loginData.url = $scope.loginData.url.replace("http:","https:");
+ $scope.loginData.apiurl = $scope.loginData.apiurl.replace("http:","https:");
+ $scope.loginData.streamingurl = $scope.loginData.streamingurl.replace("http:","https:");
+
+ }
+ else
+ {
+ // replace all https with http
+ $scope.loginData.url = $scope.loginData.url.replace("https:","http:");
+ $scope.loginData.apiurl = $scope.loginData.apiurl.replace("https:","http:");
+ $scope.loginData.streamingurl = $scope.loginData.streamingurl.replace("https:","http:");
+ }
+
+
// FIXME:: Do a login id check too
diff --git a/www/js/ModalCtrl.js b/www/js/ModalCtrl.js
index 14298269..102bc46a 100644
--- a/www/js/ModalCtrl.js
+++ b/www/js/ModalCtrl.js
@@ -29,7 +29,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'Down');
}
- },
+ },
{
content: '',
@@ -38,7 +38,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'DownLeft');
}
- },
+ },
{
content: '',
@@ -48,7 +48,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'Left');
}
- },
+ },
{
content: 'D',
empty: true,
@@ -56,7 +56,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
console.log('About');
}
- },
+ },
{
content: '',
@@ -65,7 +65,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'UpLeft');
}
- },
+ },
{
content: '',
@@ -74,7 +74,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'Up');
}
- },
+ },
{
content: '',
@@ -83,7 +83,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'UpRight');
}
- },
+ },
{
content: 'H',
@@ -91,7 +91,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
console.log('About');
}
- },
+ },
{
content: '',
@@ -100,7 +100,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'Right');
}
- },
+ },
{
@@ -110,7 +110,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
controlPTZ($scope.monitorId, 'DownRight');
}
- },
+ },
{
content: 'K',
@@ -118,17 +118,19 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
onclick: function () {
console.log('About');
}
- },
- ]
- };
+ },
+ ]};
+ //-------------------------------------------------------------
// Send PTZ command to ZM
// FIXME: moveCon is hardcoded - won't work with
// cams that don't use moveCon.
// Need to grab control ID and then control API
+ //-------------------------------------------------------------
function controlPTZ(monitorId, cmd) {
- //curl -X POST "http://server.com/zm/index.php?view=request" -d "request=control&user=admin&passwd=xx&id=4&control=moveConLeft"
+ //curl -X POST "http://server.com/zm/index.php?view=request" -d
+ //"request=control&user=admin&passwd=xx&id=4&control=moveConLeft"
console.log("Command value " + cmd + " with MID=" + monitorId);
$ionicLoading.hide();
@@ -193,16 +195,8 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco
$scope.finishedLoadingImage = function () {
console.log("***Monitor image FINISHED Loading***");
$ionicLoading.hide();
- /* $ionicLoading.show({
- template: "loading, please wait...",
- noBackdrop: true,
- });*/
- };
- // In Android, the app runs full steam while in background mode
- // while in iOS it gets suspended unless you ask for specific resources
- // So while this view, we DON'T want Android to keep sending 1 second
- // refreshes to the server for images we are not seeing!
+ };
}]);
diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js
index d0c6f90e..0d65a891 100644
--- a/www/js/MonitorCtrl.js
+++ b/www/js/MonitorCtrl.js
@@ -7,12 +7,27 @@
angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopup', '$scope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', function ($ionicPopup, $scope, ZMDataModel, message, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout) {
+
+ //-----------------------------------------------------------------------
+ // Controller Main
+ //-----------------------------------------------------------------------
+
+ console.log("***EVENTS: Waiting for Monitors to load before I proceed");
$scope.monitors = [];
+ $scope.monitors = message;
+ var loginData = ZMDataModel.getLogin();
+ monitorStateCheck();
+
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
+
+ //-----------------------------------------------------------------------
+ // All we do here is create a new random val for the URL so the
+ // image regenerates
+ //-----------------------------------------------------------------------
$scope.reloadView = function () {
console.log("*** Refreshing Modal view ***");
$scope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
@@ -23,9 +38,11 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
});
};
- // This function takes care of changing function parameters
+ //-----------------------------------------------------------------------
+ // This function takes care of changing monitor parameters
// For now, I've only limited it to enable/disable and change monitor mode
-
+ // and changing monitor function
+ //-----------------------------------------------------------------------
$scope.changeConfig = function (monitorName, monitorId, enabled, func) {
var checked = "false";
console.log("called with " + monitorId + ":" + enabled + ":" + func);
@@ -56,8 +73,8 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
text: "None",
value: "None"
}
- ];
- //$scope.monFunctions = monFunctions;
+ ];
+
$scope.monfunc = {
myfunc: func,
myenabled: checked
@@ -65,7 +82,7 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
var getConfig = $ionicPopup.show({
scope: $scope,
- template: '<ion-toggle ng-model="monfunc.myenabled" ng-checked="{{monfunc.myenabled}}" toggle-class="toggle-calm">Enabled</ion-toggle><ion-radio ng-repeat="item in monFunctions" ng-value="item.value" ng-model="monfunc.myfunc"> {{item.text}} </ion-radio>',
+ template: '<ion-toggle ng-model="monfunc.myenabled" ng-checked="{{monfunc.myenabled}}" toggle-class="toggle-calm">Enabled</ion-toggle><ion-radio ng-repeat="item in monFunctions" ng-value="item.value" ng-model="monfunc.myfunc"> {{item.text}} </ion-radio>',
title: 'Change Settings for ' + monitorName,
@@ -98,7 +115,8 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
transformRequest: function (obj) {
var str = [];
for (var p in obj)
- str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
+ str.push(encodeURIComponent(p) + "=" +
+ encodeURIComponent(obj[p]));
var foo = str.join("&");
console.log("****RETURNING " + foo);
return foo;
@@ -115,7 +133,8 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
.success(function () {
$ionicLoading.show({
- template: "Successfully changed Monitor. Please wait, restarting ZoneMinder...",
+ template:
+ "Successfully changed Monitor. Please wait, restarting ZoneMinder...",
noBackdrop: true,
duration: 60000,
});
@@ -144,9 +163,6 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
});
});
-
-
-
}
@@ -163,14 +179,9 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
$scope.finishedLoadingImage = function () {
console.log("***Monitor image FINISHED Loading***");
$ionicLoading.hide();
- /* $ionicLoading.show({
- template: "loading, please wait...",
- noBackdrop: true,
- });*/
};
-
$scope.$on('$ionicView.loaded', function () {
console.log("**VIEW ** Monitor Ctrl Loaded");
});
@@ -336,74 +347,53 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu
console.log("ERROR: " + JSON.stringify(resp));
});
- //});
}
-
-
- console.log("***EVENTS: Waiting for Monitors to load before I proceed");
-
- $scope.monitors = message;
- var loginData = ZMDataModel.getLogin();
- monitorStateCheck();
-
- function monitorStateCheck()
- {
+ function monitorStateCheck() {
var apiMonCheck;
// The status is provided by zmdc.pl
// "not running", "pending", "running since", "Unable to connect"
- for (var i = 0; i < $scope.monitors.length; i++) {
- (function (j)
- {
+ for (var i = 0; i < $scope.monitors.length; i++) {
+ (function (j) {
$scope.monitors[j].Monitor.isRunningText = "...";
$scope.monitors[j].Monitor.isRunning = "...";
$scope.monitors[j].Monitor.color = '#1E90FF';
$scope.monitors[j].Monitor.char = "ion-checkmark-circled";
apiMonCheck = loginData.apiurl + "/monitors/daemonStatus/id:" + $scope.monitors[j].Monitor.Id + "/daemon:zmc.json";
- console.log ("**** ZMC CHECK " + apiMonCheck);
+ console.log("**** ZMC CHECK " + apiMonCheck);
$http.get(apiMonCheck)
- .success(function(data)
- {
- if (data.statustext.indexOf("not running")>-1)
- {
- $scope.monitors[j].Monitor.isRunning = "false" ;
- $scope.monitors[j].Monitor.color = 'red';
- $scope.monitors[j].Monitor.char = "ion-close-circled";
- }
- else if (data.statustext.indexOf("pending")>-1)
- {
- $scope.monitors[j].Monitor.isRunning = "pending" ;
- $scope.monitors[j].Monitor.color = 'orange';
- }
- else if (data.statustext.indexOf("running since")>-1)
- {
- $scope.monitors[j].Monitor.isRunning = "true" ;
- $scope.monitors[j].Monitor.color = 'green';
- }
-
- else if (data.statustext.indexOf("Unable to connect")>-1)
- {
- $scope.monitors[j].Monitor.isRunning = "false" ;
- $scope.monitors[j].Monitor.color = 'red';
- $scope.monitors[j].Monitor.char = "ion-close-circled";
- }
-
-
- $scope.monitors[j].Monitor.isRunningText = data.statustext;
- })
- .error (function (data)
- {
- $scope.monitors[j].Monitor.isRunning = "error";
- $scope.monitors[j].Monitor.color = '#800000';
- $scope.monitors[j].Monitor.char = "ion-help-circled";
- });
+ .success(function (data) {
+ if (data.statustext.indexOf("not running") > -1) {
+ $scope.monitors[j].Monitor.isRunning = "false";
+ $scope.monitors[j].Monitor.color = 'red';
+ $scope.monitors[j].Monitor.char = "ion-close-circled";
+ } else if (data.statustext.indexOf("pending") > -1) {
+ $scope.monitors[j].Monitor.isRunning = "pending";
+ $scope.monitors[j].Monitor.color = 'orange';
+ } else if (data.statustext.indexOf("running since") > -1) {
+ $scope.monitors[j].Monitor.isRunning = "true";
+ $scope.monitors[j].Monitor.color = 'green';
+ } else if (data.statustext.indexOf("Unable to connect") > -1) {
+ $scope.monitors[j].Monitor.isRunning = "false";
+ $scope.monitors[j].Monitor.color = 'red';
+ $scope.monitors[j].Monitor.char = "ion-close-circled";
+ }
+
+
+ $scope.monitors[j].Monitor.isRunningText = data.statustext;
+ })
+ .error(function (data) {
+ $scope.monitors[j].Monitor.isRunning = "error";
+ $scope.monitors[j].Monitor.color = '#800000';
+ $scope.monitors[j].Monitor.char = "ion-help-circled";
+ });
})(i);
- }
+ }
}
$scope.doRefresh = function () {
console.log("***Pull to Refresh");
diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js
index 11306e4c..a6dfbc01 100644
--- a/www/js/MonitorModalCtrl.js
+++ b/www/js/MonitorModalCtrl.js
@@ -6,6 +6,4 @@
angular.module('zmApp.controllers').controller('zmApp.MonitorModalCtrl', ['$ionicPopup', '$scope', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', function ($ionicPopup,$scope, ZMDataModel, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope) {
-
-
}]);
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index 1e0c1a64..b39d2aac 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -6,8 +6,92 @@
angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '$rootScope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams','$ionicHistory','$ionicScrollDelegate', function ($scope, $rootScope, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http,$state, $stateParams, $ionicHistory,$ionicScrollDelegate) {
+ //---------------------------------------------------------------------
+ // Controller main
+ //---------------------------------------------------------------------
+ document.addEventListener("pause", onPause, false);
+
+ // I was facing a lot of problems with Chrome/crosswalk getting stuck with
+ // pending HTTP requests after a while. There is a problem with chrome handling
+ // multiple streams of always open HTTP get's (image streaming). This problem
+ // does not arise when the image is streamed for a single monitor - just multiple
+
+ // To work around this I am taking a single snapshot of ZMS and have implemented a timer
+ // to reload the snapshot every 1 second. Seems to work reliably even thought its a higer
+ // load. Will it bonk with many monitors? Who knows. I have tried with 5 and 1280x960@32bpp
+
+
+ this.loadNotifications = function () {
+ // randomval is appended to img src, so after each interval the image reloads
+ $scope.randomval = (new Date()).getTime();
+ //console.log ("**** NOTIFICATION with rand="+$scope.randomval+"*****");
+ };
+
+ var timestamp = new Date().getUTCMilliseconds();
+ $scope.minimal = $stateParams.minimal;
+ $scope.isRefresh = $stateParams.isRefresh;
+
+ var isLongPressActive = false;
+ var intervalHandleMontage; // will hold image resize timer on long press
+ var montageIndex = 0; // will hold monitor ID to scale in timer
+
+ $scope.monitorSize = []; // array with montage sizes per monitor
+ $scope.scaleDirection = []; // 1 = increase -1 = decrease
+
+ $scope.slider = {};
+ $scope.slider.monsize = ZMDataModel.getMontageSize();
+
+ console.log ("******** HAVE ALL MONITORS");
+ $scope.monitors = message;
+
+
+ // Do we have a saved montage array size? No?
+ if (window.localStorage.getItem("montageArraySize") == undefined)
+ {
+
+ for ( var i = 0; i<$scope.monitors.length; i++)
+ {
+ $scope.monitorSize.push(ZMDataModel.getMontageSize() );
+ $scope.scaleDirection.push(1);
+ }
+ }
+ else // recover previous settings
+ {
+ var msize = window.localStorage.getItem("montageArraySize");
+ console.log ("MontageArrayString is=>"+msize);
+ $scope.monitorSize= msize.split(":");
+ var j;
+
+ for ( j = 0; j<$scope.monitorSize.length; j++)
+ {
+ // convert to number other wise adding to it concatenates :-)
+ $scope.monitorSize[j] = parseInt($scope.monitorSize[j]);
+ $scope.scaleDirection.push(1);
+ console.log ("Montage size for monitor " + j + " is " + $scope.monitorSize[j]);
+
+ }
+
+ }
+ console.log ("******** SETTING VARS");
+ // $scope.monitorSize = monitorSize;
+ // $scope.scaleDirection = scaleDirection;
+
+ $scope.LoginData = ZMDataModel.getLogin();
+ $scope.monLimit = $scope.LoginData.maxMontage;
+ console.log("********* Inside Montage Ctrl, MAX LIMIT=" + $scope.monLimit);
+
+
+ var intervalHandle = $interval(function () {
+ this.loadNotifications();
+ // console.log ("Refreshing Image...");
+ }.bind(this), 1000);
+
+ this.loadNotifications();
+
+ //---------------------------------------------------------------------
// Triggered when you enter/exit full screen
+ //---------------------------------------------------------------------
$scope.switchMinimal = function()
{
$scope.minimal = !$scope.minimal;
@@ -21,15 +105,18 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
});
$state.go("montage", {minimal: $scope.minimal,
isRefresh:true});
- //$state.reload();
- };
+ };
- // Show/Hide PTZ control
+ //---------------------------------------------------------------------
+ // Show/Hide PTZ control in monitor view
+ //---------------------------------------------------------------------
$scope.togglePTZ = function () {
$scope.showPTZ = !$scope.showPTZ;
};
-
+ //---------------------------------------------------------------------
+ // main monitor modal open
+ //---------------------------------------------------------------------
$scope.openModal = function (mid, controllable) {
console.log("Open Monitor Modal");
@@ -55,48 +142,21 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
$scope.modal.show();
});
- // do a post login for PTZ
- var loginData = ZMDataModel.getLogin();
- console.log("*** MODAL PORTAL LOGIN ****");
- $http({
- method: 'POST',
- 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 foo = str.join("&");
- console.log("****RETURNING " + foo);
- return foo;
- },
-
- data: {
- username: loginData.username,
- password: loginData.password,
- action: "login",
- view: "console"
- }
- })
- .success(function (data) {
- console.log("**** PORTAL LOGIN OK");
- })
- .error(function (error) {
- console.log("**** PORTAL LOGIN FAILED");
- });
-
};
+ //---------------------------------------------------------------------
+ //
+ //---------------------------------------------------------------------
+
$scope.closeModal = function () {
console.log("Close & Destroy Monitor Modal");
$scope.modal.remove();
};
+ //---------------------------------------------------------------------
+ // allows you to resize individual montage windows
+ //---------------------------------------------------------------------
function scaleMontage()
{
var index = montageIndex;
@@ -123,6 +183,10 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
window.localStorage.setItem("montageArraySize", monsizestring);
}
+ //---------------------------------------------------------------------
+ // if you long press on a montage window, it calls scale montage
+ // at a 200ms freq
+ //---------------------------------------------------------------------
$scope.onHold = function (index)
{
montageIndex = index;
@@ -134,6 +198,9 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
};
+ //---------------------------------------------------------------------
+ // stop scaling montage window on release
+ //---------------------------------------------------------------------
$scope.onRelease = function (index)
{
console.log ("Press release on " + index);
@@ -143,11 +210,12 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
-
+ //---------------------------------------------------------------------
// In Android, the app runs full steam while in background mode
// while in iOS it gets suspended unless you ask for specific resources
// So while this view, we DON'T want Android to keep sending 1 second
- // refreshes to the server for images we are not seeing!
+ // refreshes to the server for images we are not seeing
+ //---------------------------------------------------------------------
function onPause() {
console.log("*** Moving to Background ***"); // Handle the pause event
@@ -155,23 +223,6 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
$interval.cancel(intervalHandle);
}
- document.addEventListener("pause", onPause, false);
-
- // I was facing a lot of problems with Chrome/crosswalk getting stuck with
- // pending HTTP requests after a while. There is a problem with chrome handling
- // multiple streams of always open HTTP get's (image streaming). This problem
- // does not arise when the image is streamed for a single monitor - just multiple
-
- // To work around this I am taking a single snapshot of ZMS and have implemented a timer
- // to reload the snapshot every 1 second. Seems to work reliably even thought its a higer
- // load. Will it bonk with many monitors? Who knows. I have tried with 5 and 1280x960@32bpp
-
-
- this.loadNotifications = function () {
- // randomval is appended to img src, so after each interval the image reloads
- $scope.randomval = (new Date()).getTime();
- //console.log ("**** NOTIFICATION with rand="+$scope.randomval+"*****");
- };
$scope.openMenu = function () {
@@ -200,23 +251,19 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
console.log("**VIEW ** Montage Ctrl Unloaded");
});
-
- $scope.isSimulated = function () {
- return ZMDataModel.isSimulated();
- };
-
-
-
+ //---------------------------------------------------------
// 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.sliderChanged = 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);
+ console.log("Rootscope Montage is " + ZMDataModel.getMontageSize() +
+ " and slider montage is " + $scope.slider.monsize);
// Now go ahead and reset sizes of entire monitor array
var monsizestring="";
var i;
@@ -243,6 +290,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
+
$scope.doRefresh = function () {
console.log("***Pull to Refresh");
$scope.monitors = [];
@@ -255,66 +303,5 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '
};
- var timestamp = new Date().getUTCMilliseconds();
- $scope.minimal = $stateParams.minimal;
- $scope.isRefresh = $stateParams.isRefresh;
-
- var isLongPressActive = false;
- var intervalHandleMontage; // will hold image resize timer on long press
- var montageIndex = 0; // will hold monitor ID to scale in timer
-
- // don't init here -will mess up scrolling
- $scope.monitorSize = []; // array with montage sizes per monitor
- $scope.scaleDirection = []; // 1 = increase -1 = decrease
-
- $scope.slider = {};
- $scope.slider.monsize = ZMDataModel.getMontageSize();
-
- //$scope.monitors = [];
- console.log ("******** HAVE ALL MONITORS");
- $scope.monitors = message;
-
-
- // Do we have a saved montage array size? No?
- if (window.localStorage.getItem("montageArraySize") == undefined)
- {
- for ( var i = 0; i<$scope.monitors.length; i++)
- {
- $scope.monitorSize.push(ZMDataModel.getMontageSize() );
- $scope.scaleDirection.push(1);
- }
- }
- else // recover previous settings
- {
- var msize = window.localStorage.getItem("montageArraySize");
- console.log ("MontageArrayString is=>"+msize);
- $scope.monitorSize= msize.split(":");
- var j;
-
- for ( j = 0; j<$scope.monitorSize.length; j++)
- {
- // convert to number other wise adding to it concatenates :-)
- $scope.monitorSize[j] = parseInt($scope.monitorSize[j]);
- $scope.scaleDirection.push(1);
- console.log ("Montage size for monitor " + j + " is " + $scope.monitorSize[j]);
-
- }
-
- }
- console.log ("******** SETTING VARS");
- // $scope.monitorSize = monitorSize;
- // $scope.scaleDirection = scaleDirection;
-
- $scope.LoginData = ZMDataModel.getLogin();
- $scope.monLimit = $scope.LoginData.maxMontage;
- console.log("********* Inside Montage Ctrl, MAX LIMIT=" + $scope.monLimit);
-
-
- var intervalHandle = $interval(function () {
- this.loadNotifications();
- // console.log ("Refreshing Image...");
- }.bind(this), 1000);
-
- this.loadNotifications();
}]);
diff --git a/www/js/StateCtrl.js b/www/js/StateCtrl.js
index 4c44b6b5..13ca288c 100644
--- a/www/js/StateCtrl.js
+++ b/www/js/StateCtrl.js
@@ -6,6 +6,9 @@
angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup', '$scope', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', function ($ionicPopup, $scope, ZMDataModel, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope) {
+//----------------------------------------------------------------------
+// Controller main
+//----------------------------------------------------------------------
$scope.zmRun = "loading...";
$scope.zmLoad = "loading...";
$scope.zmDisk = "loading...";
@@ -22,11 +25,14 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
var apiExec = loginData.apiurl + "/states/change/";
- var inProgress = 0;
+ var inProgress = 0; // prevents user from another op if one is in progress
getRunStatus();
getLoadStatus();
getDiskStatus();
+ //----------------------------------------------------------------------
+ // returns disk space in gigs taken up by events
+ //----------------------------------------------------------------------
function getDiskStatus() {
$http.get(apiDisk)
.then(
@@ -50,6 +56,9 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
);
}
+ //----------------------------------------------------------------------
+ // returns ZM running status
+ //----------------------------------------------------------------------
function getRunStatus() {
$http.get(apiRun)
.then(
@@ -82,6 +91,9 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
}
+ //----------------------------------------------------------------------
+ // gets ZM load - max[0], avg[1], min[2]
+ //----------------------------------------------------------------------
function getLoadStatus() {
$http.get(apiLoad)
.then(
@@ -101,7 +113,9 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
}
-
+ //----------------------------------------------------------------------
+ // start/stop/restart ZM
+ //----------------------------------------------------------------------
$scope.controlZM = function (str) {
if (inProgress) {
@@ -153,32 +167,15 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
$scope.zmRun = 'undetermined';
$scope.color = 'color:orange;';
inProgress = 0;
- // }
- /*else
- {
- switch (str)
- {
- case "stop":$scope.zmRun = 'stopped';
- $scope.color='color:red;'; break;
- case "start":
- case "restart":$scope.zmRun = 'running';
- $scope.color = 'color:green;';break;
-
- }
- inProgress = 0;
- }*/
-
- }
-
- );
+ }); //incredible nesting below. I make myself proud.
}
- }
- ]
+ }
+ ]
});
-
};
+
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -186,19 +183,11 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
$scope.$on('$ionicView.leave', function () {
console.log("**VIEW ** State Ctrl Left");
// FIXME not the best way...
+ // If the user exits a view before its complete,
+ // make sure he can come back in and redo
inProgress = 0;
});
- $scope.reloadView = function () {
- console.log("*** Refreshing Modal view ***");
- inProgress = 0;
- $scope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
- $ionicLoading.show({
- template: "refreshed view",
- noBackdrop: true,
- duration: 2000
- });
- };
$scope.doRefresh = function () {
console.log("***Pull to Refresh");
diff --git a/www/js/app.js b/www/js/app.js
index 463e15d4..76b14c66 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -7,13 +7,15 @@
angular.module('zmApp', [
'ionic',
'zmApp.controllers',
+ //'cordovaHTTP'
])
-
+//------------------------------------------------------------------
// this directive will be load any time an image completes loading
// via img tags where this directive is added (I am using this in
// events and mionitor view to show a loader while the image is
// downloading from ZM
+//------------------------------------------------------------------
.directive('imageonload', function () {
return {
@@ -29,14 +31,14 @@ angular.module('zmApp', [
};
})
-
+//------------------------------------------------------------------
// 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', function ($rootScope, $q) {
//console.log("*** HTTP INTERCEPTOR CALLED ***");
return {
@@ -60,7 +62,10 @@ angular.module('zmApp', [
};
})
+//-----------------------------------------------------------------
// This service automatically logs into ZM at periodic intervals
+//------------------------------------------------------------------
+
.factory('zmAutoLogin', function($interval, ZMDataModel, $http) {
var zmAutoLoginHandle;
function doLogin()
@@ -151,7 +156,9 @@ angular.module('zmApp', [
})
*/
-
+//------------------------------------------------------------------
+// First run in ionic
+//------------------------------------------------------------------
.run(function ($ionicPlatform, $ionicPopup, $rootScope, $state, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin)
{
@@ -260,6 +267,10 @@ angular.module('zmApp', [
}) //run
+//------------------------------------------------------------------
+// Route configuration
+//------------------------------------------------------------------
+
// My route map connecting menu options to their respective templates and controllers
.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
// If you do this, Allow Origin can't be *
diff --git a/www/js/controllers.js b/www/js/controllers.js
index bd907c19..99f85f29 100644
--- a/www/js/controllers.js
+++ b/www/js/controllers.js
@@ -4,7 +4,6 @@
angular.module('zmApp.controllers', ['ionic', 'tc.chartjs', 'ngCordova', 'ng-mfb','angularCircularNavigation' ])
-
.controller('zmApp.AppCtrl', function($scope, $ionicSideMenuDelegate) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
diff --git a/www/templates/devoptions.html b/www/templates/devoptions.html
index 7b5fca0e..04b90af1 100644
--- a/www/templates/devoptions.html
+++ b/www/templates/devoptions.html
@@ -7,37 +7,33 @@
<ion-content class="padding">
<div class="list list-inset">
-
- <span style="color:rgb(100,100,100)"><i class="ion-android-settings" style="font-size:150%"></i> Developer Options</span>
+ <span style="color:rgb(100,100,100)">
+ <i class="ion-android-settings" style="font-size:150%"></i> Developer Options
+ </span>
<div class="item item-input-inset">
-
Max Monitors in Montage&nbsp;
<label class="item-input-wrapper">
<input type="tel" placeholder="be careful" ng-model="loginData.maxMontage">
</label>
-
</div>
<div class="item item-input-inset">
-
Max FPS for streaming&nbsp;
<label class="item-input-wrapper">
<input type="tel" placeholder="max is 30" ng-model="loginData.maxFPS">
</label>
-
</div>
<div class="item item-input-inset">
-
Montage Streaming Quality(%)&nbsp;
<label class="item-input-wrapper">
<input type="tel" placeholder="max is 70" ng-model="loginData.montageQuality">
</label>
</div>
- <button class="button button-block button-balanced icon ion-locked" ng-click="saveDevOptions()"> Save</button>
-
+ <button class="button button-block button-balanced icon ion-locked"
+ ng-click="saveDevOptions()"> Save</button>
</ion-content>
</ion-view>
diff --git a/www/templates/events-graphs.html b/www/templates/events-graphs.html
index 91b58001..b3d19832 100644
--- a/www/templates/events-graphs.html
+++ b/www/templates/events-graphs.html
@@ -6,74 +6,61 @@
<!-- I'm calling the same controller function but with different parameters when
you switch between tabs -->
+
+ <!-- All Events view -->
<ion-tabs class="tabs-icon-top tabs-stable">
<ion-tab title="All" icon="ion-stats-bars" on-select="generateTCChart(0,'All Events',0)">
<ion-nav-view>
<ion-content class="has-header">
<canvas tc-chartjs-bar chart-data="data" chart-options="options" ng-click="handleChartClick($event)" chart="chart1">
</canvas>
-
-
</ion-content>
</ion-nav-view>
</ion-tab>
-
-
-
- <ion-tab title="Last Hour" icon="ion-stats-bars" on-select="generateTCChart(1,'Events in the last hour',1)">
+ <!-- All Events in the last hour -->
+ <ion-tab title="Last Hour" icon="ion-stats-bars"
+ on-select="generateTCChart(1,'Events in the last hour',1)">
<ion-nav-view>
-
<ion-content>
- <span></span>
-
-
-
-
<div style="overflow:scroll;">
- <canvas tc-chartjs-bar chart-data="data" chart-options="options" ng-click="handleChartClick($event)" chart="chart2">
+ <canvas tc-chartjs-bar chart-data="data" chart-options="options"
+ ng-click="handleChartClick($event)" chart="chart2">
</canvas>
</div>
- </canvas>
-
- <!-- <div google-chart chart="chartObject[1]"></div>-->
- </div>
-
</ion-content>
</ion-nav-view>
</ion-tab>
- <ion-tab title="Day" icon="ion-stats-bars" on-select="generateTCChart(2,'Events in the last day',24)">
+ <!-- All Events in last 24 hrs -->
+ <ion-tab title="Day" icon="ion-stats-bars"
+ on-select="generateTCChart(2,'Events in the last day',24)">
<ion-nav-view>
-
<ion-content>
- <span></span>
<div style="overflow:scroll;">
- <canvas tc-chartjs-bar chart-data="data" chart-options="options" chart="chart3" ng-click="handleChartClick($event)">
+ <canvas tc-chartjs-bar chart-data="data"
+ chart-options="options" chart="chart3"
+ ng-click="handleChartClick($event)">
</canvas>
</div>
-
</ion-content>
</ion-nav-view>
</ion-tab>
- <ion-tab title="Week" icon="ion-stats-bars" on-select="generateTCChart(3,'Events in the last week',168)">
- <ion-nav-view>
+ <!-- All Events in last week -->
+ <ion-tab title="Week" icon="ion-stats-bars"
+ on-select="generateTCChart(3,'Events in the last week',168)">
+ <ion-nav-view>
<ion-content>
- <span></span>
- <!--
- <div google-chart chart="chartObject[3]"></div>-->
<div style="overflow:scroll;">
- <canvas tc-chartjs-bar chart-data="data" chart-options="options" chart="chart4" ng-click="handleChartClick($event)">
+ <canvas tc-chartjs-bar chart-data="data"
+ chart-options="options" chart="chart4"
+ ng-click="handleChartClick($event)">
</canvas>
</div>
</ion-content>
</ion-nav-view>
</ion-tab>
-
</ion-tabs>
-
-
-
</ion-view>
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
index c904c9d0..a3cd5bcc 100644
--- a/www/templates/events-modal.html
+++ b/www/templates/events-modal.html
@@ -1,22 +1,12 @@
<ion-modal-view cache="false">
-
- <!-- <ion-header-bar>
- <h1 class="title">
- <span style="float:left">
- <button class="button button-clear icon icon-left ion-close" ng-click="closeModal()" >Close</button>
- </span>
- <span style="float:right">
- {{eventName}} (Duration:{{eventDur}}s)
- </span>
- </h1>
- </ion-header-bar> -->
<ion-content>
+ <!-- so I can access my common modal controller
+ which is shared between events and monitors for modal views -->
<div ng-controller="ModalCtrl">
-
- <!-- replay can also be gapless -->
-
- <ion-scroll has-bouncing=false min-zoom=1 zooming="true" direction="xy" style="width: 100%; ">
- <img imageonload="finishedLoadingImage()" ng-src="{{loginData.streamingurl}}/cgi-bin/zms?source=event&mode=jpeg&event={{eventId}}&frame=1&maxfps={{loginData.maxFPS}}&replay=single&user={{loginData.username}}&pass={{loginData.password}}&connkey={{connKey}}&rand={{rand}}" width="100%" />
+ <ion-scroll has-bouncing=false min-zoom=1 zooming="true"
+ direction="xy" style="width: 100%; ">
+ <img imageonload="finishedLoadingImage()"
+ ng-src="{{loginData.streamingurl}}/cgi-bin/zms?source=event&mode=jpeg&event={{eventId}}&frame=1&maxfps={{loginData.maxFPS}}&replay=single&user={{loginData.username}}&pass={{loginData.password}}&connkey={{connKey}}&rand={{rand}}" width="100%" />
</ion-scroll>
</div>
</ion-content>
diff --git a/www/templates/events.html b/www/templates/events.html
index 0f9a5570..12a2afc7 100644
--- a/www/templates/events.html
+++ b/www/templates/events.html
@@ -65,7 +65,7 @@
<span style="float:right">
<button class="button button-small icon icon-left ion-ios-eye"
- ng-click="openModal(event.Event.Id, event.Event.Name, event.Event.Length)" >View Footage</button>
+ ng-click="openModal(event.Event.Id, event.Event.Name, event.Event.Length,event.Event.Frames)" >View Footage</button>
</span>
</div>
diff --git a/www/templates/login.html b/www/templates/login.html
index bf1fc487..e0eb8b33 100644
--- a/www/templates/login.html
+++ b/www/templates/login.html
@@ -26,8 +26,13 @@
<label class="item item-input">
<input autocapitalize="none" type="text" placeholder="ZM Api URL" ng-model="loginData.apiurl">
</label>
+
+ <label >
+ <ion-toggle ng-model="loginData.useSSL" ng-checked="{{loginData.useSSL}}" toggle-class="toggle-calm">Use SSL</ion-toggle>
+ </label>
+
</div>
- <button class="button button-block button-balanced icon ion-locked" ng-click="login()"> Save</button>
+ <button class="button button-block button-balanced icon ion-locked" ng-click="save()"> Save</button>
</ion-content>
</ion-view>