summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/css/style.css6
-rw-r--r--www/js/EventCtrl.js456
-rw-r--r--www/templates/events-modal.html15
-rw-r--r--www/templates/events.html2
4 files changed, 289 insertions, 190 deletions
diff --git a/www/css/style.css b/www/css/style.css
index fedf5879..6a6d4e8c 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -537,6 +537,12 @@ input[type=range]::-webkit-slider-thumb {
float:left;
}
+
+#full-screen-event {
+ -webkit-animation-duration: 500ms;
+
+}
+
/*.mySliderClass.jslider.sliderCSS div.jslider-pointer
{top:-10px;left:15px;width:60px;height:60px;margin-left:-5px;background-color:silver;background-color:#615959;border-radius:50%
}*/
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index cc0abf1c..3c150d79 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', 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) {
+ .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', 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) {
// events in last 5 minutes
// TODO https://server/zm/api/events/consoleEvents/5%20minute.json
@@ -19,8 +19,6 @@ angular.module('zmApp.controllers')
var loginData = ZMDataModel.getLogin();
-
-
$scope.hours = [];
$scope.days = [];
$scope.weeks = [];
@@ -698,8 +696,8 @@ angular.module('zmApp.controllers')
// now get event details to show alarm frames
var loginData = ZMDataModel.getLogin();
- if (typeof event.Event.DefaultVideo === 'undefined')
- event.Event.DefaultVideo="";
+ if (typeof event.Event.DefaultVideo === 'undefined')
+ event.Event.DefaultVideo = "";
// grab video details
event.Event.video = {};
var videoURL = loginData.url + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;
@@ -938,7 +936,8 @@ angular.module('zmApp.controllers')
//--------------------------------------------------------
// this routine handles skipping through events
- // in different event views
+ // in different event views. NOT used as a I stopped using
+ // zms for this
//--------------------------------------------------------
function controlEventStream(cmd, disp) {
@@ -1108,154 +1107,309 @@ angular.module('zmApp.controllers')
controlEventStream(cmd, true);
};
+ // This function returns neighbor events if applicable
+ function neighborEvents(eid) {
+ var d = $q.defer();
+ // now get event details to show alarm frames
+ var loginData = ZMDataModel.getLogin();
+ var myurl = loginData.apiurl + '/events/' + eid + ".json";
+ var neighbors = {
+ prev: "",
+ next: ""
+ };
+ $http.get(myurl)
+ .success(function (data) {
+ neighbors.prev = data.event.Event.Prev ? data.event.Event.Prev : "";
+ neighbors.next = data.event.Event.Next ? data.event.Event.Next : "";
+ ZMDataModel.zmDebug("Neighbor events of " + eid + "are Prev:" +
+ neighbors.prev + " and Next:" + neighbors.next);
+
+ d.resolve(neighbors);
+ return (d.promise);
+ })
+ .error(function (err) {
+ ZMDataModel.zmLog("Error retrieving neighbors" + JSON.stringify(err));
+ d.reject(neighbors);
+ return (d.promise);
+
+
+ });
+ return (d.promise);
+
+ }
+
+
//--------------------------------------------------------
- //This is called when we first tap on an event to see
- // the feed. It's important to instantiate ionicModal here
- // as otherwise you'd instantiate it when the view loads
- // and our "Please wait loading" technique I explained
- //earlier won't work
+ //Navigate to next/prev event in full screen mode
//--------------------------------------------------------
- $scope.openModal = function (eid, ename, edur, eframes, basepath, relativepath, event) {
- ZMDataModel.zmDebug("EventCtrl: Open Modal with Base path " + relativepath);
- $scope.eventName = ename;
- $scope.eventId = eid;
- $scope.eFramesNum = eframes;
- $scope.eventDur = Math.round(edur);
- $scope.loginData = ZMDataModel.getLogin();
- if (typeof event.Event.DefaultVideo === 'undefined')
- event.Event.DefaultVideo="";
+ $scope.jumpToEvent = function (eid, dirn) {
+ ZMDataModel.zmLog("Event jump called with:" + eid);
+ if (eid == "") {
+ $ionicLoading.show({
+ template: "no more events",
+ noBackdrop: true,
+ duration: 2000
+ });
+
+ return;
+ }
+
+ var slidein;
+ var slideout;
+ if (dirn==1)
+ {
+ slideout = "animated slideOutLeft";
+ slidein = "animated slideInRight";
+ }
+ else
+ {
+ slideout = "animated slideOutRight";
+ slidein = "animated slideInLeft";
+ }
+ var element = angular.element(document.getElementById("full-screen-event"));
+ element.addClass(slideout).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {element.removeClass(slideout);prepareModalEvent(eid); element.addClass(slidein); });
- $scope.defaultVideo = event.Event.DefaultVideo;
+
+
+ };
+ //--------------------------------------------------------
+ // utility function
+ //--------------------------------------------------------
- event.Event.video = {};
- var videoURL = $scope.loginData.url + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;
+ function computeRelativePath(event) {
+ var relativePath = "";
+ var loginData = ZMDataModel.getLogin();
+ var str = event.Event.StartTime;
+ 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');
+ relativePath = event.Event.MonitorId + "/" +
+ yy + "/" +
+ mm + "/" +
+ dd + "/" +
+ hh + "/" +
+ min + "/" +
+ sec + "/";
+ return relativePath;
- console.log("************** VIDEO IS " + videoURL);
- event.Event.video.config = {
- autoPlay: true,
- sources: [
- {
- src: $sce.trustAsResourceUrl(videoURL),
- type: "video/mp4"
- }
+ }
+
+ //--------------------------------------------------------
+ // utility function
+ //--------------------------------------------------------
- ],
+ function computeBasePath(event) {
+ var basePath = "";
+ var loginData = ZMDataModel.getLogin();
+ var str = event.Event.StartTime;
+ 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');
+
+ basePath = loginData.url + "/events/" +
+ event.Event.MonitorId + "/" +
+ yy + "/" +
+ mm + "/" +
+ dd + "/" +
+ hh + "/" +
+ min + "/" +
+ sec + "/";
+ return basePath;
+ }
- theme: "lib/videogular-themes-default/videogular.css",
+ //--------------------------------------------------------
+ // Called by openModal as well as jump to event
+ // what it basically does is get a detailed event API
+ // for an event ID and constructs required playback
+ // parameters
+ // Note that openModal is called with the top level event
+ // API. Some parameters are repeated across both
+ //--------------------------------------------------------
- };
- $scope.videoObject = event.Event.video;
+ function prepareModalEvent(eid) {
- $scope.playbackURL = $scope.loginData.url;
- if ($rootScope.platformOS == "desktop") {
- $scope.playbackURL = zm.desktopUrl;
- }
+ // Lets get the detailed event API
+ var loginData = ZMDataModel.getLogin();
+ var myurl = loginData.apiurl + '/events/' + eid + ".json";
+ ZMDataModel.zmLog("*** Constructed API for detailed events: " + myurl);
+ $http.get(myurl)
+ .then(function (success) {
+ var event = success.data.event;
+ event.Event.BasePath = computeBasePath(event);
+ event.Event.relativePath = computeRelativePath(event);
- $scope.eventBasePath = basepath;
- $scope.relativePath = relativepath;
- $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
+ //console.log (JSON.stringify( success));
+ $scope.eventName = event.Event.Name;
+ $scope.eventId = event.Event.Id;
+ $scope.eFramesNum = event.Event.Frames;
+ $scope.eventDur = Math.round(event.Event.Length);
+ $scope.loginData = ZMDataModel.getLogin();
+ console.log("**** VIDEO STATE IS " + event.Event.DefaultVideo);
+ if (typeof event.Event.DefaultVideo === 'undefined')
+ event.Event.DefaultVideo = "";
+ $scope.defaultVideo = event.Event.DefaultVideo;
- $scope.slider_modal_options = {
- from: 1,
- to: eframes,
- realtime: true,
- step: 1,
- className: "mySliderClass",
- callback: function (value, released) {
- //console.log("CALLBACK"+value+released);
- $ionicScrollDelegate.freezeScroll(!released);
+ neighborEvents(event.Event.Id)
+ .then(function (success) {
+ $scope.nextId = success.next;
+ $scope.prevId = success.prev;
+ },
+ function (error) {
+ console.log(JSON.stringify(error));
+ });
+ $scope.nextId = "...";
+ $scope.prevId = "...";
- },
- //modelLabels:function(val) {return "";},
- smooth: false,
- css: {
- background: {
- "background-color": "silver"
- },
- before: {
- "background-color": "purple"
- },
- default: {
- "background-color": "white"
- }, // default value: 1px
- after: {
- "background-color": "green"
- }, // zone after default value
- pointer: {
- "background-color": "red"
- }, // circle pointer
- range: {
- "background-color": "red"
- } // use it if double value
- },
- scale: []
- };
- $scope.mycarousel.index = 0;
- $scope.ionRange.index = 1;
- //console.log("**Resetting range");
- $scope.slides = [];
- var i;
- for (i = 1; i <= eframes; i++) {
- var fname = padToN(i, eventImageDigits) + "-capture.jpg";
- // console.log ("Building " + fname);
- $scope.slides.push({
- id: i,
- img: fname
- });
- }
+ event.Event.video = {};
+ var videoURL = $scope.loginData.url + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;
+ //console.log("************** VIDEO IS " + videoURL);
+ event.Event.video.config = {
+ autoPlay: true,
+ sources: [
+ {
+ src: $sce.trustAsResourceUrl(videoURL),
+ type: "video/mp4"
+ }
- // now get event details to show alarm frames
- var loginData = ZMDataModel.getLogin();
- var myurl = loginData.apiurl + '/events/' + eid + ".json";
- ZMDataModel.zmLog("*** Constructed API for detailed events: " + myurl);
- $http.get(myurl)
- .success(function (data) {
- $scope.FrameArray = data.event.Frame;
- // $scope.slider_options.scale=[];
- $scope.slider_modal_options.scale = [];
+ ],
+
+ theme: "lib/videogular-themes-default/videogular.css",
- var i;
- for (i = 0; i < data.event.Frame.length; i++) {
- if (data.event.Frame[i].Type == "Alarm") {
+ };
- $scope.slider_modal_options.scale.push({
- val: i + 1,
- label: ' '
+ $scope.videoObject = event.Event.video;
+
+ $scope.playbackURL = $scope.loginData.url;
+ if ($rootScope.platformOS == "desktop") {
+ $scope.playbackURL = zm.desktopUrl;
+ }
+
+ $scope.eventBasePath = event.Event.BasePath;
+ $scope.relativePath = event.Event.relativePath;
+ $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
+
+ $scope.slider_modal_options = {
+ from: 1,
+ to: event.Event.Frames,
+ realtime: true,
+ step: 1,
+ className: "mySliderClass",
+ callback: function (value, released) {
+ //console.log("CALLBACK"+value+released);
+ $ionicScrollDelegate.freezeScroll(!released);
+
+
+ },
+ //modelLabels:function(val) {return "";},
+ smooth: false,
+ css: {
+ background: {
+ "background-color": "silver"
+ },
+ before: {
+ "background-color": "purple"
+ },
+ default: {
+ "background-color": "white"
+ }, // default value: 1px
+ after: {
+ "background-color": "green"
+ }, // zone after default value
+ pointer: {
+ "background-color": "red"
+ }, // circle pointer
+ range: {
+ "background-color": "red"
+ } // use it if double value
+ },
+ scale: []
+
+ };
+
+
+ $scope.mycarousel.index = 0;
+ $scope.ionRange.index = 1;
+ //console.log("**Resetting range");
+ $scope.slides = [];
+ var i;
+ for (i = 1; i <= event.Event.Frames; i++) {
+ var fname = padToN(i, eventImageDigits) + "-capture.jpg";
+ // console.log ("Building " + fname);
+ $scope.slides.push({
+ id: i,
+ img: fname
});
- } else {
- //$scope.slider_options.scale.push(' ');
}
- }
- //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']);
- });
+ // now get event details to show alarm frames
+
+ $scope.FrameArray = event.Frame;
+ // $scope.slider_options.scale=[];
+ $scope.slider_modal_options.scale = [];
+
+
+ for (i = 0; i < event.Frame.length; i++) {
+ if (event.Frame[i].Type == "Alarm") {
+
+ $scope.slider_modal_options.scale.push({
+ val: i + 1,
+ label: ' '
+ });
+ } else {
+ //$scope.slider_options.scale.push(' ');
+ }
+
+ }
+ $scope.totalEventTime = Math.round(parseFloat(event.Event.Length)) - 1;
+ $scope.currentEventTime = 0;
+ },
+ function (err) {
+ ZMDataModel.zmLog("Error retrieving detailed frame API " + JSON.stringify(err));
+ ZMDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
+ });
+
+
+ }
+
+ //--------------------------------------------------------
+ //This is called when we first tap on an event to see
+ // the feed. It's important to instantiate ionicModal here
+ // as otherwise you'd instantiate it when the view loads
+ // and our "Please wait loading" technique I explained
+ //earlier won't work
+ //--------------------------------------------------------
+
+ $scope.openModal = function (event) {
+ //ZMDataModel.zmDebug("EventCtrl: Open Modal with Base path " + relativepath);
- $scope.totalEventTime = Math.round(parseFloat(edur)) - 1;
- $scope.currentEventTime = 0;
ZMDataModel.setAwake(ZMDataModel.getKeepAwake());
+ prepareModalEvent(event.Event.Id);
+
$ionicModal.fromTemplateUrl('templates/events-modal.html', {
scope: $scope,
animation: 'slide-in-up'
@@ -1273,19 +1427,7 @@ angular.module('zmApp.controllers')
var ld = ZMDataModel.getLogin();
- // how many seconds this event will take
- //evtSegments = eframes / ld.maxFPS + 3;
- //evtCurSegment = 0;
- // console.log ("**** I SET SEGMENTS TO " + evtSegments);
-
- // call on progress indicator every 5 seconds
- // don't want to overload
- /*
- segmentHandle = $interval(function () {
- segmentCheck();
- }, zm.progressIntervalCheck);
- segmentCheck();*/
-
+
});
@@ -1420,22 +1562,8 @@ angular.module('zmApp.controllers')
var min = moment(str).format('mm');
var sec = moment(str).format('ss');
- myevents[i].Event.BasePath = loginData.url + "/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 + "/";
+ 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]);
}
@@ -1459,12 +1587,6 @@ angular.module('zmApp.controllers')
};
-
-
-
-
-
-
//--------------------------------------
// formats events dates in a nice way
//---------------------------------------
@@ -1498,7 +1620,6 @@ angular.module('zmApp.controllers')
};
-
$scope.doRefresh = function () {
doRefresh();
}; //dorefresh
@@ -1553,36 +1674,9 @@ 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');
- var loginData = ZMDataModel.getLogin();
- myevents[i].Event.BasePath = loginData.url + "/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 + "/";
-
+ 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;
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
index 4344d9be..0ffd5540 100644
--- a/www/templates/events-modal.html
+++ b/www/templates/events-modal.html
@@ -4,7 +4,7 @@
<ion-content style="background-color:#444444" ng-cloak>
<ion-scroll has-bouncing=false min-zoom=1 zooming="true" direction="xy" style="width: 100%; ">
- <div style="height: 100vh;">
+ <div id="full-screen-event" style="height: 100vh;">
<div ng-if="defaultVideo=='' || loginData.enableh264==false">
@@ -12,7 +12,7 @@
<li ng-repeat="slide in slides">
- <img imageonload="finishedLoadingImage($index)" image-spinner-src="{{playbackURL}}/index.php?view=image&rand={{$root.rand}}&path={{relativePath}}{{slide.img}}&scale=100" image-spinner-loader="lines" ng-class="{'zm-image-fit':imageFit==true, 'zm-image-crop':imageFit==false}" />
+ <img imageonload="finishedLoadingImage($index)" image-spinner-src="{{playbackURL}}/index.php?view=image&rand={{$root.rand}}&path={{relativePath}}{{slide.img}}&scale=100" image-spinner-loader="lines" ng-class="{'zm-image-fit':imageFit==true, 'zm-image-crop':imageFit==false}" />
<!--<img id="hello" imageonload="finishedLoadingImage($index)"
image-spinner-src="{{eventBasePath}}{{slide.img}}?rand={{rand}}"
@@ -31,7 +31,7 @@
</vg-media>
</videogular>
</div>
-
+
</div>
@@ -54,15 +54,14 @@
<nav mfb-menu position="tr" effect="zoomin" label="collapse" active-icon="ion-chevron-up" resting-icon="ion-chevron-down" toggling-method="click">
+ <a mfb-button icon="ion-arrow-right-c" label="next event" ng-click="jumpToEvent(nextId,1);"></a>
+ <a mfb-button icon="ion-arrow-left-c" label="prev. event" ng-click="jumpToEvent(prevId,-1);"></a>
<a mfb-button icon="ion-arrow-resize" label="fit image" ng-click="scaleImage();"></a>
- <!--<a mfb-button icon="ion-reply" label="previous event"
- ng-click="controlEventStream(eventCommands.previous)"></a>
- <a mfb-button icon="ion-forward" label="next event"
- ng-click="controlEventStream(eventCommands.next)"></a>-->
+
<a mfb-button icon="ion-close" label="exit event view" ng-click="closeModal()"> </a>
</nav>
-<div class="events-range-modal-text">playing event: {{eventId}}</div>
+<div class="events-range-modal-text">playing event: {{eventId}}, next:{{nextId}}, prev:{{prevId}}</div>
<div class="events-range-modal" ng-if="defaultVideo==''">
<div style="width:90%">
diff --git a/www/templates/events.html b/www/templates/events.html
index 9daa7b6b..88737207 100644
--- a/www/templates/events.html
+++ b/www/templates/events.html
@@ -111,7 +111,7 @@
<button class="button button-small icon icon-left ion-ios-eye"
- ng-click="closeIfOpen(event);openModal(event.Event.Id, event.Event.Name, event.Event.Length,event.Event.Frames, event.Event.BasePath, event.Event.relativePath, event)" > View Footage
+ ng-click="closeIfOpen(event);openModal(event)" > View Footage
</button>
</span>