summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/css/style.css80
-rw-r--r--www/js/EventCtrl.js2
-rw-r--r--www/js/EventModalCtrl.js6
-rw-r--r--www/js/MenuController.js1
-rw-r--r--www/js/MontageCtrl.js284
-rw-r--r--www/js/NVR.js911
-rw-r--r--www/js/TimelineCtrl.js2
-rwxr-xr-xwww/js/app.js8
-rw-r--r--www/lang/locale-en.json6
-rw-r--r--www/templates/devoptions.html8
-rw-r--r--www/templates/montage.html109
11 files changed, 925 insertions, 492 deletions
diff --git a/www/css/style.css b/www/css/style.css
index e8ba18c7..e688f152 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -279,19 +279,85 @@ figcaption {
white-space: nowrap;
}
+.montage-sidebar {
+ background: rgba(83, 92, 104,1.0);
+ color: #FFF;
+ font-size: 80% !important;
+ padding: 5px !important;
+
+ box-sizing: border-box !important;
+
+}
+
+.circle {
+ margin:auto;
+
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border-color: #fff !important;
+ font-size: 80% !important;
+ font-style: bold !important;
+ color: #fff;
+ line-height: 40px;
+ text-align:center;
+
+ background:rgba(155, 89, 182,1.0);
+ }
+
+.montage-image {
+ position:relative;
+}
+
+.montage-buttons {
+ z-index: 9999;
+ position: absolute;
+ right:0;
+ bottom:0;
+ opacity:0.7;
+ margin: auto;
+}
+
+.montage-sidebar-button {
+ z-index: 9999;
+ position: absolute;
+ right:0;
+ bottom:50%;
+ opacity:0.7;
+ margin: auto;
+}
.normal-figcaption {
background: rgba(0, 0, 0, 0.2);
color: #FFF;
- position: absolute;
+ /*position: absolute;
bottom: 0;
left: 0;
- right: 0;
+ right: 0;*/
+ opacity: 1;
+ font-size: 80%;
+}
+
+.alarmed-figcaption {
+ background: #ba3e3e;
+ color: #ffffff;
+ opacity: 0.7;
+ font-size: 80%;
+}
+.extended-figcaption {
+ background: rgba(52, 152, 219,0.2);
+ color: #FFF;
+ /*position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;*/
opacity: 1;
font-size: 80%;
}
+
+
.normal-subfigcaption {
color: #FFF;
position: absolute;
@@ -322,15 +388,7 @@ figcaption {
-.alarmed-figcaption {
- background: #ba3e3e;
- color: #ffffff;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- opacity: 0.7;
-}
+
/* modified from:
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index 15ae11df..b8a59e28 100644
--- a/www/js/EventCtrl.js
+++ b/www/js/EventCtrl.js
@@ -93,8 +93,6 @@ angular.module('zmApp.controllers')
$scope.$on('$ionicView.afterEnter', function () {
- // console.log ("********* AFTER ENTER");
- //
window.addEventListener("resize", recomputeThumbSize, false);
$ionicListDelegate.canSwipeItems(true);
// NVR.debug("enabling options swipe");
diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js
index f22f6dc0..096fc52f 100644
--- a/www/js/EventModalCtrl.js
+++ b/www/js/EventModalCtrl.js
@@ -212,7 +212,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
};
$scope.onPlaybackUpdate = function (rate) {
- // console.log ("UPDATED RATE TO "+rate);
+ //console.log ("UPDATED RATE TO "+rate);
var ld = NVR.getLogin();
ld.videoPlaybackSpeed = rate;
NVR.setLogin(ld);
@@ -244,7 +244,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
});
}
}
- NVR.debug ("Invoking play as video can be played");
+ var rate = NVR.getLogin().videoPlaybackSpeed;
+ NVR.debug ("Invoking play at rate:"+rate+" as video can be played");
+ handle.setPlayback (rate);
handle.play();
};
diff --git a/www/js/MenuController.js b/www/js/MenuController.js
index c8127c75..a7e2e640 100644
--- a/www/js/MenuController.js
+++ b/www/js/MenuController.js
@@ -69,6 +69,7 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
var zmServers = NVR.getServerGroups();
var loginData = zmServers[s];
NVR.debug("Retrieved state for this profile:" + JSON.stringify(loginData));
+ NVR.checkInitSanity(loginData);
NVR.setLogin(loginData);
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index 87794ba9..1a0fcffa 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -16,6 +16,7 @@ angular.module('zmApp.controllers')
var intervalHandleAlarmStatus; // status of each alarm state
var intervalHandleMontageCycle;
var intervalHandleReloadPage;
+ var intervalHandleEventStatus;
var gridcontainer;
var pckry, draggie;
@@ -583,12 +584,92 @@ angular.module('zmApp.controllers')
}
+
+
+ $scope.humanizeTime = function(str) {
+ //console.log ("Time:"+str+" TO LOCAL " + moment(str).local().toString());
+ //if (NVR.getLogin().useLocalTimeZone)
+ return moment.tz(str, NVR.getTimeZoneNow()).fromNow();
+ // else
+ // return moment(str).fromNow();
+
+ };
+
+ function getEventStatus(monitor) {
+ ld = NVR.getLogin();
+
+ // https:///zm/api/events/index/MonitorId=:2.json?sort=StartTime&direction=desc&limit=1
+
+ var apiurl = ld.apiurl +'/events/index'; // we need some interval or it errors
+ apiurl += "/MonitorId =:" + monitor.Monitor.Id;
+ if (monitor.Monitor.Id in ld.lastEventCheckTimes) {
+
+ // now is server TZ time
+ var now = ld.lastEventCheckTimes[monitor.Monitor.Id];
+ apiurl += "/StartTime >:" + now;
+
+ }
+
+ apiurl += "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0);
+
+ /*if ( !(monitor.Monitor.Id in ld.lastEventCheckTimes)) {
+ apiurl+= '/1 month';
+ NVR.debug ("No last time found for monitor:"+monitor.Monitor.Id+" assuming 1 month" )
+ } else {
+ var now = new moment();
+ var dur = moment.duration(now.diff(ld.lastEventCheckTimes[monitor.Monitor.Id]));
+ var interval = Math.floor(dur.asHours()) + moment.utc(dur.asMilliseconds()).format("-mm-ss");
+ NVR.debug ("Monitor "+monitor.Monitor.Id+" was last accessed "+interval+" ago");
+
+ apiurl += '/\'' + interval + '\' HOUR_SECOND';
+ }*/
+
+ apiurl += '.json?sort=StartTime&direction=desc&limit=1';
+
+ NVR.debug ("Getting event count using:"+apiurl);
+ $http.get(apiurl)
+ .then (function (data) {
+ // console.log ("EVENTS GOT: "+JSON.stringify(data));
+ var res = data.data;
+ var mid = monitor.Monitor.Id;
+ if (res.events.length == 0) res = undefined;
+ monitor.Monitor.lastEvent = res;
+
+ },
+ function (err) {
+ NVR.debug ("event status load failed: "+JSON.stringify(data));
+ });
+
+
+ }
+
+ function loadEventStatus() {
+ // console.log ("LOADING EVENT STATUS");
+
+ if (!NVR.getLogin().enableMontageOverlays) {
+ //NVR.debug ("not loading events, as overlay is off");
+ return;
+ }
+
+ for (i = 0; i < $scope.MontageMonitors.length; i++) {
+ if ($scope.MontageMonitors[i].Monitor.Enabled == 0 ||
+ $scope.MontageMonitors[i].Monitor.listDisplay == 'noshow' ||
+ $scope.MontageMonitors[i].Monitor.Function == 'None') continue;
+ getEventStatus($scope.MontageMonitors[i]);
+
+ }
+
+
+ }
+
//-----------------------------------------------------------------------
// cycle through all displayed monitors and check alarm status
//-----------------------------------------------------------------------
function loadAlarmStatus() {
+ return; // lets focus on eventDetails now. Apr 2019
+ /*
if ((NVR.versionCompare($rootScope.apiVersion, "1.30") == -1) ||
(NVR.getBandwidth() == 'lowbw') ||
(NVR.getLogin().disableAlarmCheckMontage == true)) {
@@ -605,7 +686,7 @@ angular.module('zmApp.controllers')
}
getAlarmStatus($scope.MontageMonitors[i]);
- }
+ }*/
}
@@ -953,6 +1034,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -995,6 +1077,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage); //we will renew on reload
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
var ld = NVR.getLogin();
@@ -1224,6 +1307,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -1291,6 +1375,7 @@ angular.module('zmApp.controllers')
// console.log ("closeModal: Cancelling timer");
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleReloadPage);
@@ -1305,6 +1390,12 @@ angular.module('zmApp.controllers')
// console.log ("Refreshing Image...");
}.bind(this), zm.alarmStatusTime);
+ loadEventStatus();
+ intervalHandleEventStatus = $interval(function () {
+ loadEventStatus();
+ // console.log ("Refreshing Image...");
+ }.bind(this), zm.eventCheckTime);
+
intervalHandleMontageCycle = $interval(function () {
cycleMontageProfiles();
// console.log ("Refreshing Image...");
@@ -1349,6 +1440,11 @@ angular.module('zmApp.controllers')
cleanupOnCloseModal();
+ } else if ($scope.eventModalOpen) {
+
+ $scope.eventModalOpen = false;
+ NVR.debug ("event just played, need to force reload");
+ forceReloadPage();
} else {
NVR.debug("Ignoring double-invocation");
}
@@ -1377,6 +1473,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
if (pckry) pckry.destroy();
@@ -1774,6 +1871,128 @@ angular.module('zmApp.controllers')
NVR.debug ("Image load error for: "+monitor.Monitor.Id+" regenerated connKey is:"+monitor.Monitor.connKey);
};
+
+ $scope.showEvent = function(monitor) {
+
+ var ld = NVR.getLogin();
+ var url = ld.apiurl;
+ url += '/events/'+monitor.Monitor.lastEvent.events[0].Event.Id+'.json';
+ var mid = monitor.Monitor.Id;
+
+ ld.lastEventCheckTimes[mid] = (new moment()).tz(NVR.getTimeZoneNow()).format('YYYY-MM-DD HH:mm:ss');
+ NVR.debug ("Updating monitor:"+mid+" event check time (server tz) to " + ld.lastEventCheckTimes[mid] );
+ NVR.setLogin(ld);
+ monitor.Monitor.lastEvent = undefined;
+
+ $http.get(url)
+ .then ( function (succ) {
+ var data = succ.data;
+
+ var event = data.event;
+ $scope.event = event;
+ $scope.currentEvent = event;
+
+ $scope.eventModalOpen = true;
+ // $scope.isModalActive = true;
+ // Note: no need to setAwake(true) as its already awake
+ // in montage view
+
+ currentStreamState = streamState.PAUSED;
+ $scope.isModalStreamPaused = true; // we stop montage and start modal stream in snapshot first
+ $timeout(function () { // after render
+
+
+ if (simulStreaming) {
+ NVR.debug("Killing all streams in montage to save memory/nw...");
+
+
+ for (var i = 0; i < $scope.MontageMonitors.length; i++) {
+ if ($scope.MontageMonitors[i].Monitor.listDisplay == 'show') NVR.killLiveStream($scope.MontageMonitors[i].Monitor.connKey, $scope.MontageMonitors[i].Monitor.controlURL, $scope.MontageMonitors[i].Monitor.Name);
+ }
+
+ }
+
+ });
+
+ NVR.log("Cancelling montage timer, opening Modal");
+ // NVR.log("Starting Modal timer");
+ //console.log ("openModal:Cancelling timer");
+ $interval.cancel(intervalHandleMontage);
+ $interval.cancel(intervalHandleMontageCycle);
+ $interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
+ $interval.cancel(intervalHandleReloadPage);
+
+
+ $scope.followSameMonitor = "1";
+ $scope.mycarousel = {
+ index: 0
+ };
+ $scope.ionRange = {
+ index: 1
+ };
+
+ //prepareModalEvent(event.Event.Id);
+
+ var ld = NVR.getLogin();
+ var sl = 'disabled';
+ if (ld.showLiveForInProgressEvents) {
+ sl = 'enabled';
+ }
+
+ $scope.modalData = {
+ doRefresh: false
+ };
+ $ionicModal.fromTemplateUrl('templates/events-modal.html', {
+ scope: $scope, // give ModalCtrl access to this scope
+ animation: 'slide-in-up',
+ id: 'footage',
+ showLive: sl
+ })
+ .then(function (modal) {
+ $scope.modal = modal;
+
+ $ionicLoading.show({
+ template: $translate.instant('kPleaseWait') + "...",
+ noBackdrop: true,
+ duration: 10000,
+
+ });
+
+ $scope.modal.show();
+
+ var ld = NVR.getLogin();
+
+ });
+
+ });
+
+
+
+ };
+ $scope.constructEventThumbnail = function (monitor) {
+ var stream = "";
+
+ if (!monitor.Monitor.lastEvent) {
+ return '';
+ }
+
+
+ // console.log (JSON.stringify(monitor));
+ stream = monitor.Monitor.recordingURL +
+ "/index.php?view=image&width=400&fid=snapshot" +
+ "&eid="+monitor.Monitor.lastEvent.events[0].Event.Id ;
+
+
+
+ if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
+
+ stream += NVR.insertBasicAuthToken();
+ // console.log (stream);
+ return stream;
+
+ };
+
$scope.constructStream = function (monitor) {
var stream;
@@ -1825,10 +2044,21 @@ angular.module('zmApp.controllers')
NVR.setLogin(ld);
};
+ $scope.toggleSidebar = function(monitor) {
+
+ monitor.Monitor.showSidebar = !monitor.Monitor.showSidebar;
+ $timeout (function() {
+
+ $scope.squeezeMonitors();
+ }, 300);
+
+ };
+
// minimal has to be beforeEnter or header won't hide
$scope.$on('$ionicView.beforeEnter', function () {
-
+
+ $scope.eventModalOpen = false;
$scope.$on ( "process-push", function () {
NVR.debug (">> MontageCtrl: push handler");
var s = NVR.evaluateTappedNotification();
@@ -1960,6 +2190,7 @@ angular.module('zmApp.controllers')
$interval.cancel(intervalHandleMontage);
$interval.cancel(intervalHandleMontageCycle);
$interval.cancel(intervalHandleAlarmStatus);
+ $interval.cancel(intervalHandleEventStatus);
$interval.cancel(intervalHandleReloadPage);
@@ -1979,6 +2210,12 @@ angular.module('zmApp.controllers')
// console.log ("Refreshing Image...");
}.bind(this), zm.alarmStatusTime);
+ loadEventStatus();
+ intervalHandleEventStatus = $interval(function () {
+ loadEventStatus();
+ // console.log ("Refreshing Image...");
+ }.bind(this), zm.eventCheckTime);
+
intervalHandleReloadPage = $interval(function () {
forceReloadPage();
}.bind(this), reloadPage);
@@ -2006,12 +2243,15 @@ angular.module('zmApp.controllers')
NVR.log("Inside Montage Ctrl:We found " + $scope.monitors.length + " monitors");
+
// set them all at 50% for packery
for (var i = 0; i < $scope.MontageMonitors.length; i++) {
$scope.MontageMonitors[i].Monitor.gridScale = "50";
$scope.MontageMonitors[i].Monitor.selectStyle = "";
$scope.MontageMonitors[i].Monitor.alarmState = 'rgba(0,0,0,0)';
$scope.MontageMonitors[i].Monitor.isStamp = false;
+ $scope.MontageMonitors[i].Monitor.eventCount = 0;
+ $scope.MontageMonitors[i].Monitor.showSidebar = false;
}
@@ -2031,6 +2271,23 @@ angular.module('zmApp.controllers')
});
+
+ $scope.eventButtonClicked = function (monitor, showEvents) {
+ var ld = NVR.getLogin();
+ mid = monitor.Monitor.Id;
+ // always use server tz to avoid confusion
+ ld.lastEventCheckTimes[mid] = (new moment()).tz(NVR.getTimeZoneNow()).format('YYYY-MM-DD HH:mm:ss');
+ NVR.debug ("Updating monitor:"+mid+" event check time (server tz) to " + ld.lastEventCheckTimes[mid] );
+ NVR.setLogin(ld);
+ monitor.Monitor.lastEvent = undefined;
+ if (!showEvents) return;
+ $state.go("app.events", {
+ "id": monitor.Monitor.Id,
+ "playEvent": false
+ });
+ return;
+
+ };
$scope.$on('$ionicView.beforeLeave', function () {
currentStreamState = streamState.STOPPED;
@@ -2087,7 +2344,8 @@ angular.module('zmApp.controllers')
NVR.debug("doing the jiggle and dance...");
pckry.resize(true);
pckry.shiftLayout();
- }, 300);
+ }, 600);
+
// $scope.slider.monsize = 2;
});
@@ -2102,7 +2360,27 @@ angular.module('zmApp.controllers')
}
+ $scope.formatBytes = function (bytes, decimals) {
+
+ return formatBytes (bytes, decimals);
+ };
+
+ //https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript?answertab=active#tab-top
+ function formatBytes(bytes, decimals) {
+ if (bytes === undefined) return '?';
+ if (bytes === null) return '0B';
+ if (bytes === 0) return '0B';
+ var k = 1024;
+ var dm = decimals < 0 ? 0 : decimals;
+ var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+ var i = Math.floor(Math.log(bytes) / Math.log(k));
+
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
+ }
+
$scope.squeezeMonitors = function () {
+ console.log ("squeezing");
pckry.once('layoutComplete', resizeComplete);
$timeout(function () {
pckry.layout();
diff --git a/www/js/NVR.js b/www/js/NVR.js
index 80b953fd..2f30df48 100644
--- a/www/js/NVR.js
+++ b/www/js/NVR.js
@@ -192,6 +192,9 @@ angular.module('zmApp.controllers')
'montageReviewCollapse': true,
'objectDetectionFilter': false,
'enableEventRefresh': true,
+ 'lastEventCheckTimes':{},
+ 'enableMontageOverlays': true
+
};
@@ -597,6 +600,463 @@ angular.module('zmApp.controllers')
return 0;
}
+ function _checkInitSanity(loginData) {
+ // old version hacks for new variables
+
+ // always true Oct 27 2016
+ loginData.persistMontageOrder = true;
+ loginData.enableh264 = true;
+
+ if (typeof loginData.isUseBasicAuth === 'undefined') {
+ loginData.isUseBasicAuth = false;
+ loginData.basicAuthUser = '';
+ loginData.basicAuthPassword = '';
+ $rootScope.basicAuthHeader = '';
+ $rootScope.basicAuthToken = '';
+ }
+
+ if (loginData.url.indexOf('@') != -1) {
+ log(">> " + loginData.url);
+ log(">>User/Password detected in URL, changing to new auth handling...");
+ loginData.isUseBasicAuth = true;
+
+ var components = URI.parse(loginData.url);
+ loginData.url = components.scheme + "://" + components.host;
+ if (components.port) loginData.url = loginData.url + ":" + components.port;
+ if (components.path) loginData.url = loginData.url + components.path;
+
+ components = URI.parse(loginData.streamingurl);
+ loginData.streamingurl = components.scheme + "://" + components.host;
+ if (components.port) loginData.streamingurl = loginData.streamingurl + ":" + components.port;
+ if (components.path) loginData.streamingurl = loginData.streamingurl + components.path;
+
+
+ components = URI.parse(loginData.apiurl);
+ loginData.apiurl = components.scheme + "://" + components.host;
+ if (components.port) loginData.apiurl = loginData.apiurl + ":" + components.port;
+ if (components.path) loginData.apiurl = loginData.apiurl + components.path;
+
+ $rootScope.basicAuthToken = btoa(components.userinfo);
+ $rootScope.basicAuthHeader = 'Basic ' + $rootScope.basicAuthToken;
+ //console.log (">>>> SET BASIC AUTH TO " + $rootScope.basicAuthHeader);
+
+ var up = components.userinfo.split(':');
+ loginData.basicAuthPassword = up[1];
+ loginData.basicAuthUser = up[0];
+ //console.log ("SETTING "+loginData.basicAuthUser+" "+loginData.basicAuthPassword);
+
+ }
+
+ if (loginData.isUseBasicAuth) {
+ $rootScope.basicAuthToken = btoa(loginData.basicAuthUser + ':' + loginData.basicAuthPassword);
+ $rootScope.basicAuthHeader = 'Basic ' + $rootScope.basicAuthToken;
+ debug("Basic authentication detected, constructing Authorization Header");
+
+ // console.log ("BASIC AUTH SET TO:"+$rootScope.basicAuthHeader);
+
+ }
+
+
+ if (typeof loginData.enableAlarmCount === 'undefined') {
+ debug("enableAlarmCount does not exist, setting to true");
+ loginData.enableAlarmCount = true;
+ }
+
+ if (typeof loginData.onTapScreen == 'undefined') {
+ loginData.onTapScreen = $translate.instant('kTapMontage');
+ }
+
+ if (loginData.onTapScreen != $translate.instant('kTapMontage') &&
+ loginData.onTapScreen != $translate.instant('kTapEvents') &&
+ loginData.onTapScreen != $translate.instant('kTapLiveMonitor')) {
+ log("Invalid onTap setting found, resetting. I got " + loginData.onTapScreen);
+ loginData.onTapScreen = $translate.instant('kMontage');
+ }
+
+ if (typeof loginData.minAlarmCount === 'undefined') {
+ debug("minAlarmCount does not exist, setting to true");
+ loginData.minAlarmCount = 1;
+ }
+
+ if (typeof loginData.montageSize == 'undefined') {
+ debug("montageSize does not exist, setting to 2 (2 per col)");
+ loginData.montageSize = 2;
+ }
+
+ if (typeof loginData.useNphZms == 'undefined') {
+ debug("useNphZms does not exist. Setting to true");
+ loginData.useNphZms = true;
+ }
+
+ if (typeof loginData.useNphZmsForEvents == 'undefined') {
+ debug("useNphZmsForEvents does not exist. Setting to true");
+ loginData.useNphZmsForEvents = true;
+ }
+
+ if (typeof loginData.forceImageModePath == 'undefined') {
+ debug("forceImageModePath does not exist. Setting to false");
+ loginData.forceImageModePath = false;
+ }
+
+ if (typeof loginData.reachability == 'undefined') {
+ debug("reachability does not exist. Setting to true");
+ loginData.reachability = true;
+ }
+
+
+ // force it - this may not be the problem
+ loginData.reachability = true;
+
+ // and now, force enable it
+ loginData.useNphZms = true;
+ loginData.useNphZmsForEvents = true;
+
+ if (typeof loginData.packMontage == 'undefined') {
+ debug("packMontage does not exist. Setting to false");
+ loginData.packMontage = false;
+ }
+
+ if (typeof loginData.forceNetworkStop == 'undefined') {
+ debug("forceNetwork does not exist. Setting to false");
+ loginData.forceNetworkStop = false;
+ }
+
+ if (typeof loginData.enableLogs == 'undefined') {
+ debug("enableLogs does not exist. Setting to true");
+ loginData.enableLogs = true;
+ }
+
+ if (typeof loginData.defaultPushSound == 'undefined') {
+ debug("defaultPushSound does not exist. Setting to false");
+ loginData.defaultPushSound = false;
+ }
+
+
+ //console.log("INIT SIMUL=" + loginData.disableSimulStreaming);
+ //console.log("INIT PLATFORM IS=" + $rootScope.platformOS);
+ if (typeof loginData.disableSimulStreaming == 'undefined') {
+
+
+ loginData.disableSimulStreaming = false;
+ //console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
+ }
+
+
+ if (typeof loginData.exitOnSleep == 'undefined') {
+ debug("exitOnSleep does not exist. Setting to false");
+ loginData.exitOnSleep = false;
+ }
+
+ if (typeof loginData.enableBlog == 'undefined') {
+ debug("enableBlog does not exist. Setting to true");
+ loginData.enableBlog = true;
+
+ }
+
+ if (typeof loginData.packeryPositionsArray == 'undefined') {
+ debug("packeryPositionsArray does not exist. Setting to empty");
+ loginData.packeryPositionsArray = {};
+
+ }
+
+
+ if (typeof loginData.packeryPositions == 'undefined') {
+ debug("packeryPositions does not exist. Setting to empty");
+ loginData.packeryPositions = "";
+
+ }
+
+ if (typeof loginData.EHpackeryPositions == 'undefined') {
+ debug("EHpackeryPositions does not exist. Setting to empty");
+ loginData.EHpackeryPositions = "";
+
+ }
+
+ if (typeof loginData.packerySizes == 'undefined') {
+ debug("packerySizes does not exist. Setting to empty");
+ loginData.packerySizes = "";
+
+ }
+
+ if (typeof loginData.use24hr == 'undefined') {
+ debug("use24hr does not exist. Setting to false");
+ loginData.use24hr = false;
+
+ }
+
+ if (typeof timelineModalGraphType == 'undefined') {
+ debug("timeline graph type not set. Setting to all");
+ loginData.timelineModalGraphType = $translate.instant('kGraphAll');
+ //console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + loginData.timelineModalGraphType);
+ }
+
+ if (typeof loginData.resumeDelay == 'undefined') {
+ debug("resumeDelay does not exist. Setting to 0");
+ loginData.resumeDelay = 0;
+
+ }
+ // override resumeDelay - it was developed on a wrong assumption
+ loginData.resumeDelay = 0;
+
+ if (typeof loginData.montageHistoryQuality == 'undefined') {
+ debug("montageHistoryQuality does not exist. Setting to 50");
+ loginData.montageHistoryQuality = "50";
+
+ }
+
+
+
+ if (typeof loginData.vibrateOnPush == 'undefined') {
+ debug("vibrate on push not found, setting to true");
+ loginData.vibrateOnPush = true;
+
+ }
+
+ if (typeof loginData.isFullScreen == 'undefined') {
+
+ loginData.isFullScreen = false;
+
+ }
+
+ if (typeof loginData.reloadInMontage == 'undefined') {
+
+ loginData.reloadInMontage = false;
+
+ }
+
+ if (typeof loginData.soundOnPush == 'undefined') {
+ debug("sound on push not found, setting to true");
+ loginData.soundOnPush = true;
+
+ }
+
+ if (typeof loginData.cycleMonitors == 'undefined') {
+
+ loginData.cycleMonitors = false;
+
+ }
+
+ if (typeof loginData.cycleMonitorsInterval == 'undefined') {
+
+ loginData.cycleMonitorsInterval = 10;
+
+ }
+
+ if (typeof loginData.cycleMontage == 'undefined') {
+
+ loginData.cycleMontage = false;
+
+ }
+
+ if (typeof loginData.cycleMontageInterval == 'undefined') {
+
+ loginData.cycleMontageInterval = 10;
+
+ }
+
+ if (typeof loginData.enableLowBandwidth == 'undefined') {
+
+ loginData.enableLowBandwidth = false;
+
+ }
+ // wtf is wrong with this ternary?
+ //$rootScope.runMode = (loginData.enableLowBandwith==true)? "low": "normal";
+
+ if (typeof loginData.autoSwitchBandwidth == 'undefined') {
+
+ loginData.autoSwitchBandwidth = false;
+
+ }
+
+ $rootScope.runMode = getBandwidth();
+ log("Setting NVR init bandwidth to: " + $rootScope.runMode);
+
+ if (typeof loginData.refreshSecLowBW == 'undefined') {
+
+ loginData.refreshSecLowBW = 8;
+
+ }
+
+ if (typeof loginData.disableAlarmCheckMontage == 'undefined') {
+
+ loginData.disableAlarmCheckMontage = false;
+
+ }
+
+ if (typeof loginData.useLocalTimeZone == 'undefined') {
+
+ loginData.useLocalTimeZone = true;
+
+ }
+
+ if (typeof loginData.fastLogin == 'undefined') {
+
+ loginData.fastLogin = true;
+
+ }
+
+ if (typeof loginData.currentMontageProfile == 'undefined') {
+
+ loginData.currentMontageProfile = '';
+
+ }
+
+ if (typeof loginData.followTimeLine == 'undefined') {
+
+ loginData.followTimeLine = false;
+
+ }
+
+ if (typeof loginData.timelineScale == 'undefined') {
+
+ loginData.timelineScale = -1;
+
+ }
+
+
+ if (typeof loginData.showMontageSubMenu == 'undefined') {
+
+ loginData.showMontageSubMenu = false;
+
+ }
+
+
+
+ if (typeof loginData.monSingleImageQuality == 'undefined') {
+
+ loginData.monSingleImageQuality = 100;
+
+ }
+
+ if (typeof loginData.hideArchived == 'undefined') {
+
+ loginData.hideArchived = false;
+
+ }
+
+ if (typeof loginData.videoPlaybackSpeed == 'undefined') {
+
+ loginData.videoPlaybackSpeed = 1;
+
+ }
+
+
+
+ if (typeof loginData.enableThumbs == 'undefined') {
+
+ loginData.enableThumbs = true;
+
+ }
+
+ if (typeof loginData.enableSlowLoading == 'undefined') {
+
+ loginData.enableSlowLoading = false;
+
+ }
+
+
+ if (typeof loginData.enableStrictSSL == 'undefined') {
+
+ loginData.enableStrictSSL = false;
+
+ }
+
+ if (typeof loginData.momentGridSize == 'undefined') {
+
+ loginData.momentGridSize = 40;
+
+ }
+
+ if (typeof loginData.enableMomentSubMenu == 'undefined') {
+
+ loginData.enableMomentSubMenu = true;
+
+ }
+
+ if (typeof loginData.momentMonitorFilter == 'undefined') {
+
+ loginData.momentMonitorFilter = JSON.stringify([]);
+
+ }
+
+
+ if (typeof loginData.momentArrangeBy == 'undefined') {
+
+ loginData.momentArrangeBy = "StartTime";
+
+ }
+
+ if (typeof loginData.insertBasicAuthToken == 'undefined') {
+
+ loginData.insertBasicAuthToken = false;
+
+ }
+
+
+ if (typeof loginData.showLiveForInProgressEvents == 'undefined') {
+
+ loginData.showLiveForInProgressEvents = true;
+
+ }
+
+
+ if (typeof loginData.loginAPISupported == 'undefined') {
+
+ loginData.loginAPISupported = false;
+
+ }
+
+ if (typeof loginData.montageResizeSteps == 'undefined') {
+
+ loginData.montageResizeSteps = 5;
+
+ }
+
+ if (typeof loginData.saveToCloud == 'undefined') {
+
+ loginData.saveToCloud = true;
+
+ }
+
+
+
+ if (typeof loginData.montageReviewCollapse == 'undefined') {
+
+ loginData.montageReviewCollapse = true;
+
+ }
+
+ if (typeof loginData.objectDetectionFilter == 'undefined') {
+
+ loginData.objectDetectionFilter = false;
+
+ }
+
+ if (typeof loginData.enableEventRefresh == 'undefined') {
+
+ loginData.enableEventRefresh = true;
+
+ }
+
+
+
+ if (typeof loginData.lastEventCheckTimes == 'undefined') {
+ loginData.lastEventCheckTimes = {};
+
+ }
+
+
+ if (typeof loginData.enableMontageOverlays == 'undefined') {
+ loginData.enableMontageOverlays = true;
+
+ }
+
+ loginData.canSwipeMonitors = true;
+ loginData.forceImageModePath = false;
+ loginData.enableBlog = true;
+
+ }
+
//--------------------------------------------------------------------------
// Banner display of messages
//--------------------------------------------------------------------------
@@ -1024,6 +1484,10 @@ angular.module('zmApp.controllers')
},
+ checkInitSanity: function (l) {
+ _checkInitSanity(l);
+ },
+
init: function () {
@@ -1078,449 +1542,7 @@ angular.module('zmApp.controllers')
// console.log(">>>>>>>>>>> loadedData is: " + JSON.stringify(loadedData));
if (!isEmpty(loadedData)) {
loginData = loadedData;
-
- // old version hacks for new variables
-
- // always true Oct 27 2016
- loginData.persistMontageOrder = true;
- loginData.enableh264 = true;
-
- if (typeof loginData.isUseBasicAuth === 'undefined') {
- loginData.isUseBasicAuth = false;
- loginData.basicAuthUser = '';
- loginData.basicAuthPassword = '';
- $rootScope.basicAuthHeader = '';
- $rootScope.basicAuthToken = '';
- }
-
- if (loginData.url.indexOf('@') != -1) {
- log(">> " + loginData.url);
- log(">>User/Password detected in URL, changing to new auth handling...");
- loginData.isUseBasicAuth = true;
-
- var components = URI.parse(loginData.url);
- loginData.url = components.scheme + "://" + components.host;
- if (components.port) loginData.url = loginData.url + ":" + components.port;
- if (components.path) loginData.url = loginData.url + components.path;
-
- components = URI.parse(loginData.streamingurl);
- loginData.streamingurl = components.scheme + "://" + components.host;
- if (components.port) loginData.streamingurl = loginData.streamingurl + ":" + components.port;
- if (components.path) loginData.streamingurl = loginData.streamingurl + components.path;
-
-
- components = URI.parse(loginData.apiurl);
- loginData.apiurl = components.scheme + "://" + components.host;
- if (components.port) loginData.apiurl = loginData.apiurl + ":" + components.port;
- if (components.path) loginData.apiurl = loginData.apiurl + components.path;
-
- $rootScope.basicAuthToken = btoa(components.userinfo);
- $rootScope.basicAuthHeader = 'Basic ' + $rootScope.basicAuthToken;
- //console.log (">>>> SET BASIC AUTH TO " + $rootScope.basicAuthHeader);
-
- var up = components.userinfo.split(':');
- loginData.basicAuthPassword = up[1];
- loginData.basicAuthUser = up[0];
- //console.log ("SETTING "+loginData.basicAuthUser+" "+loginData.basicAuthPassword);
-
- }
-
- if (loginData.isUseBasicAuth) {
- $rootScope.basicAuthToken = btoa(loginData.basicAuthUser + ':' + loginData.basicAuthPassword);
- $rootScope.basicAuthHeader = 'Basic ' + $rootScope.basicAuthToken;
- debug("Basic authentication detected, constructing Authorization Header");
-
- // console.log ("BASIC AUTH SET TO:"+$rootScope.basicAuthHeader);
-
- }
-
-
- if (typeof loginData.enableAlarmCount === 'undefined') {
- debug("enableAlarmCount does not exist, setting to true");
- loginData.enableAlarmCount = true;
- }
-
- if (typeof loginData.onTapScreen == 'undefined') {
- loginData.onTapScreen = $translate.instant('kTapMontage');
- }
-
- if (loginData.onTapScreen != $translate.instant('kTapMontage') &&
- loginData.onTapScreen != $translate.instant('kTapEvents') &&
- loginData.onTapScreen != $translate.instant('kTapLiveMonitor')) {
- log("Invalid onTap setting found, resetting. I got " + loginData.onTapScreen);
- loginData.onTapScreen = $translate.instant('kMontage');
- }
-
- if (typeof loginData.minAlarmCount === 'undefined') {
- debug("minAlarmCount does not exist, setting to true");
- loginData.minAlarmCount = 1;
- }
-
- if (typeof loginData.montageSize == 'undefined') {
- debug("montageSize does not exist, setting to 2 (2 per col)");
- loginData.montageSize = 2;
- }
-
- if (typeof loginData.useNphZms == 'undefined') {
- debug("useNphZms does not exist. Setting to true");
- loginData.useNphZms = true;
- }
-
- if (typeof loginData.useNphZmsForEvents == 'undefined') {
- debug("useNphZmsForEvents does not exist. Setting to true");
- loginData.useNphZmsForEvents = true;
- }
-
- if (typeof loginData.forceImageModePath == 'undefined') {
- debug("forceImageModePath does not exist. Setting to false");
- loginData.forceImageModePath = false;
- }
-
- if (typeof loginData.reachability == 'undefined') {
- debug("reachability does not exist. Setting to true");
- loginData.reachability = true;
- }
-
-
- // force it - this may not be the problem
- loginData.reachability = true;
-
- // and now, force enable it
- loginData.useNphZms = true;
- loginData.useNphZmsForEvents = true;
-
- if (typeof loginData.packMontage == 'undefined') {
- debug("packMontage does not exist. Setting to false");
- loginData.packMontage = false;
- }
-
- if (typeof loginData.forceNetworkStop == 'undefined') {
- debug("forceNetwork does not exist. Setting to false");
- loginData.forceNetworkStop = false;
- }
-
- if (typeof loginData.enableLogs == 'undefined') {
- debug("enableLogs does not exist. Setting to true");
- loginData.enableLogs = true;
- }
-
- if (typeof loginData.defaultPushSound == 'undefined') {
- debug("defaultPushSound does not exist. Setting to false");
- loginData.defaultPushSound = false;
- }
-
-
- //console.log("INIT SIMUL=" + loginData.disableSimulStreaming);
- //console.log("INIT PLATFORM IS=" + $rootScope.platformOS);
- if (typeof loginData.disableSimulStreaming == 'undefined') {
-
-
- loginData.disableSimulStreaming = false;
- //console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
- }
-
-
- if (typeof loginData.exitOnSleep == 'undefined') {
- debug("exitOnSleep does not exist. Setting to false");
- loginData.exitOnSleep = false;
- }
-
- if (typeof loginData.enableBlog == 'undefined') {
- debug("enableBlog does not exist. Setting to true");
- loginData.enableBlog = true;
-
- }
-
- if (typeof loginData.packeryPositionsArray == 'undefined') {
- debug("packeryPositionsArray does not exist. Setting to empty");
- loginData.packeryPositionsArray = {};
-
- }
-
-
- if (typeof loginData.packeryPositions == 'undefined') {
- debug("packeryPositions does not exist. Setting to empty");
- loginData.packeryPositions = "";
-
- }
-
- if (typeof loginData.EHpackeryPositions == 'undefined') {
- debug("EHpackeryPositions does not exist. Setting to empty");
- loginData.EHpackeryPositions = "";
-
- }
-
- if (typeof loginData.packerySizes == 'undefined') {
- debug("packerySizes does not exist. Setting to empty");
- loginData.packerySizes = "";
-
- }
-
- if (typeof loginData.use24hr == 'undefined') {
- debug("use24hr does not exist. Setting to false");
- loginData.use24hr = false;
-
- }
-
- if (typeof timelineModalGraphType == 'undefined') {
- debug("timeline graph type not set. Setting to all");
- loginData.timelineModalGraphType = $translate.instant('kGraphAll');
- //console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + loginData.timelineModalGraphType);
- }
-
- if (typeof loginData.resumeDelay == 'undefined') {
- debug("resumeDelay does not exist. Setting to 0");
- loginData.resumeDelay = 0;
-
- }
- // override resumeDelay - it was developed on a wrong assumption
- loginData.resumeDelay = 0;
-
- if (typeof loginData.montageHistoryQuality == 'undefined') {
- debug("montageHistoryQuality does not exist. Setting to 50");
- loginData.montageHistoryQuality = "50";
-
- }
-
-
-
- if (typeof loginData.vibrateOnPush == 'undefined') {
- debug("vibrate on push not found, setting to true");
- loginData.vibrateOnPush = true;
-
- }
-
- if (typeof loginData.isFullScreen == 'undefined') {
-
- loginData.isFullScreen = false;
-
- }
-
- if (typeof loginData.reloadInMontage == 'undefined') {
-
- loginData.reloadInMontage = false;
-
- }
-
- if (typeof loginData.soundOnPush == 'undefined') {
- debug("sound on push not found, setting to true");
- loginData.soundOnPush = true;
-
- }
-
- if (typeof loginData.cycleMonitors == 'undefined') {
-
- loginData.cycleMonitors = false;
-
- }
-
- if (typeof loginData.cycleMonitorsInterval == 'undefined') {
-
- loginData.cycleMonitorsInterval = 10;
-
- }
-
- if (typeof loginData.cycleMontage == 'undefined') {
-
- loginData.cycleMontage = false;
-
- }
-
- if (typeof loginData.cycleMontageInterval == 'undefined') {
-
- loginData.cycleMontageInterval = 10;
-
- }
-
- if (typeof loginData.enableLowBandwidth == 'undefined') {
-
- loginData.enableLowBandwidth = false;
-
- }
- // wtf is wrong with this ternary?
- //$rootScope.runMode = (loginData.enableLowBandwith==true)? "low": "normal";
-
- if (typeof loginData.autoSwitchBandwidth == 'undefined') {
-
- loginData.autoSwitchBandwidth = false;
-
- }
-
- $rootScope.runMode = getBandwidth();
- log("Setting NVR init bandwidth to: " + $rootScope.runMode);
-
- if (typeof loginData.refreshSecLowBW == 'undefined') {
-
- loginData.refreshSecLowBW = 8;
-
- }
-
- if (typeof loginData.disableAlarmCheckMontage == 'undefined') {
-
- loginData.disableAlarmCheckMontage = false;
-
- }
-
- if (typeof loginData.useLocalTimeZone == 'undefined') {
-
- loginData.useLocalTimeZone = true;
-
- }
-
- if (typeof loginData.fastLogin == 'undefined') {
-
- loginData.fastLogin = true;
-
- }
-
- if (typeof loginData.currentMontageProfile == 'undefined') {
-
- loginData.currentMontageProfile = '';
-
- }
-
- if (typeof loginData.followTimeLine == 'undefined') {
-
- loginData.followTimeLine = false;
-
- }
-
- if (typeof loginData.timelineScale == 'undefined') {
-
- loginData.timelineScale = -1;
-
- }
-
-
- if (typeof loginData.showMontageSubMenu == 'undefined') {
-
- loginData.showMontageSubMenu = false;
-
- }
-
-
-
- if (typeof loginData.monSingleImageQuality == 'undefined') {
-
- loginData.monSingleImageQuality = 100;
-
- }
-
- if (typeof loginData.hideArchived == 'undefined') {
-
- loginData.hideArchived = false;
-
- }
-
- if (typeof loginData.videoPlaybackSpeed == 'undefined') {
-
- loginData.videoPlaybackSpeed = 2;
-
- }
-
-
-
- if (typeof loginData.enableThumbs == 'undefined') {
-
- loginData.enableThumbs = true;
-
- }
-
- if (typeof loginData.enableSlowLoading == 'undefined') {
-
- loginData.enableSlowLoading = false;
-
- }
-
-
- if (typeof loginData.enableStrictSSL == 'undefined') {
-
- loginData.enableStrictSSL = false;
-
- }
-
- if (typeof loginData.momentGridSize == 'undefined') {
-
- loginData.momentGridSize = 40;
-
- }
-
- if (typeof loginData.enableMomentSubMenu == 'undefined') {
-
- loginData.enableMomentSubMenu = true;
-
- }
-
- if (typeof loginData.momentMonitorFilter == 'undefined') {
-
- loginData.momentMonitorFilter = JSON.stringify([]);
-
- }
-
-
- if (typeof loginData.momentArrangeBy == 'undefined') {
-
- loginData.momentArrangeBy = "StartTime";
-
- }
-
- if (typeof loginData.insertBasicAuthToken == 'undefined') {
-
- loginData.insertBasicAuthToken = false;
-
- }
-
-
- if (typeof loginData.showLiveForInProgressEvents == 'undefined') {
-
- loginData.showLiveForInProgressEvents = true;
-
- }
-
-
- if (typeof loginData.loginAPISupported == 'undefined') {
-
- loginData.loginAPISupported = false;
-
- }
-
- if (typeof loginData.montageResizeSteps == 'undefined') {
-
- loginData.montageResizeSteps = 5;
-
- }
-
- if (typeof loginData.saveToCloud == 'undefined') {
-
- loginData.saveToCloud = true;
-
- }
-
-
-
- if (typeof loginData.montageReviewCollapse == 'undefined') {
-
- loginData.montageReviewCollapse = true;
-
- }
-
- if (typeof loginData.objectDetectionFilter == 'undefined') {
-
- loginData.objectDetectionFilter = false;
-
- }
-
- if (typeof loginData.enableEventRefresh == 'undefined') {
-
- loginData.enableEventRefresh = true;
-
- }
-
-
- loginData.canSwipeMonitors = true;
- loginData.forceImageModePath = false;
- loginData.enableBlog = true;
-
+ _checkInitSanity(loginData);
log("NVR init retrieved store loginData");
} else {
log("defaultServer configuration NOT found. Keeping login at defaults");
@@ -2336,7 +2358,7 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.streamingURL = st;
monitors[i].Monitor.baseURL = baseurl;
monitors[i].Monitor.controlURL = controlURL;
-
+ monitors[i].Monitor.recordingURL = controlURL;
debug("Storing baseurl=" + baseurl + " streamingURL=" + st + " recordingURL=" + controlURL);
//console.log ("** Streaming="+st+" **base="+baseurl);
@@ -2382,6 +2404,7 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.streamingURL = st2;
monitors[i].Monitor.controlURL = controlURL;
+ monitors[i].Monitor.recordingURL = controlURL;
//debug ("Streaming URL for Monitor " + monitors[i].Monitor.Id + " is " + monitors[i].Monitor.streamingURL );
//console.log ("NO SERVER MATCH CONSTRUCTED STREAMING PATH="+st2);
monitors[i].Monitor.baseURL = loginData.url;
diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js
index fb5ee265..3e09a24b 100644
--- a/www/js/TimelineCtrl.js
+++ b/www/js/TimelineCtrl.js
@@ -163,6 +163,8 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
//--------------------------------------------------------
function openModal(event) {
+ //console.log (JSON.stringify(event));
+
if ($scope.modalFromTimelineIsOpen == true) {
// don't know why but some conflict from angular to timeline_instance lib
// results in double modals at times
diff --git a/www/js/app.js b/www/js/app.js
index 7c03fbdd..cc941d9b 100755
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -105,7 +105,8 @@ angular.module('zmApp', [
forceMontageReloadDelay: 4500000, // 1 hr 15m,
//forceMontageReloadDelay: 10000, // testing 10s
thumbWidth: 200,
- alarmStatusTime: 10000,
+ alarmStatusTime: 10000, // 10 sec
+ eventCheckTime: 30000, // 30 seconds
eventServerErrorDelay: 5000, // time to wait till I report initial connect errors
zmVersionCheckNag: 60 * 24, // in hrs
waitTimeTillResume: 5, // in sec, for ES error
@@ -2316,7 +2317,8 @@ angular.module('zmApp', [
// if they occur. I suspect digest and other errors will be useful
// for me to see
//$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/);
-
+ $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|content|cdvphotolibrary|blob|unsafe|local):|data:image\//);
+
$provide.decorator("$exceptionHandler", ['$delegate', '$injector', function ($delegate, $injector) {
return function (exception, cause) {
@@ -2470,7 +2472,7 @@ angular.module('zmApp', [
// so it messes up scrolldelegate zoom and possibly others
//$ionicConfigProvider.scrolling.jsScrolling(false);
$compileProvider.debugInfoEnabled(false);
- $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/);
+
/*$ionicNativeTransitionsProvider.setDefaultOptions({
duration: 250,
diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json
index 4f7039f6..a0276fea 100644
--- a/www/lang/locale-en.json
+++ b/www/lang/locale-en.json
@@ -232,6 +232,11 @@
"kMonitorVideoPassThru" :"H264 Pass through",
"kMonitorVideoEncode" :"X264 Video Encode",
"kMontage" :"Montage",
+ "kMontageEnableOverlays" :"Enable montage overlay buttons",
+ "kMontageEventStorage" : "storage",
+ "kMontageEventUnseenCount" : "unseen",
+ "kMontageEventCaughtUp" : "All caught up!",
+ "kMontageEventLatest" : "latest",
"kMontageDefaultProfile" :"all monitors",
"kMontageImageScale" :"Montage image scale",
"kMontageNoSavedProfiles" :"No saved montage profiles",
@@ -310,6 +315,7 @@
"kReconfirmPin" :"Reconfirm PIN",
"kRecordingProgress" :"recording in progress",
"kRefresh" :"refresh",
+ "kReflow" :"reflow",
"kRefreshedView" :"refreshed view",
"kReportEvents" :"report events",
"kReportedVersion" :"Reported Version",
diff --git a/www/templates/devoptions.html b/www/templates/devoptions.html
index aeb036d4..cf35d2ef 100644
--- a/www/templates/devoptions.html
+++ b/www/templates/devoptions.html
@@ -44,6 +44,14 @@
</ion-toggle>
</label>
+
+ <label>
+ <ion-toggle ng-model="loginData.enableMontageOverlays" toggle-class="toggle-calm">
+ <span class="item-text-wrap">{{'kMontageEnableOverlays' | translate}}</span>
+ </ion-toggle>
+ </label>
+
+
<!--
<div ng-if="$root.platformOS=='android'">
<label>
diff --git a/www/templates/montage.html b/www/templates/montage.html
index 73d3cb8d..1df4e255 100644
--- a/www/templates/montage.html
+++ b/www/templates/montage.html
@@ -5,9 +5,11 @@
&nbsp;
<button class="button button-icon button-clear ion-eye" ng-click="hideUnhide();">&nbsp;
</button>
- <button id="montage-move-2" class="button button-icon button-clear ion-chevron-down" ng-click="toggleSubMenuFunction();">&nbsp;
+ <button id="montage-move-2" class="button button-icon button-clear ion-chevron-down"
+ ng-click="toggleSubMenuFunction();">&nbsp;
</button>
- <button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge"
+ <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">
@@ -56,7 +58,8 @@
</a>
</li>
- <li ng-style="{'background-color': isCycleOn()?'rgba(69, 170, 242,0.7)':'rgba(108, 122, 137, 0.7)'}" ng-if="!isDragabillyOn">
+ <li ng-style="{'background-color': isCycleOn()?'rgba(69, 170, 242,0.7)':'rgba(108, 122, 137, 0.7)'}"
+ ng-if="!isDragabillyOn">
<a ng-click="toggleCycle()">
<i class="ion-android-bicycle"></i>:{{getCycleStatus()}}</a>
</li>
@@ -114,45 +117,93 @@
<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>
- <iframe width="200" height="100" src="https://news.google.com" frameborder="2" ></iframe>
- </figure>-->
+ <div class="row row-no-padding">
+ <div ng-class="monitor.Monitor.showSidebar?'col col-70 col-no-padding':'col col-no-padding'">
+ <figure role="group" class="{{dragBorder}}" ng-show="monitor.Monitor.listDisplay!='noshow'">
+ <!--<div ng-if="!isModalActive" >-->
+ <!--<div ng-if="$root.authSession!='undefined' && !isBackground() && !areImagesLoading">-->
- <figure class="{{dragBorder}}" ng-show="monitor.Monitor.listDisplay!='noshow'">
- <!--<div ng-if="!isModalActive" >-->
- <!--<div ng-if="$root.authSession!='undefined' && !isBackground() && !areImagesLoading">-->
+ <div class="montage-image">
+ <div ng-if="LoginData.enableMontageOverlays" class="montage-buttons">
+ <a ng-if="monitor.Monitor.lastEvent" class="button button-small button-assertive icon ion-ios-bell"
+ ng-click="eventButtonClicked(monitor, true)"></a>&nbsp;&nbsp;<a ng-if="monitor.Monitor.lastEvent"
+ class="button button-small button-balanced icon ion-checkmark"
+ ng-click="eventButtonClicked(monitor, false)"></a>
+ </div>
- <div ng-if="!minimal">
- <img class="{{monitor.Monitor.selectStyle}}" id="img-{{$index}}" image-spinner-src="{{constructStream(monitor)}}"
- ng-click="!isDragabillyOn?openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey,monitor):toggleSelectItem(monitor.Monitor.Id);"
- image-spinner-loader="lines" img-spinner-w="{{monitor.Monitor.Width}}" img-spinner-h="{{monitor.Monitor.Height}}" image-on-error="processImageError(monitor);" />
+ <a ng-if="LoginData.enableMontageOverlays && monitor.Monitor.Function !='None' && monitor.Monitor.Enabled != '0' && monitor.Monitor.Function != 'Monitor'"
+ ng-class="monitor.Monitor.showSidebar ? 'montage-sidebar-button button button-small button-light icon ion-chevron-left':'montage-sidebar-button button button-small button-light icon ion-chevron-right' "
+ ng-click="toggleSidebar(monitor)"></a>
- </div>
- <div ng-if="minimal">
- <img id="img-{{$index}}" image-spinner-src="{{constructStream(monitor)}}" ng-click="!isDragabillyOn?openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey,monitor):toggleSelectItem(monitor.Monitor.Id);"
- image-spinner-loader="lines" img-spinner-w="{{monitor.Monitor.Width}}" img-spinner-h="{{monitor.Monitor.Height}}" image-on-error="processImageError(monitor);"/>
+ <img class="{{monitor.Monitor.selectStyle}}" id="img-{{$index}}"
+ image-spinner-src="{{constructStream(monitor)}}"
+ ng-click="!isDragabillyOn?openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey,monitor):toggleSelectItem(monitor.Monitor.Id);"
+ image-spinner-loader="lines" img-spinner-w="{{monitor.Monitor.Width}}"
+ img-spinner-h="{{monitor.Monitor.Height}}" image-on-error="processImageError(monitor);" />
+ </div>
+
+ <figcaption id="slowpulse"
+ ng-class="monitor.Monitor.isAlarmed==true?'alarmed-figcaption animated infinite flash':'normal-figcaption'">
+ &nbsp;
+
+ <span ng-if="monitor.Monitor.isStamp && isDragabillyOn">
+ <i class="animated infinite flash ion-pin"></i>&nbsp;</span>
+ <i class="ion-ios-videocam"></i>&nbsp; {{monitor.Monitor.Name}}&nbsp;
+ <i ng-if="$root.runMode!='lowbw'" ng-style="{'color':monitor.Monitor.alarmState}"
+ class="ion-record"></i>&nbsp;
+
+ </figcaption>
+
+ </figure>
</div>
+ <div ng-if="monitor.Monitor.showSidebar" class="col col-30 col-no-padding "
+ style="background:rgba(10, 61, 98,0.3)">
+ <!--sidebar details-->
+ <img style="height: 100%; width: 100%; object-fit: contain"
+ image-spinner-src="{{constructEventThumbnail(monitor) }}" image-spinner-loader="lines"
+ img-spinner-w="{{monitor.Monitor.Width}}" img-spinner-h="{{monitor.Monitor.Height}}"
+ image-on-error="processImageError(monitor);" ng-click="showEvent(monitor)" />
- <figcaption id="slowpulse" ng-class="monitor.Monitor.isAlarmed==true?'alarmed-figcaption animated infinite flash':'normal-figcaption'">&nbsp;
+ </div>
+ </div>
+ <div ng-if="monitor.Monitor.showSidebar" class="montage-sidebar ">
- <span ng-if="monitor.Monitor.isStamp && isDragabillyOn">
- <i class="animated infinite flash ion-pin"></i>&nbsp;</span>
- <i class="ion-ios-videocam"></i>&nbsp; {{monitor.Monitor.Name}}&nbsp;
- <i ng-if="$root.runMode!='lowbw'" ng-style="{'color':monitor.Monitor.alarmState}" class="ion-record"></i>&nbsp;
+ <div class="row row-no-padding">
+ <i class="ion-social-buffer"></i>&nbsp;{{'kMontageEventStorage' | translate }}:
+ {{formatBytes(monitor.Monitor.TotalEventDiskSpace,1)}}
+ </div>
+ <div ng-if="!monitor.Monitor.lastEvent">
+ <div class="row">{{'kMontageEventCaughtUp' | translate}}</div>
+ </div>
+ <div ng-if="monitor.Monitor.lastEvent">
+ <div class="row row-no-padding">
+ <i class="ion-ios-bell"></i>&nbsp;{{monitor.Monitor.lastEvent.pagination.count}}
+ {{'kMontageEventUnseenCount' | translate}}
+ </div>
+ <div class="row row-no-padding">
+ <i class="ion-ios-calendar-outline"></i>&nbsp;{{'kMontageEventLatest' | translate}}:
+ {{humanizeTime(monitor.Monitor.lastEvent.events[0].Event.StartTime)}}<br />
+ </div>
+ <div class="row row-no-padding">
+ <i class="ion-clipboard"></i>&nbsp; {{monitor.Monitor.lastEvent.events[0].Event.Notes}}<br />
+ </div>
- </figcaption>
+ </div>
- </figure>
+ </div>
</div>
- </span>
- <!-- ngrepeat -->
+
+
+ </div>
+ </span>
+ <!-- ngrepeat -->
</div>
<ion-item style="background-color:#444444; color:#fff;border:none;" ng-show="!MontageMonitors.length">
{{'kNoMonitors' | translate}}
@@ -170,11 +221,15 @@
</button>
<!-- <button mfb-button icon="ion-refresh" label="{{'kRefresh' | translate}}" ng-click="resetSizes();">
</button>-->
+ <button mfb-button icon="ion-android-apps" label="{{'kReflow'| translate}}" ng-click="squeezeMonitors()">
+ </button>
<button mfb-button icon="ion-close" label="{{'kExitFullScreen'| translate}}" 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"
+ <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>