From e337593cc65dac19eeb29fc99b7def02fdbc55ed Mon Sep 17 00:00:00 2001 From: pliablepixels Date: Thu, 5 May 2016 11:45:19 -0400 Subject: #241 - lots of fixes, now switching between fid=XXX and path=YYYY mode depending on API version and other muti-server fixes Former-commit-id: 57ace2fa05175a07a5565c24820f5f56c6cfd2e0 --- www/js/DataModel.js | 48 ++- www/js/EventCtrl.js | 796 +++++++++++++++++--------------------------- www/js/EventModalCtrl.js | 23 +- www/js/LoginCtrl.js | 24 +- www/js/PortalLoginCtrl.js | 1 + www/js/TimelineModalCtrl.js | 154 ++------- www/js/app.js | 1 + 7 files changed, 402 insertions(+), 645 deletions(-) (limited to 'www/js') diff --git a/www/js/DataModel.js b/www/js/DataModel.js index eda58e8a..72f5e36b 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -138,6 +138,27 @@ angular.module('zmApp.controllers') $fileLogger.debug(val); } + //credit: https://gist.github.com/alexey-bass/1115557 + function versionCompare(left, right) { + if (typeof left + typeof right != 'stringstring') + return false; + + var a = left.split('.'); + var b = right.split('.'); + var i = 0; + var len = Math.max(a.length, b.length); + + for (; i < len; i++) { + if ((a[i] && !b[i] && parseInt(a[i]) > 0) || (parseInt(a[i]) > parseInt(b[i]))) { + return 1; + } else if ((b[i] && !a[i] && parseInt(b[i]) > 0) || (parseInt(a[i]) < parseInt(b[i]))) { + return -1; + } + } + + return 0; +} + //-------------------------------------------------------------------------- // Banner display of messages @@ -987,7 +1008,7 @@ angular.module('zmApp.controllers') {return parseInt(a.Monitor.Sequence)-parseInt(b.Monitor.Sequence);}); //console.log("promise resolved inside HTTP success"); monitorsLoaded = 1; - console.log ("*********************** HOOOO"); + zmDebug ("Now trying to get multi-server data, if present"); $http.get (apiurl+"/servers.json") .success (function(data){ // We found a server list API, so lets make sure @@ -1016,7 +1037,7 @@ angular.module('zmApp.controllers') if (serverFound) { - zmDebug ("Monitor " +i + " has a server hostname of " + multiservers[j].Server.Hostname); + zmDebug ("Monitor " +monitors[i].Monitor.Id + " has a server hostname of " + multiservers[j].Server.Hostname); // Now here is the logic, I need to retrieve serverhostname, // and slap on the host protocol and path. Meh. @@ -1054,9 +1075,13 @@ angular.module('zmApp.controllers') st+= (s.path? s.path: p.path); monitors[i].Monitor.streamingURL = st; monitors[i].Monitor.baseURL = baseurl; + // starting 1.30 we have fid=xxx mode to return images + monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion,"1.30")==-1) ? "path":"fid"; + zmDebug ("API " +$rootScope.apiVersion+ ": Monitor " + monitors[i].Monitor.Id + " will use " + monitors[i].Monitor.imageMode + " for direct image access" ); + + //zmDebug ("Streaming URL for Monitor " + monitors[i].Monitor.Id + " is " + monitors[i].Monitor.streamingURL ); + //zmDebug ("Base URL for Monitor " + monitors[i].Monitor.Id + " is " + monitors[i].Monitor.baseURL ); - zmDebug ("Streaming URL for Monitor " + i + " is " + monitors[i].Monitor.streamingURL ); - zmDebug ("Base URL for Monitor " + i + " is " + monitors[i].Monitor.baseURL ); } } @@ -1073,6 +1098,9 @@ angular.module('zmApp.controllers') monitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString(); monitors[i].Monitor.streamingURL = loginData.streamingurl; monitors[i].Monitor.baseURL = loginData.url; + monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion,"1.30")==-1) ? "path":"fid"; + zmDebug ("API " +$rootScope.apiVersion+ ": Monitor " + monitors[i].Monitor.Id + " will use " + monitors[i].Monitor.imageMode + " for direct image access" ); + @@ -1358,6 +1386,18 @@ angular.module('zmApp.controllers') return "(Unknown)"; }, + getImageMode: function (id) { + var idnum = parseInt(id); + for (var i = 0; i < monitors.length; i++) { + if (parseInt(monitors[i].Monitor.Id) == idnum) { + // console.log ("Matched, exiting getMonitorname"); + return monitors[i].Monitor.imageMode; + } + + } + return "(Unknown)"; + }, + getStreamingURL: function (id) { var idnum = parseInt(id); for (var i = 0; i < monitors.length; i++) { diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 27b1aee0..7d0c640e 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -7,7 +7,7 @@ // and whether the new API has a better mechanism angular.module('zmApp.controllers') - .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'appModalService', function ($scope, $rootScope, zm, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, appModalService) { + .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'ZMDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'appModalService', 'carouselUtils', function ($scope, $rootScope, zm, ZMDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, appModalService, carouselUtils) { // events in last 5 minutes // TODO https://server/zm/api/events/consoleEvents/5%20minute.json @@ -16,38 +16,91 @@ angular.module('zmApp.controllers') // Controller main //--------------------------------------------------- + var loginData; + var oldEvent; + var scrollbynumber; + var eventImageDigits = 5; // failsafe + var eventsPage; + var moreEvents; + var pageLoaded; + var enableLoadMore; + var lData; + var stackState; + var ionRangeWatcher; + var mycarouselWatcher; + + //--------------------------------------------------- + // initial code + //--------------------------------------------------- + + $scope.$on('$ionicView.beforeEnter', function () { + + document.addEventListener("pause", onPause, false); + //console.log("I got STATE PARAM " + $stateParams.id); + $scope.id = parseInt($stateParams.id, 10); + + pageLoaded = false; + enableLoadMore = true; - $scope.mycarousel = { + $scope.mycarousel = { index: 0 - }; - $scope.ionRange = { - index: 1 - }; + }; + + $scope.ionRange = { + index: 1 + }; + $scope.animationInProgress = false; + + $scope.hours = []; + $scope.days = []; + $scope.weeks = []; + $scope.months = []; - $scope.animationInProgress = false; - var loginData = ZMDataModel.getLogin(); + + $scope.eventList = { + showDelete: false + }; + + $scope.slides = []; // will hold scrub frames + $scope.totalEventTime = 0; // used to display max of progress bar + $scope.currentEventTime = 0; + oldEvent = ""; // will hold previous event that had showScrub = true + scrollbynumber = 0; + $scope.eventsBeingLoaded = true; + $scope.FrameArray = []; // will hold frame info from detailed Events API + loginData = ZMDataModel.getLogin(); + ZMDataModel.getKeyConfigParams(0) + .then(function (data) { + //console.log ("***GETKEY: " + JSON.stringify(data)); + eventImageDigits = parseInt(data); + ZMDataModel.zmLog("Image padding digits reported as " + eventImageDigits); + }); + + + $scope.showSearch = false; + eventsPage = 1; + moreEvents = true; + $scope.viewTitle = { + title: "" + }; + $scope.search = { + text:"" + + }; + $scope.myfilter = ""; + + $scope.loginData = ZMDataModel.getLogin(); + $scope.playbackURL = $scope.loginData.url; + getInitialEvents(); + setupWatchers(); - $scope.hours = []; - $scope.days = []; - $scope.weeks = []; - $scope.months = []; + + }); + - $scope.eventList = { - showDelete: false - }; - - $scope.slides = []; // will hold scrub frames - var segmentHandle = 0; // holds timer for progress bar - $scope.totalEventTime = 0; // used to display max of progress bar - $scope.currentEventTime = 0; - var oldEvent = ""; // will hold previous event that had showScrub = true - var scrollbynumber = 0; - $scope.eventsBeingLoaded = true; - $scope.FrameArray = []; // will hold frame info from detailed Events API - //var currentEvent = ""; // -------------------------------------------------------- @@ -81,211 +134,170 @@ angular.module('zmApp.controllers') }, 1000); - document.addEventListener("pause", onPause, false); - //console.log("I got STATE PARAM " + $stateParams.id); - $scope.id = parseInt($stateParams.id, 10); - - // $scope.connKey = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111; - + + //-------------------------------------- + // monitor the slider for carousels + //-------------------------------------- + function setupWatchers() + { + ZMDataModel.zmDebug ("Setting up carousel watchers"); + + ionRangeWatcher = $scope.$watch('ionRange.index', function () { + // console.log ("Watching index"); + $scope.mycarousel.index = parseInt($scope.ionRange.index) - 1; + if (carouselUtils.getStop() == true) + return; - - // These are the commands ZM uses to move around - // in ZMS - not used anymore as I am doing direct - // image access via image.php - var eventCommands = { - next: "13", - previous: "12", - zoomin: "8", - zoomout: "9", - stop: "3", - pause: "1", - play: "2", - fastFwd: "4", - slowFwd: "5", - fastRev: "7", - slowRev: "6" - }; - var eventImageDigits = 5; // failsafe - ZMDataModel.getKeyConfigParams(0) - .then(function (data) { - //console.log ("***GETKEY: " + JSON.stringify(data)); - eventImageDigits = parseInt(data); - ZMDataModel.zmLog("Image padding digits reported as " + eventImageDigits); + //console.log ("***ION RANGE CHANGED TO " + $scope.mycarousel.index); }); + - - $scope.showSearch = false; - var eventsPage = 1; - var moreEvents = true; - $scope.viewTitle = { - title: "" - }; - $scope.search = { - - }; - $scope.myfilter = ""; - $scope.eventCommands = eventCommands; - $scope.loginData = ZMDataModel.getLogin(); - $scope.playbackURL = $scope.loginData.url; - /* not needed for electron - if ($rootScope.platformOS == "desktop") { - $scope.playbackURL = zm.desktopUrl; - } - */ - - + mycarouselWatcher = $scope.$watch('mycarousel.index', function () { - // for some reason inifinite scroll is invoked - // before I actually load the first page with page count - // this makes scrolling stop as eventsPage is still 0 - // FIXME: This is a hack - - var pageLoaded = false; - var enableLoadMore = true; + + if ($scope.event && $scope.ionRange.index == parseInt($scope.event.Event.Frames) - 1) { + if (!$scope.modal || $scope.modal.isShown() == false) { + // console.log("quick scrub playback over"); + carouselUtils.setStop(true); + $scope.ionRange.index = 0; + $scope.mycarousel.index = 1; + } - // When loading images, it sometimes takes time - the images can be quite - // large. What practically was happening was you'd see a blank screen for a few - // seconds. Not a good UX. So what I am doing is when the events modal or - // monitor modal is loaded, I show an ionic loading. And then when the first frame - // finishes loading, I take it away + } + if (carouselUtils.getStop() == true) + return; + $scope.ionRange.index = ($scope.mycarousel.index + 1).toString(); + // console.log ("***IONRANGE RANGE CHANGED TO " + $scope.ionRange.index); - //console.log("***CALLING EVENTS FACTORY"); - var lData = ZMDataModel.getLogin(); - var stackState = $ionicHistory.backTitle(); + }); + - // If you came from Monitors, disregard hidden monitors in montage - if (lData.persistMontageOrder && stackState != "Monitors") { - var tempMon = message; - $scope.monitors = ZMDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; - } else - $scope.monitors = message; + } + // -------------------------------------------------------- + // Handling of back button in case modal is open should + // close the modal + // -------------------------------------------------------- - if ($scope.monitors.length == 0) + function getInitialEvents() { - $ionicPopup.alert({ - title: "No Monitors found", - template: "Please check your credentials" - }); - $ionicHistory.nextViewOptions({ - disableBack: true - }); - $state.go("login" ,{"wizard": false}); - return; - } - - // console.log ("********** GOT MONITORS " + JSON.stringify($scope.monitors)); + ZMDataModel.zmDebug ("getInitialEvents called"); + var lData = ZMDataModel.getLogin(); - //$scope.monitors = message; + var stackState = $ionicHistory.backTitle(); - // I am converting monitor ID to monitor Name - // so I can display it along with Events - // Is there a better way? + // If you came from Monitors, disregard hidden monitors in montage + if (lData.persistMontageOrder && stackState != "Monitors") { + var tempMon = message; + $scope.monitors = ZMDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; + } else + $scope.monitors = message; - $scope.events = []; - // First get total pages and then - // start from the latest. If this fails, nothing displays + if ($scope.monitors.length == 0) + { + $ionicPopup.alert({ + title: "No Monitors found", + template: "Please check your credentials" + }); + $ionicHistory.nextViewOptions({ + disableBack: true + }); + $state.go("login" ,{"wizard": false}); + return; + } - ZMDataModel.zmDebug("EventCtrl: grabbing # of event pages"); - ZMDataModel.getEventsPages($scope.id, $rootScope.fromString, $rootScope.toString) - .then(function (data) { - eventsPage = data.pageCount; - ZMDataModel.zmDebug("EventCtrl: found " + eventsPage + " pages of events"); - //console.log("TOTAL EVENT PAGES IS " + eventsPage); - pageLoaded = true; - $scope.viewTitle.title = data.count; - ZMDataModel.zmDebug("EventCtrl: grabbing events for: id=" + $scope.id + " Date/Time:" + $rootScope.fromString + - "-" + $rootScope.toString); - ZMDataModel.getEvents($scope.id, eventsPage, "", $rootScope.fromString, $rootScope.toString) - .then(function (data) { - // console.log("EventCtrl Got events"); - //var events = []; - console.log ("********** MULTISERVER"); - var myevents = data; - ZMDataModel.zmDebug("EventCtrl: success, got " + myevents.length + " events"); - var loginData = ZMDataModel.getLogin(); - for (var i = 0; i < myevents.length; i++) { + $scope.events = []; - var idfound = true; - if (loginData.persistMontageOrder) { - idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId) { - - //console.log ( $scope.monitors[ii].Monitor.Id + " MATCHES " + myevents[i].Event.MonitorId); - idfound = true; - break; + // First get total pages and then + // start from the latest. If this fails, nothing displays + + ZMDataModel.zmDebug("EventCtrl: grabbing # of event pages"); + ZMDataModel.getEventsPages($scope.id, $rootScope.fromString, $rootScope.toString) + .then(function (data) { + eventsPage = data.pageCount; + ZMDataModel.zmDebug("EventCtrl: found " + eventsPage + " pages of events"); + + pageLoaded = true; + $scope.viewTitle.title = data.count; + ZMDataModel.zmDebug("EventCtrl: grabbing events for: id=" + $scope.id + " Date/Time:" + $rootScope.fromString + + "-" + $rootScope.toString); + ZMDataModel.getEvents($scope.id, eventsPage, "", $rootScope.fromString, $rootScope.toString) + .then(function (data) { + + var myevents = data; + ZMDataModel.zmDebug("EventCtrl: success, got " + myevents.length + " events"); + var loginData = ZMDataModel.getLogin(); + for (var i = 0; i < myevents.length; i++) { + + var idfound = true; + if (loginData.persistMontageOrder) { + idfound = false; + for (var ii = 0; ii < $scope.monitors.length; ii++) { + if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId) { + + idfound = true; + break; + } } } - } - myevents[i].Event.streamingURL = ZMDataModel.getStreamingURL (myevents[i].Event.MonitorId); - myevents[i].Event.baseURL = ZMDataModel.getBaseURL (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.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); - myevents[i].Event.ShowScrub = false; - myevents[i].Event.height = zm.eventsListDetailsHeight; - // now construct base path + myevents[i].Event.streamingURL = ZMDataModel.getStreamingURL (myevents[i].Event.MonitorId); + myevents[i].Event.baseURL = ZMDataModel.getBaseURL (myevents[i].Event.MonitorId); + myevents[i].Event.imageMode = ZMDataModel.getImageMode (myevents[i].Event.MonitorId); + + //console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL); - var str = myevents[i].Event.StartTime; - //var yy = moment(str).format('h:mm:ssa on MMMM Do YYYY'); - var yy = moment(str).format('YY'); - var mm = moment(str).format('MM'); - var dd = moment(str).format('DD'); - var hh = moment(str).format('HH'); - var min = moment(str).format('mm'); - var sec = moment(str).format('ss'); - - myevents[i].Event.BasePath = myevents[i].Event.baseURL + "/events/" + - myevents[i].Event.MonitorId + "/" + - yy + "/" + - mm + "/" + - dd + "/" + - hh + "/" + - min + "/" + - sec + "/"; - - myevents[i].Event.relativePath = - myevents[i].Event.MonitorId + "/" + - yy + "/" + - mm + "/" + - dd + "/" + - hh + "/" + - min + "/" + - sec + "/"; - - if (idfound) { - $scope.events.push(myevents[i]); - } else { - //console.log ("Skipping Event MID = " + myevents[i].Event.MonitorId); - } + // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL); + + myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); + myevents[i].Event.ShowScrub = false; + myevents[i].Event.height = zm.eventsListDetailsHeight; + // now construct base path + myevents[i].Event.BasePath = computeBasePath(myevents[i]); + myevents[i].Event.relativePath = computeRelativePath(myevents[i]); + + + // in multiserver BasePath is login url for frames + // http://login.url/index.php?view=frame&eid=19696772&fid=21 + + console.log ("COMPARING "+ZMDataModel.getLogin().url+ " TO " +myevents[i].Event.baseURL); + if (ZMDataModel.getLogin().url != myevents[i].Event.baseURL) + { + ZMDataModel.zmDebug ("Multi server, changing base"); + myevents[i].Event.baseURL = ZMDataModel.getLogin().url; + + } + + if (idfound) { + $scope.events.push(myevents[i]); + } else { + //console.log ("Skipping Event MID = " + myevents[i].Event.MonitorId); + } - } //for + } //for - //$scope.events = myevents; - // we only need to stop the template from loading when the list is empty - // so this can be false once we have _some_ content - // FIXME: check reload - $scope.eventsBeingLoaded = false; - // to avoid only few events being displayed - // if last page has less events - //console.log("**Loading Next Page ***"); - if (myevents.length < 50) { - ZMDataModel.zmDebug("EventCtrl:loading one more page just in case we don't have enough to display"); - loadMore(); - } - }); + //$scope.events = myevents; + // we only need to stop the template from loading when the list is empty + // so this can be false once we have _some_ content + // FIXME: check reload + $scope.eventsBeingLoaded = false; + // to avoid only few events being displayed + // if last page has less events + //console.log("**Loading Next Page ***"); + if (myevents.length < 50) { + ZMDataModel.zmDebug("EventCtrl:loading one more page just in case we don't have enough to display"); + loadMore(); + } + }); - }); + }); + } @@ -293,9 +305,18 @@ angular.module('zmApp.controllers') // Tapping on a frame shows this image //------------------------------------------------------ - $scope.showImage = function (p,r,f, fid,e) + $scope.showImage = function (p,r,f, fid,e, imode, id) { - var img = ""; + var img; + console.log ("Image Mode " + imode); + if (imode=='path') + + img = ""; + else + { + img = ""; + // console.log ("IS MULTISERVER SO IMAGE IS " + img); + } $rootScope.zmPopup = $ionicPopup.alert({title: 'frame:'+fid+'/Event:'+e,template:img, cssClass:'popup80'}); }; @@ -608,11 +629,8 @@ angular.module('zmApp.controllers') //------------------------------------------------------------------------- function onPause() { ZMDataModel.zmDebug("EventCtrl:onpause called"); - //console.log("*** Moving to Background ***"); // Handle the pause event - //console.log("*** CANCELLING INTERVAL ****"); if ($scope.popover) $scope.popover.remove(); - $interval.cancel(segmentHandle); - // FIXME: Do I need to setAwake(false) here? + } //------------------------------------------------------------------------- // Pads the filename with leading 0s, depending on ZM_IMAGE_DIGITS @@ -662,9 +680,7 @@ angular.module('zmApp.controllers') }; function toggleGroup(event, ndx, frames, groupType) { - - // console.log ("*** video: " + event.Event.DefaultVideo); - + // If we are here and there is a record of a previous scroll // then we need to scroll back to hide that view @@ -674,7 +690,7 @@ angular.module('zmApp.controllers') } if (oldEvent && event != oldEvent) { - // console.log("SWITCHING OLD EVENT OFF"); + ZMDataModel.zmDebug("EventCtrl:Old event scrub will hide now"); oldEvent.Event.ShowScrub = false; oldEvent.Event.height = zm.eventsListDetailsHeight; @@ -709,7 +725,8 @@ angular.module('zmApp.controllers') //console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length); $scope.alarm_images.push({ - id: data.event.Frame[i].FrameId, + id: data.event.Frame[i].Id, + frameid: data.event.Frame[i].FrameId, score: data.event.Frame[i].Score, fname: padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg" }); @@ -778,21 +795,57 @@ angular.module('zmApp.controllers') //console.log("**Resetting range"); $scope.slides = []; var i; - ZMDataModel.zmDebug("EventCtrl: found " + frames + " frames to scrub"); + + if (event.Event.imageMode == 'path') + { + ZMDataModel.zmDebug("EventCtrl: found " + frames + " frames to scrub"); - for (i = 1; i <= frames; i++) { - var fname = padToN(i, eventImageDigits) + "-capture.jpg"; + for (i = 1; i <= frames; i++) { + var fname = padToN(i, eventImageDigits) + "-capture.jpg"; - $scope.slides.push({ - id: i, - img: fname - }); + $scope.slides.push({ + id: i, + img: fname + }); + + } + } + else // we need fids + { + var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json"; + ZMDataModel.zmLog("API for event details" + myurl_frames); + $http.get(myurl_frames) + .success(function (data) { + $scope.FrameArray = data.event.Frame; + // $scope.slider_options.scale=[]; + //$scope.slider_options.scale = []; + + var i; + for (i = 0; i < data.event.Frame.length; i++) { + + //console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length); + $scope.slides.push({ + id: data.event.Frame[i].Id, + frameid: data.event.Frame[i].FrameId, + + }); + + + } + + //console.log (JSON.stringify(data)); + }) + .error(function (err) { + ZMDataModel.zmLog("Error retrieving detailed frame API " + JSON.stringify(err)); + ZMDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']); + }); + } @@ -804,9 +857,14 @@ angular.module('zmApp.controllers') event.Event.DefaultVideo = ""; // grab video details event.Event.video = {}; - var videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo; + var videoURL; + + if (event.Event.imageMode == 'path') + videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo; + else + videoURL = event.Event.baseURL + "/index.php?view=view_video&eid="+event.Event.Id; - // console.log("************** VIDEO IS " + videoURL); + console.log("************** VIDEO IS " + videoURL); event.Event.video.config = { autoPlay: true, sources: [ @@ -1024,207 +1082,7 @@ angular.module('zmApp.controllers') } }; - //-------------------------------------------------------- - // Not used - plan to use it to show event progress - //-------------------------------------------------------- - function segmentCheck() { - if ($scope.totalEventTime == 0) { - - //console.log("No events to play"); - return; - } - if ($scope.currentEventTime >= $scope.totalEventTime) { - // console.log("Total event duration reached"); - $scope.currentEventTime = $scope.totalEventTime; - return; - } - - // false == don't show ionic loadings, a query is a background job - controlEventStream("99", false); - //console.log("Duration: " + $scope.currentEventTime + " of " + $scope.totalEventTime); - - - // ./skins/classic/views/event.php panelSection - } - - //-------------------------------------------------------- - // this routine handles skipping through events - // in different event views. NOT used as a I stopped using - // zms for this - //-------------------------------------------------------- - - function controlEventStream(cmd, disp) { - - ZMDataModel.zmDebug ("OH CRAP!! THE WORLD HAS COME TO AN END****************"); - // console.log("Command value " + cmd); - - if (disp) { - $ionicLoading.hide(); - $ionicLoading.show({ - template: "please wait...", - noBackdrop: true, - duration: zm.loadingTimeout, - }); - } - var loginData = ZMDataModel.getLogin(); - - /* - var CMD_NONE = 0; - var CMD_PAUSE = 1; - var CMD_PLAY = 2; - var CMD_STOP = 3; - var CMD_FASTFWD = 4; - var CMD_SLOWFWD = 5; - var CMD_SLOWREV = 6; - var CMD_FASTREV = 7; - var CMD_ZOOMIN = 8; - var CMD_ZOOMOUT = 9; - var CMD_PAN = 10; - var CMD_SCALE = 11; - var CMD_PREV = 12; - var CMD_NEXT = 13; - var CMD_SEEK = 14; - var CMD_QUERY = 99; - */ - var toast_blurb = ""; - switch (cmd) { - case "13": - toast_blurb = "moving to "; - $scope.totalEventTime = 0; - - - break; - case "12": - toast_blurb = "moving to "; - $scope.totalEventTime = 0; - break; - case "8": - toast_blurb = "zoomed into "; - break; - case "9": - toast_blurb = "zoomed out of "; - break; - case "3": - toast_blurb = "stopping playback for "; - - break; - case "2": - toast_blurb = "resuming playback for "; - - break; - case "1": - toast_blurb = "pausing playback for "; - - break; - case "4": - toast_blurb = "fast forward "; - - break; - case "5": - toast_blurb = "slow forward "; - break; - case "6": - toast_blurb = "slow rewind "; - break; - case "7": - toast_blurb = "fast rewind "; - break; - } - - - // You need to POST commands to control zms - // Note that I am url encoding the parameters into the URL - // If I leave it as JSON, it gets converted to OPTONS due - // to CORS behaviour and ZM/Apache don't seem to handle it - - //console.log("POST: " + loginData.url + '/index.php'); - - var req = $http({ - method: 'POST', - /*timeout: 15000,*/ - url: loginData.url + '/index.php', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - //'Accept': '*/*', - }, - transformRequest: function (obj) { - var str = []; - for (var p in obj) - str.push(encodeURIComponent(p) + "=" + - encodeURIComponent(obj[p])); - var foo = str.join("&"); - // console.log("****RETURNING " + foo); - return foo; - }, - - data: { - view: "request", - request: "stream", - connkey: $scope.connKey, - command: cmd, - user: loginData.username, - pass: loginData.password - } - }); - req.success(function (resp) { - - // console.log("SUCCESS: " + JSON.stringify(resp)); - var str = toast_blurb + "event:" + resp.status.event; - // console.log(str); - // $ionicLoading.hide(); - - if (disp == true) { - $ionicLoading.show({ - template: str, - noBackdrop: true, - duration: 2000 - }); - } - - // 99 is CMD_QUERY its a convenient way to know where I am in the event playback - // takes care of speed etc so I don't have to worry about it - if (cmd == '99') { - $scope.currentEventTime = Math.round(parseFloat(resp.status.progress)); - } - - if (cmd == '12' || cmd == '13') { - // console.log("New event, so recomputing"); - var newevent = resp.status.event; - //console.log("**** EXTRACTED EVENT ****" + newevent); - var ld = ZMDataModel.getLogin(); - var myurl = ld.apiurl + "/events/" + newevent + ".json"; - $http.get(myurl) - .success(function (data) { - $scope.totalEventTime = Math.round(parseFloat(data.event.Event.Length)) - 1; - $scope.currentEventTime = 0; - - - - }) - .error(function (err) { - // console.log("Error : " + JSON.stringify(err)); - ZMDataModel.zmLog("Error getting timing info for new event " + newevent + ":" + JSON.stringify(err)); - $scope.totalEventTime = 0; - - }); - } - - }); - - req.error(function (resp) { - // console.log("ERROR: " + JSON.stringify(resp)); - ZMDataModel.zmLog("Error sending event command " + JSON.stringify(resp), "error"); - }); - } - - - $scope.controlEventStream = function (cmd) { - controlEventStream(cmd, true); - }; - - - //-------------------------------------------------------- // utility function //-------------------------------------------------------- @@ -1314,6 +1172,17 @@ angular.module('zmApp.controllers') }); }; + $scope.$on('modal.removed', function (e,m) { + + if (m.id != 'footage') + return; + ZMDataModel.zmDebug ("Rebinding watchers of eventCtrl"); + setupWatchers(); + + //console.log ("************** FOOTAGE CLOSED"); + + }); + //-------------------------------------------------------- //This is called when we first tap on an event to see // the feed. It's important to instantiate ionicModal here @@ -1324,6 +1193,9 @@ angular.module('zmApp.controllers') $scope.openModal = function (event) { + ZMDataModel.zmDebug ("unbinding eventCtrl watchers as modal has its own"); + ionRangeWatcher(); + mycarouselWatcher(); //ZMDataModel.zmDebug("EventCtrl: Open Modal with Base path " + relativepath); $scope.event = event; @@ -1334,15 +1206,6 @@ angular.module('zmApp.controllers') $scope.followSameMonitor = ($stateParams.id == "0")?"0":"1"; - // prepareModalEvent(event.Event.Id); - - /* appModalService.show('templates/events-modal.html', 'EventModalCtrl') - .then(function(result) { - // result from modal controller: $scope.closeModal(result) or .closeModal(result) [Only on template] - }, function(err) { - // error - });*/ - $ionicModal.fromTemplateUrl('templates/events-modal.html', { scope: $scope, @@ -1373,8 +1236,6 @@ angular.module('zmApp.controllers') // it on open //-------------------------------------------------------- $scope.closeModal = function () { - // $interval.cancel(eventsInterval); - $interval.cancel(segmentHandle); ZMDataModel.zmDebug("EventCtrl:Close & Destroy Modal"); ZMDataModel.setAwake(false); if ($scope.modal !== undefined) { @@ -1394,7 +1255,6 @@ angular.module('zmApp.controllers') } if ($scope.popover !== undefined) $scope.popover.remove(); - $interval.cancel(segmentHandle); }); //-------------------------------------------------------- @@ -1489,19 +1349,18 @@ angular.module('zmApp.controllers') myevents[i].Event.MonitorName = ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); // now construct base path - var str = myevents[i].Event.StartTime; - //var yy = moment(str).format('h:mm:ssa on MMMM Do YYYY'); - var yy = moment(str).format('YY'); - var mm = moment(str).format('MM'); - var dd = moment(str).format('DD'); - var hh = moment(str).format('HH'); - var min = moment(str).format('mm'); - var sec = moment(str).format('ss'); + myevents[i].Event.streamingURL = ZMDataModel.getStreamingURL (myevents[i].Event.MonitorId); + myevents[i].Event.baseURL = ZMDataModel.getBaseURL (myevents[i].Event.MonitorId); + myevents[i].Event.imageMode = ZMDataModel.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]); myevents[i].Event.height = zm.eventsListDetailsHeight; - if (idfound) $scope.events = $scope.events.concat(myevents[i]); + if (idfound) $scope.events.push(myevents[i]); } //console.log("Got new page of events"); @@ -1588,56 +1447,9 @@ angular.module('zmApp.controllers') } - $scope.events = []; + getInitialEvents(); moreEvents = true; - ZMDataModel.getEventsPages($scope.id, $rootScope.fromString, $rootScope.toString) - .then(function (data) { - eventsPage = data.pageCount; - // console.log("TOTAL EVENT PAGES IS " + eventsPage); - pageLoaded = true; - $scope.viewTitle.title = data.count; - ZMDataModel.getEvents($scope.id, eventsPage, "", $rootScope.fromString, $rootScope.toString) - - .then(function (data) { - //console.log("EventCtrl Got events"); - //var events = []; - var myevents = data; - for (var i = 0; i < myevents.length; i++) { - - var idfound = true; - - var ld = ZMDataModel.getLogin(); - if (ld.persistMontageOrder) { - idfound = false; - - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId) { - - //console.log ( $scope.monitors[ii].Monitor.Id + " MATCHES " + myevents[i].Event.MonitorId); - idfound = true; - break; - } - } - } - - myevents[i].Event.MonitorName = - ZMDataModel.getMonitorName(myevents[i].Event.MonitorId); - myevents[i].Event.BasePath = computeBasePath(myevents[i]); - myevents[i].Event.relativePath = computeRelativePath (myevents[i]); - - myevents[i].Event.ShowScrub = false; - myevents[i].Event.height = zm.eventsListDetailsHeight; - - if (idfound) { - //console.log ("***********************PUSHING RELOAD EVENT " + JSON.stringify(myevents)); - $scope.events.push(myevents[i]); - } - } - // $scope.events = myevents; - loadMore(); - }); - - }); + }); } diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index 726cbc04..88c0c2ed 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -706,6 +706,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro if (m.id != 'footage') return; + //console.log ("************** MODAL INSIDE FOOTAGE CLOSED"); $scope.isModalActive = false; //console.log("**MODAL REMOVED: Stopping modal timer"); @@ -1194,7 +1195,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro event.Event.video = {}; - var videoURL = $scope.loginData.url + "/events/" + event.Event.relativePath + event.Event.DefaultVideo; + var videoURL; + + if (event.Event.imageMode == 'path') + videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo; + else + videoURL = event.Event.baseURL + "/index.php?view=view_video&eid="+event.Event.Id; + + console.log("************** VIDEO IS " + videoURL); //console.log("************** VIDEO IS " + videoURL); event.Event.video.config = { @@ -1328,24 +1336,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro if (typeof $scope.mycarousel !== 'undefined') { $scope.$watch('mycarousel.index', function () { - - - - // console.log ("***ION MYCAROUSEL CHANGED TO " + $scope.mycarousel.index); - - //console.log ("*** IONRANGE INDEX IS " + $scope.ionRange.index); - - // console.log ("**** CURRENT EVENT frames" + currentEvent.Event.Frames); - + if (currentEvent && $scope.ionRange.index == parseInt(currentEvent.Event.Frames -1)) { - // console.log ("PLAYBACK FINISHED"); playbackFinished(); } // end of playback from quick scrub // so ignore gapless - - if ($scope.event && $scope.ionRange.index == parseInt($scope.event.Event.Frames) - 1) { if (!$scope.modal || $scope.modal.isShown() == false) { // console.log("quick scrub playback over"); diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js index 6f09040f..4d569658 100644 --- a/www/js/LoginCtrl.js +++ b/www/js/LoginCtrl.js @@ -677,7 +677,17 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r ZMDataModel.zmDebug("Urk! cgi-path returned success, but it should not have come here"); loginStatus = "Login validated, but could not validate cgi-path. If live streams don't work please check your cgi-bin path or try using the discover feature"; - var refresh = ZMDataModel.getMonitors(1); + ZMDataModel.zmDebug ("refreshing API version..."); + ZMDataModel.getAPIversion() + .then (function (data) { + var refresh = ZMDataModel.getMonitors(1); + $rootScope.apiVersion = data; + }, + function (error) { + var refresh = ZMDataModel.getMonitors(1); + $rootScope.apiVersion = "0.0.0"; + ZMDataModel.zmDebug ("Error, failed API version, setting to " +$rootScope.apiVersion); + }); if (showalert) { @@ -712,7 +722,17 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r }); } - var refresh = ZMDataModel.getMonitors(1); + ZMDataModel.zmDebug ("refreshing API version..."); + ZMDataModel.getAPIversion() + .then (function (data) { + var refresh = ZMDataModel.getMonitors(1); + $rootScope.apiVersion = data; + }, + function (error) { + var refresh = ZMDataModel.getMonitors(1); + $rootScope.apiVersion = "0.0.0"; + ZMDataModel.zmDebug ("Error, failed API version, setting to " +$rootScope.apiVersion); + }); }); }); diff --git a/www/js/PortalLoginCtrl.js b/www/js/PortalLoginCtrl.js index 13224271..4f8df895 100644 --- a/www/js/PortalLoginCtrl.js +++ b/www/js/PortalLoginCtrl.js @@ -167,6 +167,7 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic ZMDataModel.getAPIversion() .then (function(data) { ZMDataModel.zmLog("Got API version: " + data); + $rootScope.apiVersion = data; var ld = ZMDataModel.getLogin(); if (versionCompare(data,zm.minAppVersion)==-1 && data !="0.0.0") { diff --git a/www/js/TimelineModalCtrl.js b/www/js/TimelineModalCtrl.js index 70bd733d..58891ef9 100644 --- a/www/js/TimelineModalCtrl.js +++ b/www/js/TimelineModalCtrl.js @@ -126,12 +126,24 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' // Tapping on a frame shows this image //------------------------------------------------------ - $scope.showImage = function (p,r,f, fid) + $scope.showImage = function (p,r,f, fid,e, imode, id) { - var img = ""; - $rootScope.zmPopup = $ionicPopup.alert({title: 'frame:'+fid+'/Event:'+$scope.eid,template:img, cssClass:'popup80'}); + var img; + console.log ("Image Mode " + imode); + if (imode=='path') + + img = ""; + else + { + img = ""; + // console.log ("IS MULTISERVER SO IMAGE IS " + img); + } + $rootScope.zmPopup = $ionicPopup.alert({title: 'frame:'+fid+'/Event:'+e,template:img, cssClass:'popup80'}); }; + + + $scope.$on('modal.removed', function (e,m) { @@ -325,6 +337,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' y:event.event.Frame[i].Score, eid: event.event.Event.Id, fid: event.event.Frame[i].FrameId, + id: event.event.Frame[i].Id, //group:i, relativePath:computeRelativePath(event.event), score:event.event.Frame[i].Score, @@ -346,6 +359,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' relativePath:computeRelativePath(event.event), score:event.event.Frame[i].Score, fname: padToN(event.event.Frame[i].FrameId,eventImageDigits)+"-capture.jpg", + id: event.event.Frame[i].Id, }); } @@ -388,11 +402,12 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' //console.log ("You tapped " + ndx); $scope.alarm_images=[]; - $scope.playbackURL = ZMDataModel.getLogin().url; + $scope.playbackURL = $scope.event.Event.baseURL; var items = current_data.datasets[0].frames[ndx]; $scope.alarm_images.push({ relativePath:items.relativePath, fid:items.fid, + id: items.id, fname:items.fname, score:items.score, time:moment(items.x).format("MMM D,"+ZMDataModel.getTimeFormatSec()), @@ -402,136 +417,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', ' } - /* - function drawGraph(event) - { - //console.log ("EVENT IS " + JSON.stringify(event)); - items = []; - groups = new vis.DataSet(); - $scope.eid = event.event.Event.Id; - for (var i=0; i< event.event.Frame.length; i++) - { - - // groups.add({id:i, content:'', //className:'c-'+i - // }); - // console.log ("Pushing " + event.event.Frame[i].TimeStamp +":"+ event.event.Frame[i].Score); - items.push ({x:event.event.Frame[i].TimeStamp, - y:event.event.Frame[i].Score, - eid: event.event.Event.Id, - fid: event.event.Frame[i].FrameId, - //group:i, - relativePath:computeRelativePath(event.event), - score:event.event.Frame[i].Score, - fname: padToN(event.event.Frame[i].FrameId,eventImageDigits)+"-capture.jpg", - tap_selected:false - }); - } - - - var dataset = new vis.DataSet(items); - var options = { - autoResize:true, - height: Math.floor($rootScope.devHeight/2), - //clickToUse:true, - - style:'bar', - start: event.event.Frame[0].TimeStamp, - end: event.event.Frame[event.event.Frame.length-1].TimeStamp, - max: event.event.Frame[event.event.Frame.length-1].TimeStamp, - min: event.event.Frame[0].TimeStamp, - - drawPoints:function (item,group) - { - //ITEM IS {"screen_x":1199.0266666666666,"screen_y":232,"x":"2016-03-28T09:27:46.000Z","y":0,"groupId":"__ungrouped__"} - var taps = false; - for (var i=0; i>Item " +i + " is true"); - } - break; - } - } - - - var style_sel = {size:30, style:'circle', className:'visred'}; - var style = {size:20, style:'circle'}; - - return (taps ? style_sel: style); - }, - barChart: - { - width: 50, - sideBySide:false, - align:'center' - }, - dataAxis: - { - left: {title: {text:'score'}}, - } - }; - var container = document.getElementById('timeline-alarm-vis'); - Graph2d = new vis.Graph2d(container, dataset, groups, options); - $scope.dataReady = true; - - - - //------------------------------------------------------- - // When you tap on a data node - //------------------------------------------------------ - - Graph2d.on('click',function (prop) { - - $timeout( function() { - $scope.alarm_images=[]; - - $scope.playbackURL = ZMDataModel.getLogin().url; - var t = moment(prop.time); - - //console.log ("date="+t.format("YYYY-MM-DD HH:mm:ss")); - var tformat = t.format ("YYYY-MM-DD HH:mm:ss"); - - - for (var i=0; i