diff options
Diffstat (limited to 'www')
| -rw-r--r-- | www/css/style.css | 17 | ||||
| -rw-r--r-- | www/index.html | 3 | ||||
| -rw-r--r-- | www/js/DevOptionsCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/EventCtrl.js | 44 | ||||
| -rw-r--r-- | www/js/EventDateTimeFilterCtrl.js | 6 | ||||
| -rw-r--r-- | www/js/EventServerSettingsCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/EventsGraphsCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/HelpCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/LogCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/LoginCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/MonitorCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/MontageCtrl.js | 10 | ||||
| -rw-r--r-- | www/js/MontageHistoryCtrl.js | 493 | ||||
| -rw-r--r-- | www/js/NewsCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/PortalLoginCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/StateCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/TimelineCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/TimelineModalCtrl.js | 3 | ||||
| -rw-r--r-- | www/js/app.js | 68 | ||||
| -rw-r--r-- | www/lang/locale-en.json | 5 | ||||
| -rw-r--r-- | www/templates/events-modal.html | 3 | ||||
| -rw-r--r-- | www/templates/montage-history.html | 372 |
22 files changed, 571 insertions, 486 deletions
diff --git a/www/css/style.css b/www/css/style.css index 96dd7aee..09acc566 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -866,6 +866,10 @@ body { background: rgba(108, 122, 137, 0.7); z-index: -1; } + +#flyoutmenu li:active { + background:#3498db; +} #flyoutmenu a { text-decoration: none; color: white; @@ -890,6 +894,19 @@ body { opacity: 1; z-index: 99; } + +#history_canvas_video { + position: absolute; + width: 95%; + top:10%; + height: 20px; + + opacity: 1; + z-index: 99; +} + + + #event_slider { position: absolute; width: 80%; diff --git a/www/index.html b/www/index.html index df6cdf13..35c4405b 100644 --- a/www/index.html +++ b/www/index.html @@ -69,6 +69,7 @@ <script src="external/draggabilly.pkgd.js"></script> <script src="external/ionic.scroll.sista.js"></script> <script src="external/angular-circular-navigation.js"></script> + <script src="external/Chart2.min.js"></script> @@ -164,7 +165,7 @@ </span>{{'kMenuTimeline'|translate}} </ion-item> - <ion-item href="#/events/0" menu-close> + <ion-item href="#/events/0/false" menu-close> <span class=" item-icon-left"> <i class="icon ion-ios-calendar-outline"></i> </span>{{'kMenuEvents'|translate}} diff --git a/www/js/DevOptionsCtrl.js b/www/js/DevOptionsCtrl.js index 7ca09068..5e75df04 100644 --- a/www/js/DevOptionsCtrl.js +++ b/www/js/DevOptionsCtrl.js @@ -22,7 +22,8 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope' disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 627b8fff..3aa4b6a2 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -84,6 +84,13 @@ angular.module('zmApp.controllers') document.addEventListener("pause", onPause, false); //console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id, 10); + $scope.showEvent = $stateParams.playEvent || false; + + console.log (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + + + NVRDataModel.log ("EventCtrl called with: EID=" + $scope.id + " playEvent = "+$scope.showEvent); + // This is the only view that hardcodes row size due to // collection repeat, so lets re-get the text size if it has changed // note that there may be a delay as its a callback - so might involve @@ -154,6 +161,34 @@ angular.module('zmApp.controllers') + function getEventObject(eid) + { + + var apiurl = NVRDataModel.getLogin().apiurl + '/events/'+eid+'.json'; + + $http.get (apiurl) + .success (function (data) { + }) + .error (function (err) { + }); + /* + myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime); + myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId); + // now construct base path + + myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId); + myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId); + myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId); + // console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL); + + // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL); + + myevents[i].Event.ShowScrub = false; + myevents[i].Event.BasePath = computeBasePath(myevents[i]); + myevents[i].Event.relativePath = computeRelativePath(myevents[i]); + */ + } + function getTextZoomCallback(tz) { @@ -667,7 +702,8 @@ angular.module('zmApp.controllers') // reloading - may solve https://github.com/pliablepixels/zmNinja/issues/36 // if you are in the same mid event page $state.go won't work $state.go("events", { - "id": monitorId + "id": monitorId, + "playEvent":false }, { reload: true }); @@ -684,7 +720,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); @@ -754,7 +791,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }); } else { NVRDataModel.log("Filter reset cancelled in popup"); diff --git a/www/js/EventDateTimeFilterCtrl.js b/www/js/EventDateTimeFilterCtrl.js index f9e982f5..4047fa1e 100644 --- a/www/js/EventDateTimeFilterCtrl.js +++ b/www/js/EventDateTimeFilterCtrl.js @@ -18,7 +18,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); @@ -50,7 +51,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }); //$ionicHistory.goBack(); diff --git a/www/js/EventServerSettingsCtrl.js b/www/js/EventServerSettingsCtrl.js index 298d9aa4..48417420 100644 --- a/www/js/EventServerSettingsCtrl.js +++ b/www/js/EventServerSettingsCtrl.js @@ -26,7 +26,8 @@ $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js index 98859649..2273598e 100644 --- a/www/js/EventsGraphsCtrl.js +++ b/www/js/EventsGraphsCtrl.js @@ -30,7 +30,8 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/HelpCtrl.js b/www/js/HelpCtrl.js index 53dc91b0..328fbfda 100644 --- a/www/js/HelpCtrl.js +++ b/www/js/HelpCtrl.js @@ -19,7 +19,8 @@ angular.module('zmApp.controllers').controller('zmApp.HelpCtrl', ['$scope', '$ro disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/LogCtrl.js b/www/js/LogCtrl.js index 67f2d185..388af6a7 100644 --- a/www/js/LogCtrl.js +++ b/www/js/LogCtrl.js @@ -63,7 +63,8 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js index a13941c6..e076cc18 100644 --- a/www/js/LoginCtrl.js +++ b/www/js/LoginCtrl.js @@ -51,7 +51,8 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js index fd0c2780..865e0e3a 100644 --- a/www/js/MonitorCtrl.js +++ b/www/js/MonitorCtrl.js @@ -66,7 +66,8 @@ angular.module('zmApp.controllers') $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index 6910f148..6b48897d 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -222,9 +222,9 @@ angular.module('zmApp.controllers') } - + pckry.shiftLayout(); $timeout (function () { - pckry.layout();},300); + pckry.shiftLayout();},300); @@ -512,7 +512,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); @@ -535,7 +536,8 @@ angular.module('zmApp.controllers') disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/MontageHistoryCtrl.js b/www/js/MontageHistoryCtrl.js index c0188d2d..c27e1c44 100644 --- a/www/js/MontageHistoryCtrl.js +++ b/www/js/MontageHistoryCtrl.js @@ -1,12 +1,12 @@ // Controller for the montage view -/* jshint -W041 */ +/* jshint -W041, -W093 */ /* jslint browser: true*/ -/* global cordova,StatusBar,angular,console,ionic,Masonry,moment,Packery, Draggabilly, imagesLoaded */ +/* global cordova,StatusBar,angular,console,ionic,Masonry,moment,Packery, Draggabilly, imagesLoaded, Chart */ // FIXME: This is a copy of montageCtrl - needs a lot of code cleanup -angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$scope', '$rootScope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', 'zm', '$ionicPopover', '$controller', 'imageLoadingDataShare', '$window', '$translate', function ($scope, $rootScope, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, zm, $ionicPopover, $controller, imageLoadingDataShare, $window, $translate) { +angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$scope', '$rootScope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', 'zm', '$ionicPopover', '$controller', 'imageLoadingDataShare', '$window', '$translate', 'qHttp', function ($scope, $rootScope, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, zm, $ionicPopover, $controller, imageLoadingDataShare, $window, $translate, qHttp) { @@ -49,13 +49,19 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc return moment(str).format(NVRDataModel.getTimeFormat() + ' on MMMM Do YYYY'); }; + $scope.humanizeTime = function (str) { + return moment(str).fromNow(); + + }; + // if you change date in footer, change hrs $scope.dateChanged = function() { - console.log ("DATE CHANGED"); + $scope.datetimeValueFrom.hrs = Math.round(moment.duration(moment().diff(moment($scope.datetimeValueFrom.value))).asHours()); }; + // if you change hrs in footer, change date $scope.hrsChanged = function() { $scope.datetimeValueFrom.value = moment().subtract($scope.datetimeValueFrom.hrs,'hours').toDate(); @@ -71,13 +77,9 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }); } - $scope.toggleSizeButtons = function () { - - $scope.showSizeButtons = !$scope.showSizeButtons; - - NVRDataModel.debug("toggling size buttons:" + $scope.showSizeButtons); - if ($scope.showSizeButtons) $ionicScrollDelegate.$getByHandle("montage-delegate").scrollTop(); - }; + + + //-------------------------------------- // pause/unpause nph-zms @@ -101,12 +103,54 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc controlEventStream(cmd, "", $scope.MontageMonitors[m].Monitor.connKey, -1); } }; + + + function sendCmd (mid, cmd, extra) + { + var m = -1; + for (var i = 0; i < $scope.MontageMonitors.length; i++) { + if ($scope.MontageMonitors[i].Monitor.Id == mid) { + m = i; + break; + } + } + if (m != -1) { - $scope.humanizeTime = function (str) { - return moment(str).fromNow(); - + NVRDataModel.debug("Sending CMD:" + cmd + " for monitor " + $scope.MontageMonitors[m].Monitor.Name); + controlEventStream(cmd, "", $scope.MontageMonitors[m].Monitor.connKey, -1, extra); + + } + } + + + $scope.seek = function (mid, p) + { + console.log ("SLIDER CALLED WITH MID="+mid+" progress="+p); + sendCmd (mid, '14', "&offset="+p); + + }; + + $scope.moveFaster = function (mid) + { + sendCmd (mid,4); + }; + + $scope.moveSlower = function (mid) + { + sendCmd (mid,5); }; + + + $scope.movePlay = function (mid) + { + sendCmd (mid,2); + }; + + + + + //-------------------------------------- // Called when ion-footer collapses @@ -120,23 +164,18 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.footerCollapse = function () { - footerCollapse(); - - }; /* Note this is also called when the view is first loaded */ function footerCollapse() { - // console.log ("**************** COLLAPSE CALLED ***************"); + if (readyToRun == false) { NVRDataModel.debug("fake call to footerCollapse - ignoring"); return; } - - $scope.dragBorder = ""; $scope.isDragabillyOn = false; $ionicSideMenuDelegate.canDragContent(true); @@ -145,22 +184,15 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var ld = NVRDataModel.getLogin(); $scope.sliderVal.realRate = $scope.sliderVal.rate * 100; - //NVRDataModel.debug ("Playback rate is:" + $scope.sliderVal.realRate); - var TimeObjectFrom = moment($scope.datetimeValueFrom.value).format("YYYY-MM-DD HH:mm"); - - //var TimeObjectTo = moment($scope.datetimeValueTo.value).format('YYYY-MM-DD HH:mm'); var TimeObjectTo = moment().format('YYYY-MM-DD HH:mm'); - // console.log ("TIME START: " + TimeObjectFrom + " " + TimeObjectTo); - //console.log ("TIME START: " + TimeObjectFrom + " " + TimeObjectTo); - - var apiurl; // release all active streams for (var i = 0; i < $scope.MontageMonitors.length; i++) { $scope.MontageMonitors[i].Monitor.selectStyle = ""; + $scope.MontageMonitors[i].Monitor.eid = "-1"; // generate new connKeys if timeline changes if ($scope.MontageMonitors[i].Monitor.eventUrl != 'img/noevent.png') { // this means this mid was showing a message, now we need to change it @@ -169,17 +201,16 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var tmpCK = angular.copy($scope.MontageMonitors[i].Monitor.connKey); timedControlEventStream(2500, 17, "", tmpCK, -1); $scope.MontageMonitors[i].Monitor.eventUrl = "img/noevent.png"; + $scope.MontageMonitors[i].Monitor.eid = "-1"; $scope.MontageMonitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString(); //console.log ("Generating connkey: " +$scope.MontageMonitors[i].Monitor.connKey); - } else { - //console.log ("footerCollapse: Skipped kill: connkey:"+$scope.MontageMonitors[i].Monitor.connKey + " function " + $scope.MontageMonitors[i].Monitor.Function + " listDisplay " + $scope.MontageMonitors[i].Monitor.lisDisplay + " enabled " + $scope.MontageMonitors[i].Monitor.Enabled + " eventURL " + $scope.MontageMonitors[i].Monitor.eventUrl); - } + } } // grab events that start on or before the time and end on or after the time // this should only bring up events that span that time - //apiurl = ld.apiurl + "/events/index/StartTime >=:" + TimeObjectFrom + "/EndTime <=:" + TimeObjectTo + ".json"; + apiurl = ld.apiurl + "/events/index/StartTime >=:" + TimeObjectFrom + "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0)+ ".json"; @@ -187,9 +218,10 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc // make sure there are no more than 5 active streams (noevent is ok) $scope.currentLimit = $scope.monLimit; - $http.get(apiurl) - .success(function (data) { - + //qHttp.get(apiurl) + qHttp({method:'get', url:apiurl}) + .then(function (succ) { + var data = succ.data; var ld = NVRDataModel.getLogin(); NVRDataModel.debug("Got " + data.events.length + "new history events..."); var eid, mid, stime; @@ -218,6 +250,11 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.MontageMonitors[j].Monitor.eventUrlTime = stime; + $scope.MontageMonitors[j].Monitor.eid = eid; + $scope.MontageMonitors[j].Monitor.eventDuration = data.events[i].Event.Length; + $scope.MontageMonitors[j].Monitor.sliderProgress = {progress:0}; + + console.log (">>> Setting Event for " + $scope.MontageMonitors[j].Monitor.Name+" to " +eid); } } @@ -255,29 +292,23 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc draggies = []; // destroy existing packery object pckry.destroy(); - initPackery(); - - - - - + } - }) - .error(function (data) { - NVRDataModel.debug("history ERROR:" + JSON.stringify(data)); - - }); - + }, + function (err) {NVRDataModel.debug("history ERROR:" + JSON.stringify(err));} ); + + function getExpandedEvents(i, indivGrab) { var ld = NVRDataModel.getLogin(); // console.log ("EXPANDED EVENT " + i + " " + indivGrab); - $http.get(indivGrab) - .success(function (data) { + qHttp({method:'get', url:indivGrab}) + .then(function (succ) { + var data = succ.data; // console.log ("EXPANDED DATA FOR MONITOR " + i + JSON.stringify(data)); if (data.events.length > 0) { @@ -292,6 +323,11 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc //console.log ("SWITCHING TO " + $scope.MontageMonitors[i].eventUrl); $scope.MontageMonitors[i].Monitor.eventUrlTime = data.events[0].Event.StartTime; + $scope.MontageMonitors[i].Monitor.eid = data.events[0].Event.Id; + $scope.MontageMonitors[i].Monitor.sliderProgress = {progress:0}; + + $scope.MontageMonitors[i].Monitor.eventDuration = data.events[0].Event.Length; + console.log (">>> Setting Event for " + $scope.MontageMonitors[i].Monitor.Name+" to " +data.events[0].Event.Id); NVRDataModel.log("Found expanded event " + data.events[0].Event.Id + " for monitor " + $scope.MontageMonitors[i].Monitor.Id); } else { @@ -301,8 +337,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc } } - }) - .error(function (data) {}); + }); + } } @@ -315,7 +351,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc function checkAllEvents() { - //console.log ("Events are checked...."); + console.log ("Timer:Events are checked...."); for (var i = 0; i < $scope.MontageMonitors.length; i++) { // don't check for monitors that are not shown @@ -325,7 +361,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.MontageMonitors[i].Monitor.Function != 'None' && $scope.MontageMonitors[i].Monitor.listDisplay != 'noshow' && $scope.MontageMonitors[i].Monitor.Enabled != '0') { - NVRDataModel.debug("Checking event status for " + $scope.MontageMonitors[i].Monitor.Name + ":" + $scope.MontageMonitors[i].Monitor.eventUrl + ":" + $scope.MontageMonitors[i].Monitor.Function + ":" + $scope.MontageMonitors[i].Monitor.listDisplay); + // NVRDataModel.debug("Checking event status for " + $scope.MontageMonitors[i].Monitor.Name + ":" + $scope.MontageMonitors[i].Monitor.eventUrl + ":" + $scope.MontageMonitors[i].Monitor.Function + ":" + $scope.MontageMonitors[i].Monitor.listDisplay); + // console.log ("Sending query 99 for " + $scope.MontageMonitors[i].Monitor.Name + " with ck="+$scope.MontageMonitors[i].Monitor.connKey); controlEventStream('99', '', $scope.MontageMonitors[i].Monitor.connKey, i); } @@ -357,7 +394,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var loginData = NVRDataModel.getLogin(); var myauthtoken = $rootScope.authSession.replace("&auth=", ""); //&auth= - var req = $http({ + var req = qHttp({ method: 'POST', /*timeout: 15000,*/ url: loginData.url + '/index.php', @@ -386,18 +423,16 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc } }); - req.success(function (resp) { - NVRDataModel.debug("subControl success:" + JSON.stringify(resp)); - }); + req.then(function (succ) { + NVRDataModel.debug("subControl success:" + JSON.stringify(succ)); + }, + function (err) {NVRDataModel.debug("subControl error:" + JSON.stringify(err));}); - req.error(function (resp) { - NVRDataModel.debug("subControl error:" + JSON.stringify(resp)); - }); } - function controlEventStream(cmd, disp, connkey, ndx) { + function controlEventStream(cmd, disp, connkey, ndx, extras) { // console.log("Command value " + cmd); if (disp) { @@ -409,6 +444,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }); } var loginData = NVRDataModel.getLogin(); + /* var CMD_NONE = 0; @@ -442,7 +478,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var myauthtoken = $rootScope.authSession.replace("&auth=", ""); //&auth= - var req = $http({ + var req = qHttp({ method: 'POST', /*timeout: 15000,*/ url: loginData.url + '/index.php', @@ -456,7 +492,9 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); var foo = str.join("&"); - // console.log("****RETURNING " + foo); + if (extras) + foo = foo + extras; + //console.log("****RETURNING " + foo); return foo; }, @@ -470,22 +508,65 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc // pass: loginData.password } }); - req.success(function (resp) { + req.then(function (succ) { - // console.log("SUCCESS FOR: " + JSON.stringify(resp)); + var resp = succ.data; + //console.log("SUCCESS FOR: " + JSON.stringify(resp)); - if (resp.result == "Ok" && ndx != -1) { + //SUCCESS FOR: {"result":"Ok","status":{"type":3,"event":29621,"progress":1,"rate":1,"zoom":"1.0","paused":0}} + //$scope.MontageMonitors[ndx].Monitor.eid = data.event.Event.Id; + + if (resp.result == "Ok" && ndx != -1 && (resp.status.event == $scope.MontageMonitors[ndx].Monitor.eid)) + $scope.MontageMonitors[ndx].Monitor.sliderProgress.progress = resp.status.progress; + + if (resp.result == "Ok" && ndx != -1 && (resp.status.event != $scope.MontageMonitors[ndx].Monitor.eid) ) { + // $scope.MontageMonitors[ndx].Monitor.sliderProgress.progress = 0; + NVRDataModel.debug ("Fetching details, as event changed for " + $scope.MontageMonitors[ndx].Monitor.Name+" from " + $scope.MontageMonitors[ndx].Monitor.eid + " to " +resp.status.event); var ld = NVRDataModel.getLogin(); var apiurl = ld.apiurl + "/events/" + resp.status.event + ".json"; //console.log ("API " + apiurl); - $http.get(apiurl) - .success(function (data) { + qHttp({method:'get', url:apiurl}) + .then(function (succ) { + var data = succ.data; var currentEventTime = moment(data.event.Event.StartTime); var maxTime = moment(); //NVRDataModel.debug ("Monitor: " + $scope.MontageMonitors[ndx].Monitor.Id + " max time="+maxTime + "("+$scope.datetimeValueTo.value+")"+ " current="+currentEventTime + "("+data.event.Event.StartTime+")"); if ($scope.MontageMonitors[ndx].Monitor.eventUrlTime != data.event.Event.StartTime && currentEventTime.diff(maxTime) <= 0) { + + var framearray = { + + labels: [], + datasets: [{ + + backgroundColor: 'rgba(242, 12, 12, 0.5)', + borderColor: 'rgba(242, 12, 12, 0.5)', + data: [], + }] + }; + + + framearray.labels = []; var ld = NVRDataModel.getLogin(); + console.log (">>>>> GRAPH"); + for (i=0; i<data.event.Frame.length; i++) + { + var ts = moment(data.event.Frame[i].TimeStamp).format(timeFormat); + + //console.log ("pushing s:" + event.Frame[i].Score+" t:"+ts); + + framearray.datasets[0].data.push({ + x: ts, + y: data.event.Frame[i].Score + }); + framearray.labels.push(""); + + } + $timeout(function () { + drawGraph(framearray,$scope.MontageMonitors[ndx].Monitor.Id); + }, 500); + + var element = angular.element(document.getElementById($scope.MontageMonitors[ndx].Monitor.Id + "-timeline")); element.removeClass('animated flipInX'); element.addClass('animated flipOutX'); @@ -496,6 +577,13 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var bw = NVRDataModel.getBandwidth() == "lowbw" ? zm.eventMontageQualityLowBW : ld.montageHistoryQuality; $scope.MontageMonitors[ndx].Monitor.eventUrl = ld.streamingurl + "/nph-zms?source=event&mode=jpeg&event=" + data.event.Event.Id + "&frame=1&replay=gapless&rate=" + $scope.sliderVal.realRate + "&connkey=" + $scope.MontageMonitors[ndx].Monitor.connKey + "&scale=" + bw + "&rand=" + $rootScope.rand; + $scope.MontageMonitors[ndx].Monitor.eid = data.event.Event.Id; + + $scope.MontageMonitors[ndx].Monitor.sliderProgress = {progress:0}; + $scope.MontageMonitors[ndx].Monitor.eventDuration = data.event.Event.Length; + console.log (">>> Setting Event for " + $scope.MontageMonitors[ndx].Monitor.Name+" to " +data.event.Event.Id); + + }, 700); } else if (currentEventTime.diff(maxTime) > 0) { @@ -505,18 +593,18 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc } - }) - .error(function (data) { - $scope.MontageMonitors[ndx].Monitor.eventUrlTime = "-"; - }); + }, + function (err) {$scope.MontageMonitors[ndx].Monitor.eventUrlTime = "-"; } + ); + } - }); + }, + function (err) { NVRDataModel.log("Error sending event command " + JSON.stringify(err), "error");} + + ); - req.error(function (resp) { - //console.log("ERROR: " + JSON.stringify(resp)); - NVRDataModel.log("Error sending event command " + JSON.stringify(resp), "error"); - }); + } @@ -537,7 +625,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); @@ -559,7 +648,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false, }, { reload: true }); @@ -583,26 +673,15 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc - //--------------------------------------------------------------------- - // Triggered when you enter/exit full screen - //--------------------------------------------------------------------- - $scope.switchMinimal = function () { - $scope.minimal = !$scope.minimal; - NVRDataModel.debug("MontageHistoryCtrl: switch minimal is " + $scope.minimal); - //console.log("Hide Statusbar"); - ionic.Platform.fullScreen($scope.minimal, !$scope.minimal); - $interval.cancel(intervalHandle); //we will renew on reload - // We are reloading this view, so we don't want entry animations - $ionicHistory.nextViewOptions({ - disableAnimate: true, - disableBack: true - }); - $state.go("montage", { - minimal: $scope.minimal, - isRefresh: true - }); - }; + + + + $scope.toggleControls = function() + { + $scope.showControls = !$scope.showControls; + }; + $scope.toggleSelectItem = function (ndx) { @@ -681,10 +760,10 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.onDropComplete = function (index, obj, event) { //console.log("dragged"); - var otherObj = $scope.monitors[index]; - var otherIndex = $scope.monitors.indexOf(obj); - $scope.monitors[index] = obj; - $scope.monitors[otherIndex] = otherObj; + var otherObj = $scope.MontageMonitors[index]; + var otherIndex = $scope.MontageMonitors.indexOf(obj); + $scope.MontageMonitors[index] = obj; + $scope.MontageMonitors[otherIndex] = otherObj; }; @@ -777,11 +856,12 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc //console.log("Setting Awake to " + NVRDataModel.getKeepAwake()); NVRDataModel.setAwake(NVRDataModel.getKeepAwake()); + NVRDataModel.debug ("query timer started"); $interval.cancel($rootScope.eventQueryInterval); //console.log ("****************** TIMER STARTED INSIDE ENTER"); $rootScope.eventQueryInterval = $interval(function () { checkAllEvents(); - // console.log ("Refreshing Image..."); + }.bind(this), zm.eventHistoryTimer); @@ -987,38 +1067,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }; - //--------------------------------------------------------- - // This function readjusts montage size - // and stores current size to persistent memory - //--------------------------------------------------------- - - function processSliderChanged(val) { - if (sizeInProgress) return; - - sizeInProgress = true; - //console.log('Size has changed'); - NVRDataModel.setMontageSize(val); - //console.log("ZMData Montage is " + NVRDataModel.getMontageSize() + - // " and slider montage is " + $scope.slider.monsize); - // Now go ahead and reset sizes of entire monitor array - var monsizestring = ""; - var i; - for (i = 0; i < $scope.monitors.length; i++) { - - $scope.monitorSize[i] = parseInt(NVRDataModel.getMontageSize()); - //console.log("Resetting Monitor " + i + " size to " + $scope.monitorSize[i]); - $scope.scaleDirection[i] = 1; - monsizestring = monsizestring + $scope.monitorSize[i] + ':'; - } - monsizestring = monsizestring.slice(0, -1); // kill last : - //console.log("Setting monsize string:" + monsizestring); - loginData.montageArraySize = monsizestring; - NVRDataModel.setLogin(loginData); - //window.localStorage.setItem("montageArraySize", monsizestring); - sizeInProgress = false; - } - - function isEmpty(obj) { + function isEmpty(obj) { for (var prop in obj) { return false; } @@ -1028,7 +1077,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc // called by afterEnter to load Packery function initPackery() { - console.log(">>>>>>>>>>>>>>>>> HIT INIT"); + $ionicLoading.show({ template: $translate.instant('kArrangingImages'), noBackdrop: true, @@ -1097,7 +1146,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $ionicLoading.hide(); - + $timeout(function () { pckry = new Packery('.grid', { itemSelector: '.grid-item', percentPosition: true, @@ -1112,11 +1161,10 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc } - $timeout(function () { + var cnt = 0; pckry.getItemElements().forEach(function (itemElem) { - console.log("DRAG ADD " + cnt++); draggie = new Draggabilly(itemElem); pckry.bindDraggabillyEvents(draggie); draggies.push(draggie); @@ -1164,16 +1212,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc function itemDragged(item) { NVRDataModel.debug("drag complete"); - //pckry.getItemElements().forEach(function (itemElem) { - - //console.log (itemElem.attributes['data-item-id'].value+" size "+itemElem.attributes['data-item-size'].value ); - // }); - - /* var positions = pckry.EHgetShiftPositions('eh-data-item-id'); - //console.log ("POSITIONS MAP " + JSON.stringify(positions)); - var ld = NVRDataModel.getLogin(); - ld.EHpackeryPositions = JSON.stringify(positions); - NVRDataModel.setLogin(ld);*/ + } @@ -1186,6 +1225,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc // I don't think I am using this anymore FIXME: check and delete if needed // $rootScope.rand = Math.floor((Math.random() * 100000) + 1); + + $scope.showControls = false; $timeout(function () { initPackery(); }, zm.packeryTimer); @@ -1203,24 +1244,83 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc //console.log("***Pull to Refresh, recomputing Rand"); NVRDataModel.log("Reloading view for montage view, recomputing rand"); $rootScope.rand = Math.floor((Math.random() * 100000) + 1); - $scope.monitors = []; + $scope.MontageMonitors = []; imageLoadingDataShare.set(0); var refresh = NVRDataModel.getMonitors(1); refresh.then(function (data) { - $scope.monitors = data; + $scope.MontageMonitors = data.data; $scope.$broadcast('scroll.refreshComplete'); }); }; + + + function drawGraph(f,mid) { + + + console.log ("Graphing on " + "eventchart-"+mid); + var cv = document.getElementById("eventchart-"+mid); + var ctx = cv.getContext("2d"); + + + frameoptions = { + responsive: true, + legend: false, + title: { + display: false, + text: "" + }, + scales: { + yAxes: [{ + display: false, + scaleLabel: { + display: false, + labelString: 'value', + } + + }], + xAxes: [{ + type: 'time', + display: false, + time: { + + format: timeFormat, + tooltipFormat: 'll HH:mm', + min: f.datasets[0].data[0].x, + max: f.datasets[0].data[f.datasets[0].data.length - 1].x, + displayFormats: { + + } + }, + scaleLabel: { + display: false, + labelString: '' + } + + }] + } + }; + + + $timeout(function () { + + + var myChart = new Chart(ctx, { + type: 'line', + data: f, + options: frameoptions, + }); + + }); + } + //--------------------------------------------------------------------- // Controller main //--------------------------------------------------------------------- - - var intervalHandle; $scope.isModalActive = false; var modalIntervalHandle; @@ -1235,6 +1335,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.displayDateTimeSliders = true; $scope.showtimers = true; $scope.loginData = NVRDataModel.getLogin(); + var timeFormat = 'MM/DD/YYYY HH:mm:ss'; var curYear = new Date().getFullYear(); @@ -1252,6 +1353,8 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }; + + var frameoptions = []; // default = start of day @@ -1262,10 +1365,6 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc $scope.sliderVal.realRate = $scope.sliderVal.rate * 100; - - //var tdatetimeValueFrom = new Date(); - //tdatetimeValueFrom.setDate(tdatetimeValueFrom.getDate()-1); - $scope.datetimeValueFrom = { value: "", hrs:"" @@ -1319,22 +1418,11 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }; - - var isLongPressActive = false; - $scope.isReorder = false; - var intervalHandleMontage; // will hold image resize timer on long press - var montageIndex = 0; // will hold monitor ID to scale in timer - var gridcontainer, pckry, draggie, draggies; $scope.monitorSize = []; // array with montage sizes per monitor $scope.scaleDirection = []; // 1 = increase -1 = decrease - $scope.slider = {}; - - //console.log ("************ HISTORY " + NVRDataModel.getMontageSize()); - $scope.slider.monsize = NVRDataModel.getMontageSize(); - $scope.revMonSize = 11 - parseInt($scope.slider.monsize); // The difference between old and original is this: // old will have a copy of the last re-arranged monitor list @@ -1363,33 +1451,31 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc return; } - // console.log ("TEMP MONITORS IS " + JSON.stringify(tempMonitors)); - - $scope.monitors = tempMonitors; - - NVRDataModel.log("Inside MontageHistoryCtrl:We found " + $scope.monitors.length + " monitors"); + + $scope.MontageMonitors = message; + NVRDataModel.log("Inside MontageHistoryCtrl:We found " + $scope.MontageMonitors.length + " monitors"); // $scope.MontageMonitors = NVRDataModel.applyMontageMonitorPrefs(message, 1)[0]; - $scope.MontageMonitors = message; + var loginData = NVRDataModel.getLogin(); - $scope.packMontage = loginData.packMontage; - - // init monitors NVRDataModel.debug(">>Initializing connkeys and images..."); for (i = 0; i < $scope.MontageMonitors.length; i++) { //$scope.MontageMonitors[i].Monitor.connKey=''; + $scope.MontageMonitors[i].Monitor.eid = "-1"; $scope.MontageMonitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString(); $scope.MontageMonitors[i].Monitor.eventUrl = 'img/noevent.png'; + $scope.MontageMonitors[i].Monitor.eid = "-1"; $scope.MontageMonitors[i].Monitor.eventUrlTime = ""; $scope.MontageMonitors[i].Monitor.isPaused = false; $scope.MontageMonitors[i].Monitor.gridScale = "50"; $scope.MontageMonitors[i].Monitor.selectStyle = ""; $scope.MontageMonitors[i].Monitor.alarmState = 'color:rgba(0,0,0,0);'; + $scope.MontageMonitors[i].Monitor.sliderProgress = {progress:0}; } readyToRun = true; @@ -1423,54 +1509,14 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc }, 1000); - - - $scope.showSizeButtons = false; - $ionicPopover.fromTemplateUrl('templates/help/montage-help.html', { - scope: $scope, - }).then(function (popover) { - $scope.popover = popover; - }); - - var timestamp = new Date().getUTCMilliseconds(); - $scope.minimal = $stateParams.minimal; - $scope.zmMarginTop = $scope.minimal ? 0 : 15; - //console.log ("********* MARGIN IS " + $scope.zmMarginTop); - + + $scope.isRefresh = $stateParams.isRefresh; var sizeInProgress = false; - $scope.imageStyle = true; - $ionicSideMenuDelegate.canDragContent(true); - // Do we have a saved montage array size? No? - // if (window.localStorage.getItem("montageArraySize") == undefined) { - if (loginData.montageArraySize == '0') { - - for (i = 0; i < $scope.monitors.length; i++) { - $scope.monitorSize.push(NVRDataModel.getMontageSize()); - $scope.scaleDirection.push(1); - } - } else // recover previous settings - { - var msize = loginData.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]); - - } - - } - // $scope.monitorSize = monitorSize; - // $scope.scaleDirection = scaleDirection; $scope.LoginData = NVRDataModel.getLogin(); $scope.monLimit = $scope.LoginData.maxMontage; @@ -1478,13 +1524,12 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc if ($rootScope.platformOS != 'ios') { NVRDataModel.log("Limiting montage to 5, thanks to Chrome's stupid connection limit"); - $scope.monLimit = 5; $scope.currentLimit = 5; + $scope.monLimit = 5; + } - //console.log("********* Inside MontageHistoryCtrl, MAX LIMIT=" + $scope.monLimit); - - + $rootScope.authSession = "undefined"; $ionicLoading.show({ template: $translate.instant('kNegotiatingStreamAuth'), @@ -1499,7 +1544,7 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc var ld = NVRDataModel.getLogin(); //console.log ("MONITORS " + JSON.stringify($scope.monitors)); - $rootScope.validMonitorId = $scope.monitors[0].Monitor.Id; + $rootScope.validMonitorId = $scope.MontageMonitors[0].Monitor.Id; NVRDataModel.getAuthKey($rootScope.validMonitorId) .then(function (success) { $ionicLoading.hide(); diff --git a/www/js/NewsCtrl.js b/www/js/NewsCtrl.js index c8bf78b4..8305fa6b 100644 --- a/www/js/NewsCtrl.js +++ b/www/js/NewsCtrl.js @@ -19,7 +19,8 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/PortalLoginCtrl.js b/www/js/PortalLoginCtrl.js index 7e874fa4..541af937 100644 --- a/www/js/PortalLoginCtrl.js +++ b/www/js/PortalLoginCtrl.js @@ -281,7 +281,8 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic } else if (ld.onTapScreen == $translate.instant('kTapEvents')) { NVRDataModel.debug("Going to events"); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/StateCtrl.js b/www/js/StateCtrl.js index 76c11543..58f13c4b 100644 --- a/www/js/StateCtrl.js +++ b/www/js/StateCtrl.js @@ -112,7 +112,8 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup' disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js index 1bbd6dee..90ecf37e 100644 --- a/www/js/TimelineCtrl.js +++ b/www/js/TimelineCtrl.js @@ -31,7 +31,8 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/TimelineModalCtrl.js b/www/js/TimelineModalCtrl.js index f92aff26..4c3b7ea7 100644 --- a/www/js/TimelineModalCtrl.js +++ b/www/js/TimelineModalCtrl.js @@ -42,7 +42,8 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' disableBack: true }); $state.go("events", { - "id": 0 + "id": 0, + "playEvent":false }, { reload: true }); diff --git a/www/js/app.js b/www/js/app.js index 99b635b9..6badb37f 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -1,4 +1,4 @@ -/* jshint -W041 */ +/* jshint -W041, -W093 */ /* jslint browser: true*/ /* global cordova,StatusBar,angular,console,alert,PushNotification, moment ,ionic, URI,Packery, ConnectSDK, CryptoJS, ContactFindOptions, localforage,$, Connection, MobileAccessibility */ @@ -83,7 +83,7 @@ angular.module('zmApp', [ latestRelease: "https://api.github.com/repos/pliablepixels/zmNinja/releases/latest", blogUrl: "http://pliablepixels.github.io/feed.json", nphSwitchTimer: 3000, - eventHistoryTimer: 10000, + eventHistoryTimer: 5000, eventPlaybackQuery: 3000, packeryTimer: 500, @@ -257,6 +257,52 @@ angular.module('zmApp', [ }) +/*.factory('qHttp', function($q, $http) { + //credit: http://stackoverflow.com/a/29719693 + var queue = $q.when(); + + return function queuedHttp(httpConf) { + var f = function(data) { + return $http(httpConf); + }; + return queue = queue.then(f, f); + }; +})*/ + + +//credit: http://stackoverflow.com/a/14468276 +.factory('qHttp', function($q,$http) { + + var queue=[]; + var execNext = function() { + var task = queue[0]; + //console.log ("qHTTP>>> Executing:"+JSON.stringify(task.c)+">>> pending:"+queue.length); + + $http(task.c).then(function(data) { + queue.shift(); + task.d.resolve(data); + if (queue.length>0) execNext(); + }, function(err) { + queue.shift(); + task.d.reject(err); + if (queue.length>0) execNext(); + }) + ; + }; + return function(config) { + var d = $q.defer(); + //config.headers.push({'X-qHttp':'enabled'}); + queue.push({c:config,d:d}); + if (queue.length===1) + { + execNext(); + } + //else + //console.log ("qHTTP>>> Queuing:"+JSON.stringify(config)); + return d.promise; + }; +}) + //credit: https://github.com/driftyco/ionic/issues/3131 .factory('SecuredPopups', [ '$ionicPopup', @@ -461,7 +507,11 @@ angular.module('zmApp', [ 'request': function (config) { - + // NOTE ON TIMEOUTS: As of Oct 10 2016, it seems + // the Http queue often gets messed up when there is a timeout + // and the # of requests are plentiful. I'm going to disable it and see + + // console.log (">>>>"+config.url); // handle basic auth properly if (config.url.indexOf("@") > -1) { @@ -476,6 +526,7 @@ angular.module('zmApp', [ } + //console.log (">>>>>>>>>>>>> INTERCEPT OBJECT " + JSON.stringify(config)); if ($rootScope.zmCookie) { config.headers.Cookie = "ZMSESSID=" + $rootScope.zmCookie; @@ -486,18 +537,21 @@ angular.module('zmApp', [ if ((config.url.indexOf("/api/states/change/") > -1) || (config.url.indexOf("getDiskPercent.json") > -1) || (config.url.indexOf("daemonCheck.json") > -1) || - (config.url.indexOf("getLoad.json") > -1)) + (config.url.indexOf("getLoad.json") > -1) ) { + // these can take time, so lets bump up timeout config.timeout = zm.largeHttpTimeout; } else if ((config.url.indexOf("view=view_video") > -1) || config.url.indexOf(".mp4") > -1) { // console.log(">>> skipping timers for MP4"); - } else { - config.timeout = zm.httpTimeout; + // put a timeout for zms urls + } else if (config.url.indexOf("zms?") > -1) { + // config.timeout = zm.httpTimeout; + } return config; }, @@ -1629,7 +1683,7 @@ angular.module('zmApp', [ return NVRDataModel.getMonitors(0); } }, - url: "/events/:id", + url: "/events/:id/:playEvent", templateUrl: "templates/events.html", controller: 'zmApp.EventCtrl', diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json index 8557256c..156756d7 100644 --- a/www/lang/locale-en.json +++ b/www/lang/locale-en.json @@ -357,6 +357,9 @@ "kZMUndetermined" :"undetermined", "kZMUpgradeNeeded" :"ZoneMinder upgrade needed", "kEventHistShowFrom" :"Show from", - "kEventHistHrs" :"hours ago" + "kEventHistHrs" :"hours ago", + "kEventHistSlower" : "slower", + "kEventHistFaster" : "faster", + "kEventHistPlay" : "play" } diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html index e6211aab..2c1c38c7 100644 --- a/www/templates/events-modal.html +++ b/www/templates/events-modal.html @@ -113,6 +113,9 @@ <a mfb-button icon="ion-skip-backward" label="{{'kFastRewind'|translate}}" ng-click="adjustSpeed('fr');"></a> <a mfb-button icon="ion-skip-forward" label="{{'kFastForward'|translate}}" ng-click="adjustSpeed('ff');"></a> <a mfb-button icon="ion-play" label="{{'kNormalPlay'|translate}}" ng-click="adjustSpeed('np');"></a> + + + <a mfb-button icon="ion-pause" label="{{'kPause'|translate}}" ng-click="adjustSpeed('p');"> </a> diff --git a/www/templates/montage-history.html b/www/templates/montage-history.html index 3a4cbd86..aa38df16 100644 --- a/www/templates/montage-history.html +++ b/www/templates/montage-history.html @@ -1,240 +1,148 @@ <ion-view view-title="{{'kEventMontage' | translate}}" cache-view="false" hide-nav-bar="{{minimal}}"> - <ion-nav-buttons side="left"> - <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> - - <button class="button button-icon button-clear ion-arrow-move" ng-click="dragToggle();"> - </button> - - <button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge" ng-click="handleAlarms();" ng-if="$root.isAlarm"></button> - </ion-nav-buttons> - - - - <ion-nav-buttons side="right"> - - <button class="button button-icon button-clear ion-loop" ng-click="resetSizes();"> - </button> - - <button class="button button-icon button-clear ion-plus-round" ng-click="sliderChanged(1);"> - </button> - - <button class="button button-icon button-clear ion-minus-round" ng-click="sliderChanged(-1);"> - </button> - - <button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge" ng-click="handleAlarms();" ng-if="$root.isAlarm"></button> - - - - </ion-nav-buttons> - - <ion-content scroll-sista has-bouncing="false" style="background-color:#444444" delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll> - - - - <!--<div class="timeline_text" ion-datetime-picker title="From" am-pm={{!loginData.use24hr}} ng-model="datetimeValueFrom.value" ng-change="dateChanged()"> - <b>{{'kFrom' | translate}} : </b>{{datetimeValueFrom.value | date: timeFormat}} - </div>--> - - <!--<div class="timeline_text" ion-datetime-picker am-pm={{!loginData.use24hr}} ng-model="datetimeValueTo.value" ng-change="dateChanged()"> - <b>{{'kTo' | translate}}: </b>{{datetimeValueTo.value | date: timeFormat}} @ {{sliderVal.rate}}x - <div ng-if="$root.platformOS != 'ios'">({{'kChromeMax' | translate}})</div> - </div>--> - - <div class="timeline_text"> - {{'kFrom' | translate}}:{{prettifyDateTimeFirst(datetimeValueFrom.value)}} ({{humanizeTime(datetimeValueFrom.value)}}) - <!-- - {{'kTo' | translate}}:{{prettifyDateTimeFirst(datetimeValueTo.value)}} --> - <div ng-if="$root.platformOS != 'ios'">({{'kChromeMax' | translate}})</div> - </div> - - - <div class="grid" id="mygrid"> - <div class="grid-sizer grid-item-10"></div> - - - - - <!-- <span ng-repeat="monitor in MontageMonitors|limitTo: monLimit" ng- --> - <span ng-repeat="monitor in MontageMonitors | onlyEnabledAndEventHas |limitTo: currentLimit"> - - - - - <div ng-if="$root.authSession!='undefined'"> - <div ng-if = "monitor.Monitor.eventUrl == 'img/noevent.png' && !sliderVal.hideNoEvents"> - - <!-- make sure we don't use id here + <ion-nav-buttons side="left"> + <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button> + <button class="button button-icon button-clear ion-arrow-move" ng-click="dragToggle();"> </button> + <button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge" ng-click="handleAlarms();" ng-if="$root.isAlarm"></button> + </ion-nav-buttons> + + <ion-nav-buttons side="right"> + <button class="button button-icon button-clear ion-loop" ng-click="resetSizes();"> </button> + <button class="button button-icon button-clear ion-plus-round" ng-click="sliderChanged(1);"> </button> + <button class="button button-icon button-clear ion-minus-round" ng-click="sliderChanged(-1);"> </button> + <button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge" ng-click="handleAlarms();" ng-if="$root.isAlarm"></button> + </ion-nav-buttons> + + <ion-content scroll-sista has-bouncing="false" style="background-color:#444444" delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll> + <div class="timeline_text"> {{'kFrom' | translate}}:{{prettifyDateTimeFirst(datetimeValueFrom.value)}} ({{humanizeTime(datetimeValueFrom.value)}}) + <div ng-if="$root.platformOS != 'ios'">({{'kChromeMax' | translate}})</div> + </div> + <div class="grid" id="mygrid"> + <div class="grid-sizer grid-item-10"></div> + <!-- <span ng-repeat="monitor in MontageMonitors|limitTo: monLimit" ng- --> + <span ng-repeat="monitor in MontageMonitors | onlyEnabledAndEventHas |limitTo: currentLimit"> + <div ng-if="$root.authSession!='undefined'"> + <div ng-if = "monitor.Monitor.eventUrl == 'img/noevent.png' && !sliderVal.hideNoEvents"> + <!-- make sure we don't use id here -- or we lose the handle for cleanup forever!--> - <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" > - <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'"> - - <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?noop():toggleSelectItem($index)" /> - - - <figcaption class="normal-figcaption" > + <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" > + <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'"> + <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?noop():toggleSelectItem($index)" > + <figcaption class="normal-figcaption" > - <i class="ion-ios-videocam"></i> + + <i class="ion-ios-videocam"></i> {{monitor.Monitor.Name}} - </figcaption> - - - - </figure> - </div> - </div> - - <div ng-if = "monitor.Monitor.eventUrl != 'img/noevent.png' && monitor.Monitor.connKey !=''"> - - <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" > - <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'"> - - <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}{{$root.authSession}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?togglePause(monitor.Monitor.Id):toggleSelectItem($index)" /> - - - <figcaption class="normal-figcaption" > - - <i class="ion-ios-videocam"></i> <span style="background-color:red;color:#fff" ng-if="monitor.Monitor.isPaused"> <i class="ion-pause"></i> </span> {{monitor.Monitor.Name}} - - <div ng-if="sliderVal.showTimeline && $root.runMode!='lowbw'" style="white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:9px" class="header-event-id" id="{{monitor.Monitor.Id}}-timeline"> - <i class="ion-clock"></i> {{prettifyDateTimeFirst(monitor.Monitor.eventUrlTime)}} ({{humanizeTime(monitor.Monitor.eventUrlTime)}}) - </div> - - </figcaption> - - - - </figure> - </div> - - - - - - <!-- - <div ng-if="sliderVal.showTimeline && $root.runMode!='lowbw'" style=" position:absolute; bottom:15px; right:0%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;" - class="header-event-id" id="{{monitor.Monitor.Id}}-timeline"> - <i class="ion-clock"></i> - {{prettifyDate(monitor.Monitor.eventUrlTime)}} - </div> - --> - - - <!--<div ng-if="!monitor.isPaused" - style="position:absolute; bottom:35px; right:0%;white-space:nowrap;overflow:hidden;" class="header-event-id">paused - </div>--> - - - </div> - </div> - <!-- valid auth session &!background --> - - <div ng-if="!$root.authSession=='undefined' || isBackground()"> - <img image-spinner-src="img/pausevideo.png" /> - - </div> - </span> - </div> - - <ion-item ng-show="!MontageMonitors.length"> - {{'kNoMonitors' | translate }} - </ion-item> - - - - </ion-content> - - <div class="bwmode" ng-if="$root.runMode=='lowbw'"> - {{ 'kLowBWDisplay' | translate }} - </div> - - <div ng-show="minimal"> - <nav mfb-menu position="br" effect="zoomin" label="collapse" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click"> - - <button mfb-button icon="ion-arrow-expand" label="increase size" ng-click="changeSize(-1)"> - </button> - <button mfb-button icon="ion-arrow-shrink" label="decrease size" ng-click="changeSize(1)"> - </button> - <button mfb-button icon="ion-refresh" label="refresh" ng-click="reloadView();"> - </button> - <button mfb-button icon="ion-close" label="exit full screen" ng-click="switchMinimal()"> - </button> - </nav> - - <span class="modal-alarm-badge"> - <a data-badge="{{$root.alarmCount}}" class="animated infinite tada button icon ion-ios-bell notification-badge button-assertive" + + </figcaption> + </figure> + </div> + </div> + <div ng-if = "monitor.Monitor.eventUrl != 'img/noevent.png' && monitor.Monitor.connKey !=''"> + <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" > + <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'"> + <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}{{$root.authSession}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?togglePause(monitor.Monitor.Id):toggleSelectItem($index)" on-swipe-left="toggleControls()" /> + <figcaption class="normal-figcaption" > + + + <i class="ion-ios-videocam"></i> + <span style="background-color:red;color:#fff" ng-if="monitor.Monitor.isPaused"> + <i class="ion-pause"></i> + </span> {{monitor.Monitor.Name}} + + <div ng-if="sliderVal.showTimeline && $root.runMode!='lowbw'" style="white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:9px" class="header-event-id" id="{{monitor.Monitor.Id}}-timeline"> + <i class="ion-clock"></i> {{prettifyDateTimeFirst(monitor.Monitor.eventUrlTime)}} ({{humanizeTime(monitor.Monitor.eventUrlTime)}}) + </div> + </figcaption> + </figure> + <div ng-if="showControls"> + + + + <div class="range" style="position:absolute;top:5%;width:95%;z-index:999"> + <input on-release="seek(monitor.Monitor.Id,monitor.Monitor.sliderProgress.progress )" type="range" min="0" max="{{monitor.Monitor.eventDuration}}" ng-model="monitor.Monitor.sliderProgress.progress"> + </div> + <div id="history_canvas_video"> + eventchart-{{monitor.Monitor.Id}} + <canvas id="eventchart-{{monitor.Monitor.Id}}" width="95%" height="20px"></canvas> + </div> + + </div> + <div id="flyoutmenu" ng-if="showControls" style="position:absolute;top:50%;left:50%;z-index:99999;transform: translate(-50%, -50%);"> + <ul> + <li> + <a href="" ng-click="moveSlower(monitor.Monitor.Id)"> {{'kEventHistSlower' | translate}} </a> + </li> + <li> + <a href="" ng-click= "movePlay(monitor.Monitor.Id)">{{'kEventHistPlay' | translate}}</a> + </li> + <li> + <a href="" ng-click = "moveFaster(monitor.Monitor.Id)">{{'kEventHistFaster' | translate}}</a> + </li> + </ul> + </div> + </div> + </div> + </div> + <!-- valid auth session &!background --> + <div ng-if="!$root.authSession=='undefined' || isBackground()"> + <img image-spinner-src="img/pausevideo.png" /> + </div> + </span> + </div> + <ion-item ng-show="!MontageMonitors.length"> {{'kNoMonitors' | translate }} </ion-item> + </ion-content> + <div class="bwmode" ng-if="$root.runMode=='lowbw'"> {{ 'kLowBWDisplay' | translate }} </div> + <div ng-show="minimal"> + <nav mfb-menu position="br" effect="zoomin" label="collapse" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click"> + <button mfb-button icon="ion-arrow-expand" label="increase size" ng-click="changeSize(-1)"></button> + <button mfb-button icon="ion-arrow-shrink" label="decrease size" ng-click="changeSize(1)"></button> + <button mfb-button icon="ion-refresh" label="refresh" ng-click="reloadView();"></button> + <button mfb-button icon="ion-close" label="exit full screen" ng-click="switchMinimal()"></button> + </nav> + <span class="modal-alarm-badge"> + <a data-badge="{{$root.alarmCount}}" class="animated infinite tada button icon ion-ios-bell notification-badge button-assertive" ng-click="handleAlarmsWhileMinimized();" ng-if="$root.isAlarm"></a> - </span> - - </div> - - <ion-pull-up-footer class="zmPullup" on-expand="footerExpand()" on-minimize="footerCollapse()" on-collapse="footerCollapse()" initial-state="minimized" default-behavior="expand"> - <ion-pull-up-handle width="100" height="25" toggle="ion-chevron-up ion-chevron-down" style="border-radius: 25px 25px 0 0"> - <i class="icon ion-chevron-up"></i> - </ion-pull-up-handle> - <ion-pull-up-bar> - <h1 class="title" ion-pull-up-trigger>{{'kEventMontage' | translate}}</h1> - </ion-pull-up-bar> - <ion-pull-up-content scroll="true"> - - - <div class="list list-inset"> - - - <!--<ion-toggle ng-model="sliderVal.hideNoEvents" ng-checked="{{sliderVal.hideNoEvents}}" toggle-class="toggle-dark"><span class="item-text-wrap">{{'kHideMonsWithoutEvents' | translate}}</span></ion-toggle>--> - - - - - <!--<div class="item item-divider" ion-datetime-picker ng-model="datetimeValueFrom.value"> + </span> + </div> + <ion-pull-up-footer class="zmPullup" on-expand="footerExpand()" on-minimize="footerCollapse()" on-collapse="footerCollapse()" initial-state="minimized" default-behavior="expand"> + <ion-pull-up-handle width="100" height="25" toggle="ion-chevron-up ion-chevron-down" style="border-radius: 25px 25px 0 0"> + <i class="icon ion-chevron-up"></i> + </ion-pull-up-handle> + <ion-pull-up-bar> + <h1 class="title" ion-pull-up-trigger>{{'kEventMontage' | translate}}</h1> + </ion-pull-up-bar> + <ion-pull-up-content scroll="true"> + <div class="list list-inset"> + <!--<ion-toggle ng-model="sliderVal.hideNoEvents" ng-checked="{{sliderVal.hideNoEvents}}" toggle-class="toggle-dark"><span class="item-text-wrap">{{'kHideMonsWithoutEvents' | translate}}</span></ion-toggle>--> + <!--<div class="item item-divider" ion-datetime-picker ng-model="datetimeValueFrom.value"> Tap to change: {{datetimeValueFrom.value| date: "yyyy-MMM-dd hh:mma"}} </div>--> - - - - - - - - <div class="item item-divider">{{'kTimeline' | translate}}</div> - - <div class="item item-input-inset"> - {{'kEventHistShowFrom'|translate}}: - <label class="item-input-wrapper"> - <input ng-change="hrsChanged()" type="tel" placeholder="hours" ng-model="datetimeValueFrom.hrs"> - </label> - {{'kEventHistHrs' | translate}} - </div> - - <ion-item> - <div ion-datetime-picker title="From" am-pm={{!loginData.use24hr}} ng-model="datetimeValueFrom.value" ng-change="dateChanged()"> - <b>{{'kFrom' | translate }}: </b>{{datetimeValueFrom.value | date: timeFormat}} - </div> ({{humanizeTime(datetimeValueFrom.value)}}) - </ion-item> - - <div class="row"> - <div class="col col-75"> - <br/> - <div style="width:90%;color:black;"> - <input ng-model="sliderVal.rate" type="text" id="mySlider6" slider options="slider_modal_options_rate" /> - </div> - <br/> - </div> - <div class="col col-25" style="background-color:#AEA8D3;text-align:center"> - {{'kSpeed' | translate }} - </div> - </div> - <!--<ion-item> - <div ion-datetime-picker am-pm={{!loginData.use24hr}} ng-model="datetimeValueTo.value"> - <b>{{'kTo' | translate}}: </b>{{datetimeValueTo.value | date: timeFormat}} - </div> - </ion-item>--> - - </div> - </ion-pull-up-content> - </ion-pull-up-footer> - - - - - -</ion-view>
\ No newline at end of file + <div class="item item-divider">{{'kTimeline' | translate}}</div> + <div class="item item-input-inset"> {{'kEventHistShowFrom'|translate}}: + + <label class="item-input-wrapper"> + <input ng-change="hrsChanged()" type="tel" placeholder="hours" ng-model="datetimeValueFrom.hrs"> + </label> {{'kEventHistHrs' | translate}} + </div> + <ion-item> + <div ion-datetime-picker title="From" am-pm={{!loginData.use24hr}} ng-model="datetimeValueFrom.value" ng-change="dateChanged()"> + <b>{{'kFrom' | translate }}: </b>{{datetimeValueFrom.value | date: timeFormat}} + </div> ({{humanizeTime(datetimeValueFrom.value)}}) + </ion-item> + <div class="row"> + <div class="col col-75"> + <br/> + <div style="width:90%;color:black;"> + <input ng-model="sliderVal.rate" type="text" id="mySlider6" slider options="slider_modal_options_rate" /> + </div> + <br/> + </div> + <div class="col col-25" style="background-color:#AEA8D3;text-align:center"> {{'kSpeed' | translate }} </div> + </div> + <!--<ion-item><div ion-datetime-picker am-pm={{!loginData.use24hr}} ng-model="datetimeValueTo.value"><b>{{'kTo' | translate}}: </b>{{datetimeValueTo.value | date: timeFormat}} + </div></ion-item>--> + </div> + </ion-pull-up-content> + </ion-pull-up-footer> + </ion-view>
\ No newline at end of file |
