diff options
| author | PliablePixels <pliablepixels@gmail.com> | 2015-07-15 21:03:42 -0400 |
|---|---|---|
| committer | PliablePixels <pliablepixels@gmail.com> | 2015-07-15 21:03:42 -0400 |
| commit | ca9d64b313a4638d665e08e6d6c79c5b2538601d (patch) | |
| tree | a34bcb2ab67d9d7bdb448c26951a905a53a00ba3 /www | |
| parent | e41a65e082bcaa1487621a7a7ddcb2c1228a6c3f (diff) | |
Updated with functionality to save feed snapshots to camera roll
Diffstat (limited to 'www')
| -rw-r--r-- | www/css/style.css | 11 | ||||
| -rw-r--r-- | www/index.html | 12 | ||||
| -rw-r--r-- | www/js/DataModel.js | 44 | ||||
| -rw-r--r-- | www/js/DevOptionsCtrl.js | 12 | ||||
| -rw-r--r-- | www/js/EventCtrl.js | 6 | ||||
| -rw-r--r-- | www/js/EventsGraphsCtrl.js | 10 | ||||
| -rw-r--r-- | www/js/LogCtrl.js | 6 | ||||
| -rw-r--r-- | www/js/LoginCtrl.js | 6 | ||||
| -rw-r--r-- | www/js/ModalCtrl.js | 36 | ||||
| -rw-r--r-- | www/js/MonitorCtrl.js | 132 | ||||
| -rw-r--r-- | www/js/MontageCtrl.js | 85 | ||||
| -rw-r--r-- | www/js/StateCtrl.js | 2 | ||||
| -rw-r--r-- | www/js/app.js | 55 | ||||
| -rw-r--r-- | www/templates/monitors-modal.html | 12 | ||||
| -rw-r--r-- | www/templates/montage.html | 2 |
15 files changed, 340 insertions, 91 deletions
diff --git a/www/css/style.css b/www/css/style.css index a8c4b3f7..0092b0a2 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -105,6 +105,15 @@ Credit: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ } +.camera-icon +{ + position:absolute; + bottom:20px; + left:10px; + z-index:10; + opacity:0.7; +} + /* Styling of progress bar http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/ */ @@ -206,3 +215,5 @@ progress[aria-valuenow]:before { } + + diff --git a/www/index.html b/www/index.html index 9f6030cb..e59eb108 100644 --- a/www/index.html +++ b/www/index.html @@ -87,12 +87,6 @@ <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> @@ -105,6 +99,12 @@ </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> diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 8b91847f..5104e464 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -7,7 +7,7 @@ // 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', '$ionicBackdrop', '$fileLogger', function ($http, $q, $ionicLoading, $ionicBackdrop,$fileLogger) { +angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm',function ($http, $q, $ionicLoading, $ionicBackdrop,$fileLogger,zm) { var zmAppVersion="unknown"; var monitorsLoaded = 0; @@ -139,10 +139,13 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion }, isLoggedIn: function () { - if (loginData.username != "" && loginData.password != "" && loginData.url != "" && loginData.apiurl != "") { + if (loginData.username != "" && loginData.password != "" && loginData.url != "" && loginData.apiurl != "") + { return 1; } else - return 0; {} + { + return 0; + } }, getLogin: function () { @@ -246,7 +249,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion template: 'Loading Monitors...', animation: 'fade-in', showBackdrop: true, - duration: 15000, + duration: zm.loadingTimeout, maxWidth: 200, showDelay: 0 }); @@ -361,7 +364,7 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion showBackdrop: true, maxWidth: 200, showDelay: 0, - duration: 15000, //specifically for Android - http seems to get stuck at times + duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times }); } @@ -449,6 +452,37 @@ angular.module('zmApp.controllers').service('ZMDataModel', ['$http', '$q', '$ion monitorsLoaded = loaded; }, + //----------------------------------------------------------------------------- + // returns the next monitor ID in the list + // used for swipe next + //----------------------------------------------------------------------------- + getNextMonitor: function(monitorId, direction) + { + var id = parseInt(monitorId); + var foundIndex = -1; + for (var i = 0; i < monitors.length; i++) { + if (parseInt(monitors[i].Monitor.Id) == id) + { + foundIndex = i; + break; + } + } + if (foundIndex != -1) + { + foundIndex = foundIndex + direction; + // wrap around if needed + if (foundIndex < 0) foundIndex = monitors.length - 1; + if (foundIndex >= monitors.length) foundIndex = 0; + return (monitors[foundIndex].Monitor.Id); + } + else + { + zmLog("getNextMonitor could not find monitor "+monitorId); + return (monitorId); + } + + + }, //----------------------------------------------------------------------------- diff --git a/www/js/DevOptionsCtrl.js b/www/js/DevOptionsCtrl.js index eff88e8d..9396ecfa 100644 --- a/www/js/DevOptionsCtrl.js +++ b/www/js/DevOptionsCtrl.js @@ -2,7 +2,7 @@ /* jslint browser: true*/ /* 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) { +angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope', '$rootScope', '$ionicModal','zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', function ($scope, $rootScope, $ionicModal,zm, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading) { $scope.openMenu = function () { @@ -27,7 +27,7 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope' $scope.saveDevOptions = function () { console.log('Saving Dev Options'); - if (parseInt($scope.loginData.maxMontage) > 10) { + if (parseInt($scope.loginData.maxMontage) > zm.safeMontageLimit) { $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' @@ -35,13 +35,13 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope' } - if ((parseInt($scope.loginData.maxFPS) < 0) || (parseInt($scope.loginData.maxFPS) > 30)) { - $scope.loginData.maxFPS = '3'; + if ((parseInt($scope.loginData.maxFPS) < 0) || (parseInt($scope.loginData.maxFPS) > zm.maxFPS)) { + $scope.loginData.maxFPS = zm.defaultFPS.toString(); } - if ((parseInt($scope.loginData.montageQuality) < 10) || (parseInt($scope.loginData.montageQuality) > 70)) { - $scope.loginData.montageQuality = '50'; + if ((parseInt($scope.loginData.montageQuality) < zm.safeMontageLimit) || (parseInt($scope.loginData.montageQuality) > 70)) { + $scope.loginData.montageQuality = zm.defaultMontageQuality.toString(); } diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index dacb5345..eb412575 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -6,7 +6,7 @@ // 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', ['$scope', '$rootScope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', function ($scope, $rootScope, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate) { +angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$scope', '$rootScope','zm', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', function ($scope, $rootScope, zm,ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate) { //--------------------------------------------------- @@ -256,7 +256,7 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$scope', '$r $ionicLoading.show({ template: "please wait...", noBackdrop: true, - duration: 15000, + duration: zm.loadingTimeout, }); } var loginData = ZMDataModel.getLogin(); @@ -462,7 +462,7 @@ angular.module('zmApp.controllers').controller('zmApp.EventCtrl', ['$scope', '$r // don't want to overload segmentHandle = $interval(function () { segmentCheck(); - }, 5000); + }, zm.progressIntervalCheck); segmentCheck(); diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js index 07fdce0b..77409eba 100644 --- a/www/js/EventsGraphsCtrl.js +++ b/www/js/EventsGraphsCtrl.js @@ -8,7 +8,7 @@ // the main function is generateChart. I call generate chart with required parameters // from the template file -angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ionicPlatform', '$scope', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', function ($ionicPlatform, $scope, ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http) { +angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ionicPlatform', '$scope','zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', function ($ionicPlatform, $scope, zm,ZMDataModel, $ionicSideMenuDelegate, $rootScope, $http) { console.log("Inside Graphs controller"); $scope.openMenu = function () { $ionicSideMenuDelegate.toggleLeft(); @@ -103,11 +103,9 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni datasets: [ { label: '', - fillColor: 'rgba(151,187,205,0.5)', - strokeColor: 'rgba(151,187,205,0.8)', - highlightFill: 'rgba(0,163,124,0.5)', - // highlightFill: 'rgba(151,187,205,0.75)', - // highlightStroke: 'rgba(151,187,205,1)', + fillColor: zm.graphFillColor, + strokeColor: zm.graphStrokeColor, + highlightFill: zm.graphHighlightFill, data: [] }, ]}; diff --git a/www/js/LogCtrl.js b/www/js/LogCtrl.js index eb66b71e..d30c4a62 100644 --- a/www/js/LogCtrl.js +++ b/www/js/LogCtrl.js @@ -2,7 +2,7 @@ /* jslint browser: true*/ /* global cordova,StatusBar,angular,console */ -angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', function ($scope, $rootScope, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout) { +angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope','zm', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', function ($scope, $rootScope,zm, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout) { $scope.openMenu = function () { $ionicSideMenuDelegate.toggleLeft(); }; @@ -24,7 +24,7 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo if (res) { $fileLogger.deleteLogfile().then(function () { console.log('Logfile deleted'); - $fileLogger.setStorageFilename('zmNinjaLog.txt'); + $fileLogger.setStorageFilename(zm.logFile); $scope.zmLog.logString = ""; }); } @@ -71,7 +71,7 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo logstring = logstring.replace(re3, "<server>"); var email = { - to: 'pliablepixels+zmNinja@gmail.com', + to: zm.authoremail, subject: 'zmNinja Logs', body: logstring, isHtml: false diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js index 86da2e06..05631b1d 100644 --- a/www/js/LoginCtrl.js +++ b/www/js/LoginCtrl.js @@ -2,7 +2,7 @@ /* jslint browser: true*/ /* global cordova,StatusBar,angular,console */ -angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$rootScope', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', function ($scope, $rootScope, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading) { +angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$rootScope','zm', '$ionicModal', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicPopup', '$http', '$q', '$ionicLoading', function ($scope, $rootScope,zm, $ionicModal, ZMDataModel, $ionicSideMenuDelegate, $ionicPopup, $http, $q, $ionicLoading) { $scope.openMenu = function () { $ionicSideMenuDelegate.toggleLeft(); }; @@ -60,7 +60,7 @@ function addhttp(url) { $scope.save = function () { console.log('Saving login'); - if (parseInt($scope.loginData.maxMontage) > 10) { + if (parseInt($scope.loginData.maxMontage) > zm.safeMontageLimit) { $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' @@ -142,7 +142,7 @@ function addhttp(url) { template: 'Checking data...', animation: 'fade-in', showBackdrop: true, - duration: 15000, + duration: zm.loadingTimeout, maxWidth: 200, showDelay: 0 }); diff --git a/www/js/ModalCtrl.js b/www/js/ModalCtrl.js index e8910585..c5d1f512 100644 --- a/www/js/ModalCtrl.js +++ b/www/js/ModalCtrl.js @@ -4,12 +4,13 @@ /* global cordova,StatusBar,angular,console,ionic */ -angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootScope', 'ZMDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', function ($scope, $rootScope, ZMDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate) { +angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootScope', 'zm','ZMDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', function ($scope, $rootScope,zm, ZMDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate) { console.log("**** INSIDE MODAL CTRL, recomputing rand *****"); $scope.rand = Math.floor((Math.random() * 100000) + 1); + $rootScope.tempmid = $scope.monitorId; //$state.go($state.current, {}, {reload: true}); // This holds the PTZ menu control @@ -156,7 +157,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco $ionicLoading.show({ template: "please wait...", noBackdrop: true, - duration: 15000, + duration: zm.loadingTimeout, }); var loginData = ZMDataModel.getLogin(); @@ -164,7 +165,7 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco $ionicLoading.show({ template: "Sending PTZ..", noBackdrop: true, - duration: 15000, + duration: zm.loadingTimeout, }); @@ -224,6 +225,35 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco }; + $scope.onSwipeLeft = function(m,d) + { + console.log ("SWIPED LEFT"); + console.log ("Next Monitor ID is " + ZMDataModel.getNextMonitor(m,d)); + $scope.monitorId = ZMDataModel.getNextMonitor(m,d); + $rootScope.tempmid = $scope.monitorId; //FIXME: Hack + + $ionicLoading.hide(); + $ionicLoading.show({ + template: "please wait...", + noBackdrop: true, + duration: zm.loadingTimeout, + }); + + }; + + $scope.onSwipeRight = function(m,d) + { + console.log ("SWIPED RIGHT"); + console.log ("Next Monitor ID is " + ZMDataModel.getNextMonitor(m,d)); + $scope.monitorId = ZMDataModel.getNextMonitor(m,d); + $rootScope.tempmid = $scope.monitorId; + + $ionicLoading.show({ + template: "please wait...", + noBackdrop: true, + duration: zm.loadingTimeout, + }); + }; }]); diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js index 02a6dcce..3307c800 100644 --- a/www/js/MonitorCtrl.js +++ b/www/js/MonitorCtrl.js @@ -5,7 +5,7 @@ // controller for Monitor View // refer to comments in EventCtrl for the modal stuff. They are almost the same -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) { +angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopup', 'zm', '$scope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', '$rootScope', function ($ionicPopup, zm, $scope, ZMDataModel, message, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout) { //----------------------------------------------------------------------- @@ -17,9 +17,9 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu $scope.monitors = message; var loginData = ZMDataModel.getLogin(); monitorStateCheck(); - console.log ("Setting Awake to "+ZMDataModel.getKeepAwake()); + console.log("Setting Awake to " + ZMDataModel.getKeepAwake()); ZMDataModel.setAwake(ZMDataModel.getKeepAwake()); - $scope.imageStyle=true; + $scope.imageStyle = true; @@ -122,7 +122,7 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu var str = []; for (var p in obj) str.push(encodeURIComponent(p) + "=" + - encodeURIComponent(obj[p])); + encodeURIComponent(obj[p])); var foo = str.join("&"); console.log("****RETURNING " + foo); return foo; @@ -139,10 +139,9 @@ 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, + duration: zm.largeHttpTimeout, }); $http.post(apiRestart) .then(function (success) { @@ -213,7 +212,7 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu }); $scope.openModal = function (mid, controllable, controlid) { - console.log("Open Monitor Modal with monitor Id=" + mid + " and Controllable:" + controllable + " with control ID:"+controlid); + console.log("Open Monitor Modal with monitor Id=" + mid + " and Controllable:" + controllable + " with control ID:" + controlid); $scope.monitorId = mid; $scope.LoginData = ZMDataModel.getLogin(); @@ -225,22 +224,21 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu ZMDataModel.setAwake(ZMDataModel.getKeepAwake()); // if its controllable, lets get the control command - if (controllable == '1') - { + if (controllable == '1') { var apiurl = $scope.LoginData.apiurl; - var myurl = apiurl+"/controls/"+controlid+".json"; - console.log ("getting control details:"+myurl); + var myurl = apiurl + "/controls/" + controlid + ".json"; + console.log("getting control details:" + myurl); $http.get(myurl) - .success(function(data) { - $scope.ptzMoveCommand = (data.control.Control.CanMoveCon == '1')? 'moveCon':'move'; - console.log("***moveCommand: " +$scope.ptzMoveCommand ); - ZMDataModel.zmLog ("ControlDB reports PTZ command to be " + $scope.ptzMoveCommand ); - }) - .error(function(data) { - console.log ("** Error retrieving move PTZ command"); - ZMDataModel.zmLog ("Error retrieving PTZ command " + JSON.stringify(data),"error"); - }); + .success(function (data) { + $scope.ptzMoveCommand = (data.control.Control.CanMoveCon == '1') ? 'moveCon' : 'move'; + console.log("***moveCommand: " + $scope.ptzMoveCommand); + ZMDataModel.zmLog("ControlDB reports PTZ command to be " + $scope.ptzMoveCommand); + }) + .error(function (data) { + console.log("** Error retrieving move PTZ command"); + ZMDataModel.zmLog("Error retrieving PTZ command " + JSON.stringify(data), "error"); + }); } @@ -255,7 +253,7 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu $ionicLoading.show({ template: "please wait...", noBackdrop: true, - duration: 15000 + duration: zm.loadingTimeout }); $scope.isControllable = controllable; $scope.showPTZ = false; @@ -293,11 +291,11 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu // The status is provided by zmdc.pl // "not running", "pending", "running since", "Unable to connect" var i; - for ( i = 0; i < $scope.monitors.length; i++) { + for (i = 0; i < $scope.monitors.length; i++) { (function (j) { $scope.monitors[j].Monitor.isRunningText = "..."; $scope.monitors[j].Monitor.isRunning = "..."; - $scope.monitors[j].Monitor.color = '#03A9F4'; + $scope.monitors[j].Monitor.color = zm.monitorCheckingColor; $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); @@ -305,17 +303,17 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu .success(function (data) { if (data.statustext.indexOf("not running") > -1) { $scope.monitors[j].Monitor.isRunning = "false"; - $scope.monitors[j].Monitor.color = '#F44336'; + $scope.monitors[j].Monitor.color = zm.monitorNotRunningColor; $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 = '#FF9800'; + $scope.monitors[j].Monitor.color = zm.monitorPendingColor; } else if (data.statustext.indexOf("running since") > -1) { $scope.monitors[j].Monitor.isRunning = "true"; - $scope.monitors[j].Monitor.color = '#4CAF50'; + $scope.monitors[j].Monitor.color = zm.monitorRunningColor; } else if (data.statustext.indexOf("Unable to connect") > -1) { $scope.monitors[j].Monitor.isRunning = "false"; - $scope.monitors[j].Monitor.color = '#F44336'; + $scope.monitors[j].Monitor.color = zm.monitorNotRunningColor; $scope.monitors[j].Monitor.char = "ion-close-circled"; } @@ -324,7 +322,7 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu }) .error(function (data) { $scope.monitors[j].Monitor.isRunning = "error"; - $scope.monitors[j].Monitor.color = '#795548'; + $scope.monitors[j].Monitor.color = zm.monitorErrorColor; $scope.monitors[j].Monitor.char = "ion-help-circled"; }); @@ -349,10 +347,82 @@ angular.module('zmApp.controllers').controller('zmApp.MonitorCtrl', ['$ionicPopu }; - $scope.scaleImage = function() { - console.log ("Switching image style"); + $scope.scaleImage = function () { + console.log("Switching image style"); $scope.imageStyle = !$scope.imageStyle; }; + function SaveSuccess() { + $ionicLoading.show({ + template: "done!", + noBackdrop: true, + duration: 1000 + }); + console.log("***SUCCESS"); + } + + + function SaveError(e) { + $ionicLoading.show({ + template: "error - could not save", + noBackdrop: true, + duration: 2000 + }); + ZMDataModel.zmLog("Error saving image: " + e.message); + console.log("***ERROR"); + } + + //----------------------------------------------------------------------- + // Saves a snapshot of the monitor image to phone storage + //----------------------------------------------------------------------- + + //http://stackoverflow.com/questions/11618266/save-a-web-photo-to-camera-roll-in-phonegap + $scope.saveImageToPhone = function (mid) { + $ionicLoading.show({ + template: "saving snapshot..", + noBackdrop: true, + duration: zm.httpTimeout + }); + + console.log("IMAGE CAPTURE"); + var canvas, context, imageDataUrl, imageData; + var loginData = ZMDataModel.getLogin(); + var url = loginData.streamingurl + + '/cgi-bin/zms?mode=single&monitor=' + $rootScope.tempmid + + '&user=' + loginData.username + + '&pass=' + loginData.password; + ZMDataModel.zmLog("SavetoPhone:Trying to save image from " + url); + + var img = new Image(); + img.onload = function () { + canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + context = canvas.getContext('2d'); + context.drawImage(img, 0, 0); + try { + imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); + imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); + cordova.exec( + SaveSuccess, + SaveError, + 'Canvas2ImagePlugin', + 'saveImageDataToLibrary', [imageData] + ); + } catch (e) { + + SaveError(e.message); + } + }; + try { + img.src = url; + } catch (e) { + SaveError(e.message); + + } + }; + + + }]); diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index 20843a94..420b6f12 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -4,7 +4,7 @@ /* global cordova,StatusBar,angular,console,ionic */ -angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '$rootScope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', function ($scope, $rootScope, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate) { +angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', '$rootScope', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', 'zm', function ($scope, $rootScope, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, zm) { //--------------------------------------------------------------------- // Controller main @@ -376,6 +376,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' // Note: no need to setAwake(true) as its already awake // in montage view $scope.monitorId = mid; + $scope.LoginData = ZMDataModel.getLogin(); $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111; $scope.ptzMoveCommand = ""; @@ -413,7 +414,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' $ionicLoading.show({ template: "please wait...", noBackdrop: true, - duration: 15000 + duration: zm.loadingTimeout }); $scope.isControllable = controllable; $scope.showPTZ = false; @@ -463,7 +464,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' //--------------------------------------------------------------------- // if you long press on a montage window, it calls scale montage - // at a 200ms freq + // at a 300 freq //--------------------------------------------------------------------- $scope.onHold = function (index) { montageIndex = index; @@ -471,8 +472,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' intervalHandleMontage = $interval(function () { scaleMontage(); - }.bind(this), 200); - + }.bind(this), zm.montageScaleFrequency); + console.log("**************" + zm.montageScaleFrequency); }; //--------------------------------------------------------------------- @@ -592,6 +593,76 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' $rootScope.rand = Math.floor((Math.random() * 100000) + 1); }); + function SaveSuccess() { + $ionicLoading.show({ + template: "done!", + noBackdrop: true, + duration: 1000 + }); + console.log("***SUCCESS"); + } + + function SaveError(e) { + $ionicLoading.show({ + template: "error - could not save", + noBackdrop: true, + duration: 2000 + }); + ZMDataModel.zmLog("Error saving image: " + e.message); + console.log("***ERROR"); + } + + //----------------------------------------------------------------------- + // Saves a snapshot of the monitor image to phone storage + //----------------------------------------------------------------------- + + + $scope.saveImageToPhone = function (mid) { + $ionicLoading.show({ + template: "saving snapshot..", + noBackdrop: true, + duration: zm.httpTimeout + }); + + console.log("IMAGE CAPTURE"); + var canvas, context, imageDataUrl, imageData; + var loginData = ZMDataModel.getLogin(); + var url = loginData.streamingurl + + '/cgi-bin/zms?mode=single&monitor=' + $rootScope.tempmid + + '&user=' + loginData.username + + '&pass=' + loginData.password; + ZMDataModel.zmLog("SavetoPhone:Trying to save image from " + url); + + var img = new Image(); + img.onload = function () { + canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + context = canvas.getContext('2d'); + context.drawImage(img, 0, 0); + try { + imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); + imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); + cordova.exec( + SaveSuccess, + SaveError, + 'Canvas2ImagePlugin', + 'saveImageDataToLibrary', [imageData] + ); + } catch (e) { + + SaveError(e.message); + } + }; + try { + img.src = url; + } catch (e) { + SaveError(e.message); + + } + }; + + @@ -607,8 +678,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', ['$scope', ' }; - $scope.scaleImage = function() { - console.log ("Switching image style"); + $scope.scaleImage = function () { + console.log("Switching image style"); $scope.imageStyle = !$scope.imageStyle; }; diff --git a/www/js/StateCtrl.js b/www/js/StateCtrl.js index 08bdf06e..29cf04e0 100644 --- a/www/js/StateCtrl.js +++ b/www/js/StateCtrl.js @@ -4,7 +4,7 @@ // controller for State View -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) { +angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup', '$scope', 'zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', function ($ionicPopup, $scope,zm, ZMDataModel, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope) { //---------------------------------------------------------------------- // Controller main diff --git a/www/js/app.js b/www/js/app.js index ad047864..870c041e 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -14,6 +14,33 @@ angular.module('zmApp', [ ]) +.constant('zm', { + httpTimeout:15000, + largeHttpTimeout:60000, + logFile:'zmNinjaLog.txt', + authoremail:'pliablepixels+zmNinja@gmail.com', + logFileMaxSize: 50000, + loginInterval:300000, //5m*60s*1000 + loadingTimeout:15000, + safeMontageLimit:10, + maxFPS:30, + defaultFPS:3, + maxMontageQuality:70, + defaultMontageQuality:50, + progressIntervalCheck:5000, + graphFillColor:'rgba(151,187,205,0.5)', + graphStrokeColor: 'rgba(151,187,205,0.8)', + graphHighlightFill: 'rgba(0,163,124,0.5)', + monitorCheckingColor:'#03A9F4', + monitorNotRunningColor: '#F44336', + monitorPendingColor: '#FF9800', + monitorRunningColor: '#4CAF50', + monitorErrorColor: '#795548', + montageScaleFrequency:300 + + + +}) //------------------------------------------------------------------ // this directive will be load any time an image completes loading @@ -36,6 +63,7 @@ angular.module('zmApp', [ }; }) + //------------------------------------------------------------------ // In Android, HTTP requests seem to get stuck once in a while // It may be a crosswalk issue. @@ -44,7 +72,7 @@ angular.module('zmApp', [ // 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) { +.factory('timeoutHttpIntercept', function ($rootScope, $q,zm) { return { 'request': function (config) { if ( !(config.url.indexOf("/api/states/change/") > -1 || @@ -67,7 +95,7 @@ angular.module('zmApp', [ // This service automatically logs into ZM at periodic intervals //------------------------------------------------------------------ -.factory('zmAutoLogin', function($interval, ZMDataModel, $http) { +.factory('zmAutoLogin', function($interval, ZMDataModel, $http,zm) { var zmAutoLoginHandle; function doLogin() { @@ -118,7 +146,7 @@ angular.module('zmApp', [ { doLogin(); - },5*60*1000); // Auto login every 5 minutes + },zm.loginInterval); // Auto login every 5 minutes // PHP timeout is around 10 minutes // should be ok? } @@ -165,7 +193,7 @@ angular.module('zmApp', [ // First run in ionic //------------------------------------------------------------------ -.run(function ($ionicPlatform, $ionicPopup, $rootScope, $state, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, $fileLogger,$timeout, $ionicHistory, $window) +.run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, ZMDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, $fileLogger,$timeout, $ionicHistory, $window, $ionicSideMenuDelegate) { ZMDataModel.init(); @@ -178,16 +206,13 @@ angular.module('zmApp', [ } - $ionicPlatform.registerBackButtonAction(function (event) { - console.log("STATE NAME IS " + $ionicHistory.currentStateName()); - - if ($ionicHistory.currentStateName() == "whatd do I put here?") { - $ionicPlatform.exitApp(); - - } else { - // do something else + // This code takes care of trapping the Android back button + // and takes it to the menu. FIXME: For some reason, isOpen of Side + // MenuDelegate always returns False, so I don't know + // when its on or off, so can't exit the app if its on - } + $ionicPlatform.registerBackButtonAction(function (event) { + $ionicSideMenuDelegate.toggleLeft(); }, 100); // this works reliably on both Android and iOS. The "onorientation" seems to reverse w/h in Android. Go figure. @@ -238,7 +263,7 @@ angular.module('zmApp', [ $fileLogger.checkFile().then(function(resp) { - if (parseInt(resp.size) > 50000) + if (parseInt(resp.size) > zm.logFileMaxSize) { console.log ("Deleting old log file as it exceeds 50K bytes"); $fileLogger.deleteLogfile().then(function() @@ -257,7 +282,7 @@ angular.module('zmApp', [ //fileLogger is an excellent cross platform library // that allows you to manage log files without worrying about // paths etc.https://github.com/pbakondy/filelogger - $fileLogger.setStorageFilename('zmNinjaLog.txt'); + $fileLogger.setStorageFilename(zm.logFile); if (window.cordova) { diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html index e1d5c98a..aa87844e 100644 --- a/www/templates/monitors-modal.html +++ b/www/templates/monitors-modal.html @@ -6,12 +6,15 @@ <ion-scroll has-bouncing=false min-zoom=1 zooming="true" direction="xy" style="width: 100%; "> <!-- android needs this 100vh - otherwise max- does not work --> + <div style="height: 100vh;"> <img imageonload="finishedLoadingImage()" - ng-src="{{LoginData.streamingurl}}/cgi-bin/zms?mode=jpeg&monitor={{monitorId}}&maxfps={{LoginData.maxFPS}}&buffer=1000&user={{LoginData.username}}&pass={{LoginData.password}}&rand={{rand}}" ng-class="{'zm-image-fit':imageStyle==true, 'zm-image-crop':imageStyle==false}" /> + ng-src="{{LoginData.streamingurl}}/cgi-bin/zms?mode=jpeg&monitor={{monitorId}}&maxfps={{LoginData.maxFPS}}&buffer=1000&user={{LoginData.username}}&pass={{LoginData.password}}&rand={{rand}}" ng-class="{'zm-image-fit':imageStyle==true, 'zm-image-crop':imageStyle==false}" on-swipe-left="onSwipeLeft(monitorId,-1)" on-swipe-right="onSwipeRight(monitorId,1)" fade-in /> + </div> + </ion-scroll> </ion-content> @@ -31,3 +34,10 @@ <button mfb-button icon="ion-arrow-expand" label="pan/tilt/zoom" ng-click="togglePTZ();"></button> <button mfb-button icon="ion-close" label="exit live view" ng-click="closeModal();"></button> </nav> + +<span class="camera-icon"> + <a class="button icon ion-ios-camera button-positive" href="" ng-click="saveImageToPhone(tempmid)"></a> +</span> + + + diff --git a/www/templates/montage.html b/www/templates/montage.html index d63a3bcd..13f21952 100644 --- a/www/templates/montage.html +++ b/www/templates/montage.html @@ -26,7 +26,7 @@ </ion-nav-buttons> - <ion-content has-bouncing="false" > + <ion-content has-bouncing="false" style="background-color:#FEFEFE"> <div ng-controller="ModalCtrl"> <ion-refresher pulling-text="Pull to reload Monitors..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher> <span ng-show="!minimal"> |
