summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/css/style.css2
-rw-r--r--www/index.html2
-rw-r--r--www/js/DataModel.js190
-rw-r--r--www/js/DevOptionsCtrl.js14
-rw-r--r--www/js/EventCtrl.js283
-rw-r--r--www/js/EventModalCtrl.js88
-rw-r--r--www/js/EventServer.js38
-rw-r--r--www/js/EventsModalGraphCtrl.js2
-rw-r--r--www/js/LogCtrl.js193
-rw-r--r--www/js/LoginCtrl.js20
-rw-r--r--www/js/MomentCtrl.js21
-rw-r--r--www/js/MonitorCtrl.js136
-rw-r--r--www/js/MontageCtrl.js29
-rw-r--r--www/js/MontageHistoryCtrl.js15
-rw-r--r--www/js/NewsCtrl.js18
-rw-r--r--www/js/PortalLoginCtrl.js175
-rw-r--r--www/js/StateCtrl.js136
-rw-r--r--www/js/TimelineCtrl.js34
-rw-r--r--www/js/TimelineModalCtrl.js76
-rw-r--r--www/js/WizardCtrl.js22
-rwxr-xr-xwww/js/app.js194
-rw-r--r--www/lang/locale-ar.json1
-rw-r--r--www/lang/locale-ba.json1
-rw-r--r--www/lang/locale-de.json27
-rw-r--r--www/lang/locale-en.json34
-rw-r--r--www/lang/locale-es.json2
-rw-r--r--www/lang/locale-fr.json2
-rw-r--r--www/lang/locale-hu.json2
-rw-r--r--www/lang/locale-it.json1
-rwxr-xr-xwww/lang/locale-nl.json2
-rw-r--r--www/lang/locale-pl.json24
-rw-r--r--www/lang/locale-pt.json2
-rw-r--r--www/lang/locale-ru.json2
-rw-r--r--www/templates/events-modal.html5
-rw-r--r--www/templates/events-popover.html5
-rw-r--r--www/templates/events.html4
-rw-r--r--www/templates/log.html16
-rw-r--r--www/templates/moment.html2
-rw-r--r--www/templates/monitors-modal.html1
-rw-r--r--www/templates/monitors.html9
-rw-r--r--www/templates/state.html105
-rw-r--r--www/templates/timeline-modal.html2
42 files changed, 1148 insertions, 789 deletions
diff --git a/www/css/style.css b/www/css/style.css
index 2d8650d7..3c12a932 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -810,7 +810,7 @@ progress[aria-valuenow]:before {
}
.list .item.item-accordion {
- line-height: 200px;
+ line-height: 100%;
padding-top: 0;
padding-bottom: 0;
transition: 3s all linear;
diff --git a/www/index.html b/www/index.html
index 7aa77593..97db02aa 100644
--- a/www/index.html
+++ b/www/index.html
@@ -66,6 +66,8 @@
<script src="lib/ng-mfb/src/mfb-directive.js"></script>
<script src="lib/angular-touch/angular-touch.min.js"></script>
<script src="lib/holderjs/holder.min.js"></script>
+ <script src="lib/angular-cookies/angular-cookies.min.js"></script>
+
diff --git a/www/js/DataModel.js b/www/js/DataModel.js
index 6dbd5958..3e5f41c1 100644
--- a/www/js/DataModel.js
+++ b/www/js/DataModel.js
@@ -20,7 +20,7 @@ angular.module('zmApp.controllers')
DO NOT TOUCH zmAppVersion
It is changed by sync_version.sh
*/
- var zmAppVersion = "1.3.026";
+ var zmAppVersion = "1.3.029";
var isBackground = false;
var justResumed = false;
var timeSinceResumed = -1;
@@ -408,7 +408,7 @@ angular.module('zmApp.controllers')
var as = 'undefined';
- if (!mid && monitors.length > 0) {
+ if (!mid && monitors && monitors.length > 0) {
mid = monitors[0].Monitor.Id;
}
@@ -675,6 +675,67 @@ angular.module('zmApp.controllers')
debug(val);
},
+ evaluateTappedNotification: function() {
+
+ var state = "";
+ var stateParams1 = {};
+ var stateParams2 = {};
+
+ debug ("Inside evaluateNotifications");
+
+ if ($rootScope.tappedNotification == 2) { // url launch
+ debug("Came via app url launch with mid=" + $rootScope.tappedMid);
+ debug("Came via app url launch with eid=" + $rootScope.tappedEid);
+
+
+ if (parseInt($rootScope.tappedMid) > 0) {
+ debug("Going to live view ");
+ state = "app.monitors";
+
+ } else if (parseInt($rootScope.tappedEid) > 0) {
+ debug("Going to events with EID=" + $rootScope.tappedEid);
+ state = "app.events";
+ stateParams1 = {
+ "id": 0,
+ "playEvent": true
+ };
+ stateParams2 = {
+ reload: true
+ };
+
+ }
+
+
+ } // 2
+ else if ($rootScope.tappedNotification == 1) // push
+ {
+
+
+ debug("Came via push tap. onTapScreen=" + loginData.onTapScreen);
+ if (loginData.onTapScreen == $translate.instant('kTapMontage')) {
+ debug("Going to montage");
+ state = "app.montage";
+
+
+ } else if (loginData.onTapScreen == $translate.instant('kTapEvents')) {
+ debug("Going to events");
+ state = "app.events";
+ stateParams1 = {
+ "id": 0,
+ "playEvent": true
+ };
+
+ } else // we go to live
+ {
+ debug("Going to live view ");
+ state = "app.monitors";
+
+ }
+ }
+ $rootScope.tappedNotification = 0;
+ return [state, stateParams1, stateParams2];
+ },
+
setLastUpdateCheck: function (val) {
lastUpdateCheck = val;
localforage.setItem("lastUpdateCheck", lastUpdateCheck);
@@ -703,13 +764,7 @@ angular.module('zmApp.controllers')
// the ZM authors fix this and streamline the access of images
// from APIs, I don't have an option
- zmStateGo: function (state, p1, p2) {
- if ($rootScope.platformOS == 'desktop')
- $state.go(state, p1, p2);
- else
- $state.go(state, p1, p2);
- // $ionicNativeTransitions.stateGo(state, p1, p2);
- },
+
// used when an empty server profile is created
getDefaultLoginObject: function () {
@@ -912,8 +967,8 @@ angular.module('zmApp.controllers')
if (exists) {
log("A cloud configuration has been found");
window.cordova.plugin.cloudsettings.load(function (cloudData) {
- console.log("CLOUD DATA FOUND" + JSON.stringify(cloudData));
- debug("Cloud data retrieved is:" + JSON.stringify(cloudData));
+ //console.log("CLOUD DATA FOUND" + JSON.stringify(cloudData));
+ // debug("Cloud data retrieved is:" + JSON.stringify(cloudData));
if (cloudData && cloudData.defaultServerName && cloudData.serverGroupList) {
log("retrieved a valid cloud config with a defaultServerName of:" + cloudData.defaultServerName);
log("replacing local DB with cloud...");
@@ -1148,7 +1203,7 @@ angular.module('zmApp.controllers')
if (typeof loginData.disableSimulStreaming == 'undefined') {
- loginData.disableSimulStreaming = ($rootScope.platformOS == 'ios') ? true : false;
+ loginData.disableSimulStreaming = false;
//console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
}
@@ -1364,7 +1419,7 @@ angular.module('zmApp.controllers')
loginData.enableSlowLoading = false;
}
- log("SlowDelay is: " + loginData.enableSlowLoading);
+
if (typeof loginData.enableStrictSSL == 'undefined') {
@@ -1830,7 +1885,7 @@ angular.module('zmApp.controllers')
if (forceReload == 1 || configParams.ZM_EVENT_IMAGE_DIGITS == '-1') {
var apiurl = loginData.apiurl;
var myurl = apiurl + '/configs/viewByName/ZM_EVENT_IMAGE_DIGITS.json';
- debug("Config URL for digits is:" + myurl);
+ //debug("Config URL for digits is:" + myurl);
$http.get(myurl)
.then(function (data) {
data = data.data;
@@ -1848,8 +1903,8 @@ angular.module('zmApp.controllers')
return (d.promise);
});
} else {
- log("ZM_EVENT_IMAGE_DIGITS is already configured for " +
- configParams.ZM_EVENT_IMAGE_DIGITS);
+ // log("ZM_EVENT_IMAGE_DIGITS is already configured for " +
+ // configParams.ZM_EVENT_IMAGE_DIGITS);
d.resolve(configParams.ZM_EVENT_IMAGE_DIGITS);
return (d.promise);
}
@@ -1925,11 +1980,11 @@ angular.module('zmApp.controllers')
return $http.get(req + "&command=1")
.then(
function (s) {
- debug("pause success for ck:" + ck + " with:" + JSON.stringify(s));
+ // debug("pause success for ck:" + ck );
},
function (e) {
- debug("pause success for ck:" + ck + " with:" + JSON.stringify(e));
+ // debug("pause error for ck:" + ck + " with:" + JSON.stringify(e));
}
);
@@ -1949,11 +2004,11 @@ angular.module('zmApp.controllers')
return $http.get(req + "&command=2")
.then(
function (s) {
- debug("play success for ck:" + ck + " with:" + JSON.stringify(s));
+ // debug("play success for ck:" + ck + " with:" + JSON.stringify(s));
},
function (e) {
- debug("play success for ck:" + ck + " with:" + JSON.stringify(e));
+ // debug("play error for ck:" + ck + " with:" + JSON.stringify(e));
}
);
@@ -2026,6 +2081,29 @@ angular.module('zmApp.controllers')
},*/
+ getMultiServersCached: function () {
+ return multiservers;
+ },
+
+ // use non cached for daemon status
+ getMultiServers: function () {
+ return $http.get (loginData.apiurl+'/servers.json');
+
+ },
+
+ getMultiServer: function (id) {
+
+ var ndx = -1;
+ for (var i=0; i < multiservers.length; i++) {
+ if (multiservers[i].Server.Id == id) {
+ ndx = i;
+ break;
+ }
+ }
+ return ndx == -1 ? {}:multiservers[ndx];
+
+ },
+
regenConnKeys: function () {
debug("DataModel: Regenerating connkeys...");
@@ -2067,7 +2145,7 @@ angular.module('zmApp.controllers')
.then(function (data) {
// console.log("HTTP success got " + JSON.stringify(data.monitors));
data = data.data;
- monitors = data.monitors;
+ if (data.monitors) monitors = data.monitors;
if ($rootScope.authSession == 'undefined') {
@@ -2089,7 +2167,7 @@ angular.module('zmApp.controllers')
data = data.data;
// We found a server list API, so lets make sure
// we get the hostname as it will be needed for playback
- log("multi server list loaded" + JSON.stringify(data));
+ log("multi server list loaded:" + JSON.stringify(data));
multiservers = data.servers;
var multiserver_scheme = "http://";
@@ -2103,6 +2181,8 @@ angular.module('zmApp.controllers')
for (var i = 0; i < monitors.length; i++) {
// make them all show for now
+
+
monitors[i].Monitor.listDisplay = 'show';
monitors[i].Monitor.isAlarmed = false;
monitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
@@ -2123,15 +2203,16 @@ angular.module('zmApp.controllers')
multiservers[j].Server.Hostname = multiserver_scheme + multiservers[j].Server.Hostname;
}
- debug("Monitor " + monitors[i].Monitor.Id + " has a recording server hostname of " + multiservers[j].Server.Hostname);
+ // debug("Monitor " + monitors[i].Monitor.Id + " has a recording 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.
- var p = URI.parse(loginData.streamingurl);
- var s = URI.parse(multiservers[j].Server.Hostname);
+ var s = URI.parse(loginData.streamingurl);
+ var m = URI.parse(multiservers[j].Server.Hostname);
+ var p = URI.parse(loginData.url);
/* if (!p.port && !isNaN(p.path)) {
debug ("Portal: port path reversed?");
@@ -2148,31 +2229,33 @@ angular.module('zmApp.controllers')
}
*/
- debug("recording server parsed is " + JSON.stringify(s));
+ debug("recording server reported is " + JSON.stringify(m));
debug("portal parsed is " + JSON.stringify(p));
+ debug("streaming url parsed is " + JSON.stringify(s));
+ debug ("multi-port is:"+zmsPort);
var st = "";
var baseurl = "";
var streamingurl = "";
- st += (s.scheme ? s.scheme : p.scheme) + "://"; // server scheme overrides
+ st += (m.scheme ? m.scheme : p.scheme) + "://"; // server scheme overrides
// if server doesn't have a protocol, what we want is in path
- if (!s.host) {
- s.host = s.path;
- s.path = undefined;
+ if (!m.host) {
+ m.host = m.path;
+ m.path = undefined;
}
- st += s.host;
+ st += m.host;
//console.log ("STEP 1: ST="+st);
if (zmsPort <= 0 || loginData.disableSimulStreaming) {
- if (p.port || s.port) {
- st += (s.port ? ":" + s.port : ":" + p.port);
+ if (p.port || m.port) {
+ st += (m.port ? ":" + m.port : ":" + p.port);
streamingurl = st;
//console.log ("STEP 2 no ZMS: ST="+st);
@@ -2180,17 +2263,19 @@ angular.module('zmApp.controllers')
} else {
var sport = parseInt(zmsPort) + parseInt(monitors[i].Monitor.Id);
- streamingurl = st + ':' + sport;
+ st = st + ':' + sport;
- if (p.port || s.port)
- st += (s.port ? ":" + s.port : ":" + p.port);
+ if (p.port || m.port)
+ st += (m.port ? ":" + m.port : ":" + p.port);
//console.log ("STEP 2: ST="+st);
}
baseurl = st;
+
controlURL = st;
+ controlURL += (p.path ? p.path:'');
st += (s.path ? s.path : p.path);
streamingurl += (s.path ? s.path : p.path);
@@ -2203,6 +2288,9 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.streamingURL = st;
monitors[i].Monitor.baseURL = baseurl;
monitors[i].Monitor.controlURL = controlURL;
+
+
+ debug ("Storing baseurl="+baseurl+" streamingURL="+st+" recordingURL="+controlURL);
//console.log ("** Streaming="+st+" **base="+baseurl);
// starting 1.30 we have fid=xxx mode to return images
monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion, "1.30") == -1) ? "path" : "fid";
@@ -2213,11 +2301,13 @@ angular.module('zmApp.controllers')
} else {
//monitors[i].Monitor.listDisplay = 'show';
+ debug ("No servers matched, filling defaults...");
monitors[i].Monitor.isAlarmed = false;
monitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
monitors[i].Monitor.rndKey = (Math.floor((Math.random() * 999999) + 1)).toString();
var st2 = loginData.streamingurl;
+ controlURL = loginData.url;
if (zmsPort > 0 && !loginData.disableSimulStreaming) {
// we need to insert minport
@@ -2239,6 +2329,8 @@ angular.module('zmApp.controllers')
if (p3.path) controlURL += p3.path;
}
+ debug ("Storing streaming="+st2+" recording="+controlURL);
+
monitors[i].Monitor.streamingURL = st2;
monitors[i].Monitor.controlURL = controlURL;
//debug ("Streaming URL for Monitor " + monitors[i].Monitor.Id + " is " + monitors[i].Monitor.streamingURL );
@@ -2246,13 +2338,7 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.baseURL = loginData.url;
monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion, "1.30") == -1) ? "path" : "fid";
- // but now check if forced path
- if (loginData.forceImageModePath) {
- debug("Overriding, setting image mode to true as you have requested force enable");
- monitors[i].Monitor.imageMode = 'path';
- }
-
- // debug("API " + $rootScope.apiVersion + ": Monitor " + monitors[i].Monitor.Id + " will use " + monitors[i].Monitor.imageMode + " for direct image access");
+
}
}
// now get packery hide if applicable
@@ -2347,7 +2433,7 @@ angular.module('zmApp.controllers')
var succ;
try {
- console.log(textsucc);
+ //console.log(textsucc);
succ = JSON.parse(textsucc.data);
if (succ.data) succ = succ.data;
if (succ.config) {
@@ -2849,6 +2935,20 @@ angular.module('zmApp.controllers')
},
+
+ getRecordingURL: 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");
+ //console.log ("!!!"+monitors[i].Monitor.controlURL);
+ return monitors[i].Monitor.controlURL;
+ }
+
+ }
+ return "(Unknown)";
+ },
+
getBaseURL: function (id) {
var idnum = parseInt(id);
for (var i = 0; i < monitors.length; i++) {
@@ -2876,7 +2976,7 @@ angular.module('zmApp.controllers')
$rootScope.authSession = "undefined";
- console.log("CURRENT SERVER: " + loginData.currentServerVersion);
+ // console.log("CURRENT SERVER: " + loginData.currentServerVersion);
if (loginData.currentServerVersion && (versionCompare(loginData.currentServerVersion, zm.versionWithLoginAPI) != -1 || loginData.loginAPISupported)) {
diff --git a/www/js/DevOptionsCtrl.js b/www/js/DevOptionsCtrl.js
index dab4570b..1e194fab 100644
--- a/www/js/DevOptionsCtrl.js
+++ b/www/js/DevOptionsCtrl.js
@@ -10,6 +10,7 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope'
};
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -47,6 +48,19 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope'
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> DevOptionsCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
//console.log("**VIEW ** DevOptions Ctrl Entered");
$scope.loginData = NVRDataModel.getLogin();
console.log("DEV LOGS=" + $scope.loginData.enableLogs);
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index 90b615a2..66ff6463 100644
--- a/www/js/EventCtrl.js
+++ b/www/js/EventCtrl.js
@@ -32,7 +32,7 @@ angular.module('zmApp.controllers')
})
- .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', '$ionicListDelegate', 'ionPullUpFooterState', function ($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile, $ionicListDelegate, ionPullUpFooterState) {
+ .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', '$ionicListDelegate', 'ionPullUpFooterState', 'SecuredPopups', function ($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile, $ionicListDelegate, ionPullUpFooterState,SecuredPopups) {
// events in last 5 minutes
// TODO https://server/zm/api/events/consoleEvents/5%20minute.json
@@ -71,6 +71,9 @@ angular.module('zmApp.controllers')
// initial code
//---------------------------------------------------
+
+
+
//we come here is TZ is updated after the view loads
var tzu = $scope.$on('tz-updated', function () {
$scope.tzAbbr = NVRDataModel.getTimeZoneNow();
@@ -90,7 +93,7 @@ angular.module('zmApp.controllers')
//
window.addEventListener("resize", recomputeThumbSize, false);
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe");
+ // NVRDataModel.debug("enabling options swipe");
// see if we come from monitors, if so, don't filter events
if ($ionicHistory.backTitle() == 'Monitors') {
@@ -115,8 +118,8 @@ angular.module('zmApp.controllers')
footerExpand();
// now do event playback if asked
- if (parseInt($rootScope.tappedEid) > 0) {
- NVRDataModel.debug(" Trying ot live play " + $rootScope.tappedEid);
+ if (parseInt($rootScope.tappedEid) > 0 && $stateParams.playEvent == 'true') {
+ NVRDataModel.debug(" Trying to play event due to push:" + $rootScope.tappedEid);
playSpecificEvent($rootScope.tappedEid);
}
@@ -137,7 +140,7 @@ angular.module('zmApp.controllers')
};
$scope.event = event;
$scope.currentEvent = event;
- openModal(event);
+ openModal(event, 'enabled');
}
@@ -146,9 +149,9 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("EventCtrl: Deregistering resize listener");
window.removeEventListener("resize", recomputeThumbSize, false);
- NVRDataModel.debug("EventCtrl: Deregistering broadcast handles");
+ //NVRDataModel.debug("EventCtrl: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
- // broadcastHandles[i]();
+ // broadcastHandles[i]();
}
broadcastHandles = [];
});
@@ -158,6 +161,21 @@ angular.module('zmApp.controllers')
//console.log ("********* BEFORE ENTER");
//
+ $scope.mid = '';
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> EventCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $scope.mid = $rootScope.tappedMid;
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
$scope.modalData = {
"doRefresh": false
};
@@ -192,7 +210,7 @@ angular.module('zmApp.controllers')
if (NVRDataModel.getLogin().enableThumbs) {
- NVRDataModel.debug("--> thumbnail means increasing row size");
+ // NVRDataModel.debug("--> thumbnail means increasing row size");
eventsListScrubHeight = 370;
eventsListDetailsHeight = 330;
@@ -427,19 +445,18 @@ angular.module('zmApp.controllers')
myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime);
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
//console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+ // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.recordingURL);
myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId);
myevents[i].Event.ShowScrub = false;
myevents[i].Event.height = eventsListDetailsHeight;
// now construct base path
- myevents[i].Event.BasePath = computeBasePath(myevents[i]);
- myevents[i].Event.relativePath = computeRelativePath(myevents[i]);
+
// get thumbW/H
@@ -459,18 +476,11 @@ angular.module('zmApp.controllers')
// in multiserver BasePath is login url for frames
// http://login.url/index.php?view=frame&eid=19696772&fid=21
- // console.log ("COMPARING "+NVRDataModel.getLogin().url+ " TO " +myevents[i].Event.baseURL);
- if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) {
- //NVRDataModel.debug ("Multi server, changing base");
- myevents[i].Event.baseURL = NVRDataModel.getLogin().url;
-
- }
+ // console.log ("COMPARING "+NVRDataModel.getLogin().url+ " TO " +myevents[i].Event.recordingURL);
+
- if (myevents[i].Event.imageMode == 'path')
- //if (1)
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo;
- else
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
+
+ myevents[i].Event.videoPath = myevents[i].Event.recordingURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
// if (idfound)
if (idfound) {
@@ -525,7 +535,7 @@ angular.module('zmApp.controllers')
}
- function saveNow(imgsrc, r, f) {
+ function saveNow(imgsrc) {
var fname = "zmninja.jpg";
var fn = "cordova.plugins.photoLibrary.saveImage";
@@ -874,9 +884,11 @@ angular.module('zmApp.controllers')
});
};
- $scope.showImage = function (p, r, f, fid, e, imode, id, parray, ndx) {
+ $scope.showImage = function (p, f, fid, e, imode, id, parray, ndx) {
var img;
+// console.log ("P="+p+" F="+f+" E="+e+" imode="+imode+" id="+id+" parray="+JSON.stringify(parray)+" ndx="+ndx);
+
//console.log ("HERE");
$scope.kFrame = $translate.instant('kFrame');
$scope.kEvent = $translate.instant('kEvent');
@@ -903,20 +915,11 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("No index adjustment necessary as we are using all frames");
}
- // console.log ("Image Mode " + imode);
- // console.log ("parray : " + JSON.stringify(parray));
- // console.log ("index: " + ndx);
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
//$rootScope.zmPopup = $ionicPopup.alert({title: kFrame+':'+fid+'/'+kEvent+':'+e,template:img, cssClass:'popup80'});
@@ -944,7 +947,7 @@ angular.module('zmApp.controllers')
type: 'button-assertive button-small ion-camera',
onTap: function (e) {
e.preventDefault();
- saveNow($scope.imgsrc, r, parray[$scope.ndx].fname);
+ saveNow($scope.imgsrc);
}
},
@@ -969,17 +972,11 @@ angular.module('zmApp.controllers')
if (nndx == null) nndx = $scope.ndx;
$scope.ndx = nndx;
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
e.preventDefault();
@@ -1008,17 +1005,11 @@ angular.module('zmApp.controllers')
if (nndx == null) nndx = $scope.ndx;
$scope.ndx = nndx;
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
e.preventDefault();
@@ -1193,14 +1184,9 @@ angular.module('zmApp.controllers')
{
var fname;
//console.log ("PATH="+e.Event.imageMode);
- if (e.Event.imageMode == 'path')
- //if (1)
- {
- var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg";
- fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&path=" + e.Event.relativePath + rfp;
- } else {
- fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&fid=" + data.event.Frame[i].Id;
- }
+
+ fname = e.Event.recordingURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&fid=" + data.event.Frame[i].Id;
+
if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/ )
@@ -1814,11 +1800,25 @@ angular.module('zmApp.controllers')
// data for events ranges summaries using the consolveEvents facility of ZM
//--------------------------------------------------------------------------
+
+ $scope.footerToggle = function() {
+
+ if ($scope.footerState == ionPullUpFooterState.EXPANDED)
+ $scope.footerCollapse();
+ else
+ $scope.footerExpand();
+ };
+
$scope.footerExpand = function () {
+ $scope.footerState = ionPullUpFooterState.EXPANDED;
footerExpand();
};
+ $scope.footerCollapse = function() {
+ $scope.footerState = ionPullUpFooterState.MINIMIZED;
+ };
+
function footerExpand() {
//https://server/zm/api/events/consoleEvents/5%20minute.json
var ld = NVRDataModel.getLogin();
@@ -1826,12 +1826,12 @@ angular.module('zmApp.controllers')
var af = "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0);
var apiurl = ld.apiurl + "/events/consoleEvents/1 hour" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ // NVRDataModel.debug(JSON.stringify(data));
$scope.hours = [];
var p = data.results;
for (var key in data.results) {
@@ -1863,11 +1863,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 day" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ //NVRDataModel.debug(JSON.stringify(data));
$scope.days = [];
var p = data.results;
for (var key in data.results) {
@@ -1896,11 +1896,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 week" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ // NVRDataModel.debug(JSON.stringify(data));
$scope.weeks = [];
var p = data.results;
for (var key in data.results) {
@@ -1930,11 +1930,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 month" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ //NVRDataModel.debug(JSON.stringify(data));
$scope.months = [];
var p = data.results;
for (var key in data.results) {
@@ -2033,7 +2033,7 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("disabling options swipe");
} else {
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe");
+ //NVRDataModel.debug("enabling options swipe");
}
};
@@ -2075,11 +2075,11 @@ angular.module('zmApp.controllers')
if (event.Event.ShowScrub == false) {
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe due to toggle");
+ //NVRDataModel.debug("enabling options swipe due to toggle");
} else {
$ionicListDelegate.canSwipeItems(false);
$ionicListDelegate.closeOptionButtons();
- NVRDataModel.debug("disabling options swipe due to toggle");
+ // NVRDataModel.debug("disabling options swipe due to toggle");
}
@@ -2105,7 +2105,17 @@ angular.module('zmApp.controllers')
NVRDataModel.log("API for event details" + myurl);
$http.get(myurl)
.then(function (data) {
+
+
data = data.data;
+
+
+ // var ndata = data.replace(/<pre class="cake-error">/,'');
+
+ // console.log ("NDATA:"+ndata);
+ //<pre class="cake-error">
+
+
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
@@ -2143,7 +2153,7 @@ angular.module('zmApp.controllers')
},
function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
- NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
+ // NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
});
} // end of groupType == alarms
@@ -2200,20 +2210,7 @@ angular.module('zmApp.controllers')
$scope.slides = [];
var i;
- if (event.Event.imageMode == 'path') {
- NVRDataModel.debug("EventCtrl: found " + frames + " frames to scrub");
-
- for (i = 1; i <= frames; i++) {
- var fname = padToN(i, eventImageDigits) + "-capture.jpg";
-
- $scope.slides.push({
- id: i,
- img: fname
- });
-
- }
- } else // we need fids
- {
+
var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json";
NVRDataModel.log("API for event details" + myurl_frames);
$http.get(myurl_frames)
@@ -2243,7 +2240,7 @@ angular.module('zmApp.controllers')
NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]);
});
- }
+
// now get event details to show alarm frames
loginData = NVRDataModel.getLogin();
@@ -2254,10 +2251,8 @@ angular.module('zmApp.controllers')
event.Event.video = {};
var videoURL;
- //if (event.Event.imageMode == 'path')
-
- /* videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;*/
- videoURL = event.Event.baseURL + "/index.php?view=view_video&eid=" + event.Event.Id;
+
+ videoURL = event.Event.recordingURL + "/index.php?view=view_video&eid=" + event.Event.Id;
if ($rootScope.authSession != 'undefined') videoURL += $rootScope.authSession;
videoURL += NVRDataModel.insertBasicAuthToken();
@@ -2480,56 +2475,8 @@ angular.module('zmApp.controllers')
}
};
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeRelativePath(event) {
- var relativePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
- relativePath = event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return relativePath;
-
- }
-
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeBasePath(event) {
- var basePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
-
- basePath = event.Event.baseURL + "/events/" +
- event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return basePath;
- }
+
+
$scope.modalGraph = function () {
$ionicModal.fromTemplateUrl('templates/events-modalgraph.html', {
@@ -2745,11 +2692,13 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("No more - We have a total of " + maxEventsPage + " and are at page=" + currEventsPage);
console.log("*** At Page " + currEventsPage + " of " + maxEventsPage + ", not proceeding");
+ $ionicLoading.hide();
return;
}
currEventsPage++;
if (!enableLoadMore) {
+ $ionicLoading.hide();
moreEvents = false; // Don't ion-scroll till enableLoadMore is true;
$scope.$broadcast('scroll.infiniteScrollComplete');
@@ -2759,11 +2708,15 @@ angular.module('zmApp.controllers')
var loadingStr = "";
if ($scope.search.text != "") {
- var toastStr = $translate.instant('kToastSearchingPage') + currEventsPage;
+
+ var toastStr = $translate.instant('kPleaseWait') +'...'+ currEventsPage;
+ console.log ("SHOW " + toastStr );
$ionicLoading.show({
maxwidth: 100,
+ noBackdrop:true,
scope: $scope,
- template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >' + toastStr + '</button>'
+ template: toastStr,
+ // template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >' + toastStr + '</button>'
});
loadingStr = "none";
@@ -2806,15 +2759,13 @@ angular.module('zmApp.controllers')
// now construct base path
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
// console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+ // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.recordingURL);
myevents[i].Event.ShowScrub = false;
- myevents[i].Event.BasePath = computeBasePath(myevents[i]);
- myevents[i].Event.relativePath = computeRelativePath(myevents[i]);
myevents[i].Event.height = eventsListDetailsHeight;
// get thumbW/H
@@ -2837,11 +2788,8 @@ angular.module('zmApp.controllers')
}
- if (myevents[i].Event.imageMode == 'path')
- //if (1)
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo;
- else
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
+
+ myevents[i].Event.videoPath = myevents[i].Event.recordingURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
if (idfound) $scope.events.push(myevents[i]);
}
@@ -2854,6 +2802,7 @@ angular.module('zmApp.controllers')
function (error) {
// console.log("*** No More Events to Load, Stop Infinite Scroll ****");
moreEvents = false;
+ $ionicLoading.hide();
$scope.$broadcast('scroll.infiniteScrollComplete');
});
@@ -2866,7 +2815,7 @@ angular.module('zmApp.controllers')
function recomputeThumbSize() {
- NVRDataModel.debug("EventCtrl: recompute thumbnails");
+ // NVRDataModel.debug("EventCtrl: recompute thumbnails");
for (var i = 0; i < $scope.events.length; i++) {
var tempMon = NVRDataModel.getMonitorObject($scope.events[i].Event.MonitorId);
@@ -2930,7 +2879,7 @@ angular.module('zmApp.controllers')
$scope.constructThumbnail = function (event) {
var stream = "";
- stream = event.Event.baseURL +
+ stream = event.Event.recordingURL +
"/index.php?view=image&show=capture&fid=" +
(event.Event.MaxScoreFrameId ? event.Event.MaxScoreFrameId : "1&eid=" + event.Event.Id) +
"&width=" + event.Event.thumbWidth * 2 +
@@ -2945,14 +2894,10 @@ angular.module('zmApp.controllers')
$scope.constructScrubFrame = function (event, slide) {
var stream = "";
- if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL + "/index.php?view=image" +
- "&path=" + event.Event.relativePath + slide.img + "&height=380";
-
- } else if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL + "/index.php?view=image" +
+
+ stream = event.Event.recordingURL + "/index.php?view=image" +
"&fid=" + slide.id + $scope.outlineMotionParam;
- }
+
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
@@ -2964,22 +2909,14 @@ angular.module('zmApp.controllers')
$scope.constructAlarmFrame = function (event, alarm, motion) {
var stream = "";
- if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL +
+
+ stream = event.Event.recordingURL +
"/index.php?view=image&fid=" + alarm.id;
if (motion) stream += $scope.outlineMotionParam;
-
- } else if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL +
- "/index.php?view=image&path=" + event.Event.relativePath +
- motion ? alarm.aname : alarm.fname +
- "&height=380";
-
-
- }
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
+// console.log ("alarm:"+stream);
return stream;
};
diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js
index b992017c..11a7434a 100644
--- a/www/js/EventModalCtrl.js
+++ b/www/js/EventModalCtrl.js
@@ -261,7 +261,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("player reported a video error:" + JSON.stringify(event));
$rootScope.zmPopup = SecuredPopups.show('alert', {
title: $translate.instant('kError'),
- template: $rootScope.platformOS == 'desktop' ? $translate.instant('kVideoError') : $translate.instant('kVideoErrorMobile'),
+ template: $translate.instant('kVideoError'),
okText: $translate.instant('kButtonOk'),
cancelText: $translate.instant('kButtonCancel'),
});
@@ -349,7 +349,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
})
.then(function (resp) {
- NVRDataModel.debug("sendCmd response:" + JSON.stringify(resp));
+ // NVRDataModel.debug("sendCmd response:" + JSON.stringify(resp));
d.resolve(resp);
return (d.promise);
@@ -762,9 +762,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.mycarousel.index = 1;
- if ($scope.event.Event.imageMode == 'path') {
- url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.mycarousel.index].img;
- } else {
+
console.log("SLIDES " + JSON.stringify($scope.slides));
console.log("CAROUSEL " + JSON.stringify($scope.mycarousel));
@@ -772,7 +770,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand +
"&eid=" + $scope.eventId +
"&fid=" + $scope.slides[$scope.mycarousel.index - 1].id;
- }
+
if ($rootScope.authSession != 'undefined') {
url += $rootScope.authSession;
@@ -803,11 +801,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
onTap: function (e) {
if ($scope.slideIndex > 0) $scope.slideIndex--;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -831,11 +827,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
onTap: function (e) {
if ($scope.slideIndex < $scope.slideLastIndex) $scope.slideIndex++;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -860,11 +854,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
if (tempVar < 0) tempVar = 0;
$scope.slideIndex = tempVar;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -889,11 +881,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.slideIndex = tempVar;
if ($scope.slideIndex < $scope.slideLastIndex) $scope.slideIndex++;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -1074,14 +1064,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
if (currentStreamState == streamState.STOPPED || !$scope.eventId) {
stream = "";
} else if (currentStreamState == streamState.SNAPSHOT) {
- stream = $scope.loginData.url +
+ stream = currentEvent.Event.recordingURL +
"/index.php?view=image" +
"&fid=" + $scope.snapshotFrameId +
(!isGlobalFid ? "&eid=" + $scope.eventId : "") +
"&scale=" + $scope.singleImageQuality +
$rootScope.authSession;
} else if (currentStreamState == streamState.ACTIVE) {
- stream = $scope.loginData.streamingurl +
+ stream = currentEvent.Event.streamingURL +
"/nph-zms?source=event&mode=jpeg" +
"&event=" + $scope.eventId + "&frame=1" +
"&replay=" + $scope.currentStreamMode +
@@ -1092,9 +1082,11 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
//console.log ($scope.connKey );
- //console.log ("STREAM="+stream);
+
//console.log ("EID="+$scope.eventId);
if ($rootScope.basicAuthToken && stream) stream += "&basicauth=" + $rootScope.basicAuthToken;
+
+ //console.log ("STREAM="+stream);
return stream;
};
@@ -1141,6 +1133,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
isSnapShotEnabled = true;
currentStreamState = streamState.SNAPSHOT;
if (m.snapshotId) {
+
+ $scope.snapshotFrameId = m.snapshotId;
+
$scope.snapshotFrameId = m.snapshotId;
isGlobalFid = true;
} else {
@@ -1170,10 +1165,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.singleImageQuality = (NVRDataModel.getBandwidth() == "lowbw") ? zm.eventSingleImageQualityLowBW : ld.singleImageQuality;
$scope.blockSlider = false;
$scope.checkEventOn = false;
- //$scope.singleImageQuality = 100;
-
- //$scope.commandURL = $scope.currentEvent.Event.baseURL+"/index.php";
- // NVRDataModel.log (">>>>>>>>>>>>>>>>>>ZMS url command is " + $scope.commandURL);
+
currentEvent = $scope.currentEvent;
@@ -1311,7 +1303,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
- NVRDataModel.debug("Deregistering broadcast handles");
+ // NVRDataModel.debug("Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
// broadcastHandles[i]();
}
@@ -1924,7 +1916,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
function computeAlarmFrames(data) {
$scope.alarm_images = [];
tempAlarms = [];
- $scope.FrameArray = data.event.Frame;
+ $scope.FrameArray = [];
+
+ //console.log ("FRAME ARRAY: "+JSON.stringify(data));
+ if (data.event && data.event.Frame) $scope.FrameArray = data.event.Frame;
var ts = 0;
for (i = 0; i < data.event.Frame.length; i++) {
@@ -1953,14 +1948,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.constructFrame = function (fid) {
var frame = "";
- frame = currentEvent.Event.baseURL + "/index.php?view=image" +
+ frame = currentEvent.Event.recordingURL + "/index.php?view=image" +
"&eid=" + currentEvent.Event.Id +
"&fid=" + fid +
"&height=" + 200;
if ($rootScope.authSession != 'undefined') frame += $rootScope.authSession;
frame += NVRDataModel.insertBasicAuthToken();
- // console.log (frame);
+ //console.log ("alarm:"+frame);
return frame;
};
@@ -1983,8 +1978,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.log("*** Constructed API for detailed events: " + myurl);
$scope.humanizeTime = "...";
$scope.mName = "...";
- $scope.liveFeedMid = '';
-
+ $scope.liveFeedMid = $scope.mid;
$http.get(myurl)
.then(function (success) {
@@ -1992,8 +1986,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
var event = success.data.event;
currentEvent = event;
$scope.event = event;
+ $scope.currentEvent = event;
-
+ // console.log ("prepareModal DATA:"+JSON.stringify(success.data));
computeAlarmFrames(success.data);
$scope.eventWarning = '';
@@ -2008,8 +2003,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
event.Event.relativePath = computeRelativePath(event);
event.Event.streamingURL = NVRDataModel.getStreamingURL(event.Event.MonitorId);
- // event.Event.baseURL = NVRDataModel.getBaseURL (event.Event.MonitorId);
- event.Event.baseURL = loginData.url;
+
+ event.Event.recordingURL = NVRDataModel.getRecordingURL(event.Event.MonitorId);
event.Event.imageMode = NVRDataModel.getImageMode(event.Event.MonitorId);
//console.log (JSON.stringify( success));
@@ -2056,10 +2051,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
event.Event.video = {};
var videoURL;
- if ((event.Event.imageMode == 'path') || NVRDataModel.getLogin().forceImageModePath)
- 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;
+ videoURL = event.Event.recordingURL + "/index.php?view=view_video&eid=" + event.Event.Id;
if ($rootScope.authSession != 'undefined') videoURL += $rootScope.authSession;
if ($rootScope.basicAuthToken) videoURL = videoURL + "&basicauth=" + $rootScope.basicAuthToken;
@@ -2073,10 +2065,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("Video url passed to player is: " + videoURL);
- // console.log (">>>>>>>>>>>>>"+loginData.url+"-VS-"+event.Event.baseURL);
-
- //console.log("************** VIDEO IS " + videoURL);
-
+
$scope.videoObject = {
config: {
autoPlay: true,
@@ -2204,7 +2193,12 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
},
function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
- NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
+ // NVRDataModel.displayBanner('error', ['could not retrieve frame details']);
+ $scope.eventWarning = $translate.instant('kLiveView');
+ // if this happens we get to live feed
+ $scope.liveFeedMid = $scope.mid;
+
+
});
}
diff --git a/www/js/EventServer.js b/www/js/EventServer.js
index 1340b88d..5ef0a260 100644
--- a/www/js/EventServer.js
+++ b/www/js/EventServer.js
@@ -17,6 +17,7 @@ angular.module('zmApp.controllers')
var pushInited = false;
var isTimerOn = false;
var nativeWebSocketId = -1;
+ var iClosed = false;
@@ -31,7 +32,10 @@ angular.module('zmApp.controllers')
NVRDataModel.log("openHandshake: Websocket open, sending Auth");
sendMessage("auth", {
user: loginData.username,
- password: loginData.password
+ password: loginData.password,
+ monlist: loginData.eventServerMonitors,
+ intlist: loginData.eventServerInterval
+
});
@@ -63,6 +67,13 @@ angular.module('zmApp.controllers')
function handleClose(event) {
+
+ if (iClosed) {
+ NVRDataModel.debug ("App closed socket, not reconnecting");
+ iClosed = false;
+ return;
+ }
+
console.log("*********** WEBSOCKET CLOSE CALLED");
if (!NVRDataModel.getLogin().isUseEventServer) return;
@@ -99,6 +110,7 @@ angular.module('zmApp.controllers')
if (str.reason == 'APNSDISABLED') {
console.log("FORCE CLOSING");
+ iClosed=true;
ws.close();
NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000);
$rootScope.apnsToken = "";
@@ -319,7 +331,7 @@ angular.module('zmApp.controllers')
NVRDataModel.log("Clearing error/close cbk, disconnecting and deleting Event Server socket...");
- if ($rootScope.platforOS == 'desktop') {
+ if ($rootScope.platformOS == 'desktop') {
if (typeof ws === 'undefined') {
NVRDataModel.log("Event server socket is empty, nothing to disconnect");
return;
@@ -327,10 +339,12 @@ angular.module('zmApp.controllers')
ws.onmessage = null;
+ iClosed = true;
ws.close();
ws = undefined;
} else {
if (nativeWebSocketId != -1) //native;
+ iClosed = true;
CordovaWebsocketPlugin.wsClose(nativeWebSocketId, 1000, "Connection closed");
nativeWebSocketId = -1;
@@ -478,6 +492,7 @@ angular.module('zmApp.controllers')
// console.log("*********** MEDIA BLOG IS " + mediasrc);
media = $cordovaMedia.newMedia(mediasrc);
+
push.on('registration', function (data) {
pushInited = true;
NVRDataModel.debug("Push Notification registration ID received: " + JSON.stringify(data));
@@ -522,10 +537,6 @@ angular.module('zmApp.controllers')
}
-
-
- //console.log ("WUTPUT SENDING REG WITH "+monstring);
-
$rootScope.monstring = monstring;
$rootScope.intstring = intstring;
@@ -548,6 +559,7 @@ angular.module('zmApp.controllers')
push.on('notification', function (data) {
$ionicPlatform.ready(function () {
+ NVRDataModel.log("******* notification handler device ready");
NVRDataModel.debug("received push notification");
var ld = NVRDataModel.getLogin();
@@ -598,13 +610,13 @@ angular.module('zmApp.controllers')
$rootScope.tappedMid = mid;
$rootScope.tappedEid = eid;
- NVRDataModel.log("Push notification: Tapped Monitor taken as:" + $rootScope.tappedMid);
+ NVRDataModel.log("ES:Push notification: Tapped Monitor taken as:" + $rootScope.tappedMid);
if ($rootScope.platformOS == 'ios') {
- NVRDataModel.debug("iOS only: clearing background push");
+ NVRDataModel.debug("ES:iOS only: clearing background push");
push.finish(function () {
- NVRDataModel.debug("processing of push data is finished");
+ NVRDataModel.debug("ES:processing of push data is finished");
});
}
@@ -616,7 +628,13 @@ angular.module('zmApp.controllers')
}
// keep this emit not broadcast
// see Portal latch for reason
- $rootScope.$emit('process-push');
+
+ //https://stackoverflow.com/a/22651128/1361529
+ $timeout ( function () {
+ NVRDataModel.debug ("EventServer: broadcasting process-push");
+ $rootScope.$broadcast('process-push');
+ },100);
+
} else // app is foreground
{
diff --git a/www/js/EventsModalGraphCtrl.js b/www/js/EventsModalGraphCtrl.js
index b4e82ee2..0cfacb68 100644
--- a/www/js/EventsModalGraphCtrl.js
+++ b/www/js/EventsModalGraphCtrl.js
@@ -23,7 +23,7 @@ angular.module('zmApp.controllers').controller('EventsModalGraphCtrl', ['$scope'
$scope.$on('modal.removed', function (e, m) {
- NVRDataModel.debug("Deregistering broadcast handles");
+ //NVRDataModel.debug("Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
// broadcastHandles[i]();
}
diff --git a/www/js/LogCtrl.js b/www/js/LogCtrl.js
index 78a02992..01566750 100644
--- a/www/js/LogCtrl.js
+++ b/www/js/LogCtrl.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
/* global saveAs, cordova,StatusBar,angular,console,moment */
-angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', '$ionicHistory', '$state', '$interval', '$ionicLoading', '$translate', '$http', function ($scope, $rootScope, zm, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout, $ionicHistory, $state, $interval, $ionicLoading, $translate, $http) {
+angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', '$ionicHistory', '$state', '$interval', '$ionicLoading', '$translate', '$http', 'SecuredPopups', function ($scope, $rootScope, zm, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout, $ionicHistory, $state, $interval, $ionicLoading, $translate, $http, SecuredPopups) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -11,20 +11,9 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
// Controller main
//---------------------------------------------------------------
- var intervalLogUpdateHandle;
- document.addEventListener("pause", onPause, false);
- document.addEventListener("resume", onResume, false);
- function onPause() {
- NVRDataModel.debug("LogCtrl: pause called, killing log timer");
- // $interval.cancel(intervalLogUpdateHandle);
- }
- function onResume() {
- // NVRDataModel.debug("LogCtrl: resume called, starting log timer");
- loadLogs();
- }
$scope.flipLogs = function () {
if ($scope.logEntity == 'ZoneMinder')
@@ -76,115 +65,84 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
}
};
- //--------------------------------------------------------------------------
- // Make sure user knows information masking is best effort
- //--------------------------------------------------------------------------
-
- $scope.sendEmail = function (logstring) {
- logstring = logstring.substring(0, 20000);
- $ionicPopup.confirm({
- title: $translate.instant('kSensitiveTitle'),
- template: $rootScope.appName + ' ' + $translate.instant('kSensitiveBody'),
- okText: $translate.instant('kButtonOk'),
- cancelText: $translate.instant('kButtonCancel'),
- })
- .then(function (res) {
- if (res) {
-
- logstring = "zmNinja version:" + $scope.zmAppVersion +
- " (" + $rootScope.platformOS + ")\n" +
- "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion() + "\n" +
- logstring;
- sendEmailReally(logstring);
- }
- });
- };
+ // desktop download
+ $scope.downloadLogs = function () {
+ var body = "zmNinja version:" + $scope.zmAppVersion +
+ " (" + $rootScope.platformOS + ")\n" +
+ "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion()+"\n\n";
- //--------------------------------------------------------------------------
- // Convenience function to send logs via email
- //--------------------------------------------------------------------------
- function sendEmailReally(logstring) {
-
- //console.log ("LOGSTRING:"+logstring);
- if (window.cordova) {
-
- // do my best to replace sensitive information
- var loginData = NVRDataModel.getLogin();
-
- // We don't need this anymore as log and debug now strip passwords
- /*if (loginData.password !="")
- {
- var re1 = new RegExp(loginData.password, "g");
- logstring = logstring.replace(re1, "<deleted>");
- }*/
- // keep the protocol, helps to debug
- var urlNoProtocol = loginData.url.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re2 = new RegExp(urlNoProtocol, "g");
- // just replacing baseurl - that will take care of
- // masking api but may not be cgi
- logstring = logstring.replace(re2, "<server>");
- }
- urlNoProtocol = loginData.streamingurl.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re3 = new RegExp(urlNoProtocol, "g");
- logstring = logstring.replace(re3, "<server>");
- }
+ body = $translate.instant('kSensitiveBody') + '\n\n\n' + body;
+ var fname = $rootScope.appName + "-logs-" +
+ moment().format('MMM-DD-YY_HH-mm-ss') + ".txt";
- urlNoProtocol = loginData.eventServer.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re4 = new RegExp(urlNoProtocol, "g");
- logstring = logstring.replace(re4, "<server>");
- }
+ $fileLogger.checkFile()
+ .then(function (d) {
- //console.log ("NEW LOGSTRING:"+logstring);
- /* window.plugins.emailComposer.showEmailComposerWithCallback(callback, $rootScope.appName + ' logs', logstring, [zm.authoremail]);*/
-
-
- cordova.plugins.email.isAvailable(
- function (isAvailable) {
-
- if (isAvailable) {
- // body encapsulation requires br :^
- // see https://github.com/katzer/cordova-plugin-email-composer/issues/150
- logstring = logstring.split('\n').join('<br/>');
- cordova.plugins.email.open({
- to: zm.authoremail,
- subject: $rootScope.appName + ' logs',
- body: logstring
- });
- } else {
- // kEmailNotConfigured
- $rootScope.zmPopup = SecuredPopups.show('alert', {
- title: $translate.instant('kError'),
- template: $translate.instant('kEmailNotConfigured'),
- okText: $translate.instant('kButtonOk'),
- cancelText: $translate.instant('kButtonCancel'),
- });
+ body = body + window.localStorage[d.name];
+ var file = new Blob([body], {
+ type: 'text/plain'
+ });
+ var url = URL.createObjectURL(file);
+
+ $rootScope.zmPopup = SecuredPopups.show('alert', {
+ title: $translate.instant('kNote'),
+ template: $translate.instant('kTapDownloadLogs') + "<br/><br/><center><a href='" + url + "' class='button button-assertive icon ion-android-download' download='" + fname + "'>" + " " + $translate.instant('kDownload') + "</a></center>",
+ okText: $translate.instant('kDismiss'),
+ okType: 'button-stable'
+ },
+ function (e) {
+ NVRDataModel.debug("Error getting log file:" + JSON.stringify(e));
}
- });
+ );
+ });
- } else {
- // console.log("Using default email client to send data");
- var fname = $rootScope.appName + "-logs-" +
- moment().format('MMM-DD-YY_HH-mm-ss') + ".txt";
+ };
- var blob = new Blob([logstring], {
- type: "text/plain;charset=utf-8"
- });
- saveAs(blob, fname);
- }
+ // mobile - picks up applogs on the FS and sends an email with it
+
+ $scope.attachLogs = function () {
+ var body = "zmNinja version:" + $scope.zmAppVersion +
+ " (" + $rootScope.platformOS + ")<br/>" +
+ "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion() + "<br/>";
+ body = '<b>' + $translate.instant('kSensitiveBody') + '</b><br/><br/>' + body;
+
+ $fileLogger.checkFile()
+ .then(function (d) {
+ var fileWithPath = cordova.file.dataDirectory + d.name;
+ NVRDataModel.log("file location:" + fileWithPath);
+
+ var onSuccess = function (result) {
+ NVRDataModel.log("Share completed? " + result.completed);
+ NVRDataModel.log("Shared to app: " + result.app);
+ };
+
+ var onError = function (msg) {
+ NVRDataModel.log("Sharing failed with message: " + msg);
+ };
+
+ window.plugins.socialsharing.shareViaEmail(
+ body, //body
+ 'zmNinja Logs attached', // subject
+ [zm.authoremail], //to
+ null, // cc
+ null, //bcc
+ [fileWithPath],
+ onSuccess,
+ onError
+ );
- }
+ },
+ function (e) {
+ NVRDataModel.debug("Error attaching log file:" + JSON.stringify(e));
+ });
+
+
+ };
- function callback() {
- // console.log ("EMAIL SENT");
- NVRDataModel.debug("Email sent callback called");
- }
function loadZMlogs() {
var ld = NVRDataModel.getLogin();
@@ -257,6 +215,22 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on('$ionic.beforeEnter', function () {
+
+ $scope.$on("process-push", function () {
+ NVRDataModel.debug(">> LogCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:" + JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate: true,
+ disableBack: true
+ });
+ $state.go(s[0], s[1], s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
//console.log("**VIEW ** Log Ctrl Entered");
@@ -280,6 +254,7 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
};
$scope.zmAppVersion = NVRDataModel.getAppVersion();
+ $scope.zmVersion = NVRDataModel.getCurrentServerVersion();
/* intervalLogUpdateHandle = $interval(function ()
{
diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js
index ca6b9df9..09a48ac2 100644
--- a/www/js/LoginCtrl.js
+++ b/www/js/LoginCtrl.js
@@ -33,6 +33,7 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
}
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -233,6 +234,20 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
$scope.$on('$ionicView.beforeEnter', function () {
+
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> LoginCtrl: push handler. Not processing push, because you might be here due to login failure");
+ /*var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);*/
+ });
+
+
oldLoginData = '';
$scope.loginData = NVRDataModel.getLogin();
@@ -262,11 +277,6 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
NVRDataModel.log("Creating new login entry for wizard");
$scope.loginData = angular.copy(NVRDataModel.getDefaultLoginObject());
- // default object has this as false
- if ($rootScope.platformOS == 'ios') {
- $scope.loginData.disableSimulStreaming = true;
- }
-
$scope.loginData.serverName = $rootScope.wizard.serverName;
$scope.loginData.url = $rootScope.wizard.loginURL;
$scope.loginData.apiurl = $rootScope.wizard.apiURL;
diff --git a/www/js/MomentCtrl.js b/www/js/MomentCtrl.js
index 6a56158e..44f653df 100644
--- a/www/js/MomentCtrl.js
+++ b/www/js/MomentCtrl.js
@@ -23,6 +23,8 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$ionicSideMenuDelegate.toggleLeft();
};
+
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -134,9 +136,8 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
data.events[i].Event.hide = false;
data.events[i].Event.icon = "ion-code-working";
- //data.events[i].Event.baseURL = NVRDataModel.getBaseURL(data.events[i].Event.MonitorId);
- // huh? why did I need the above? eventCtrl reverses it with below...
- data.events[i].Event.baseURL = NVRDataModel.getLogin().url;
+
+ data.events[i].Event.recordingURL = NVRDataModel.getLogin().url;
data.events[i].Event.monitorName = NVRDataModel.getMonitorName(data.events[i].Event.MonitorId);
data.events[i].Event.dateObject = new Date(data.events[i].Event.StartTime);
@@ -267,7 +268,7 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$scope.constructFrame = function (moment) {
var stream = "";
// console.log ($scope.isMaxScoreFramePresent);
- stream = moment.Event.baseURL + "/index.php?view=image" +
+ stream = moment.Event.recordingURL + "/index.php?view=image" +
($scope.isMaxScoreFramePresent ? "&fid=" + moment.Event.MaxScoreFrameId : "&eid=" + moment.Event.Id + "&fid=1") +
"&width=" + moment.Event.thumbWidth * 2 +
"&height=" + moment.Event.thumbHeight * 2;
@@ -834,6 +835,18 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MomentCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
//console.log ("HERE>>>>>>>>>>>>>>>>>>>>>>>>>>>");
monitors = angular.copy(message); // don't mess up the main monitors list
diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js
index 9edb1e36..7241db53 100644
--- a/www/js/MonitorCtrl.js
+++ b/www/js/MonitorCtrl.js
@@ -6,18 +6,12 @@
// refer to comments in EventCtrl for the modal stuff. They are almost the same
angular.module('zmApp.controllers')
- .controller('zmApp.MonitorCtrl', ['$ionicPopup', 'zm', '$scope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', '$rootScope', '$timeout', '$ionicHistory', '$ionicPlatform', '$translate', '$q',
- function ($ionicPopup, zm, $scope, NVRDataModel, message, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout, $ionicHistory, $ionicPlatform, $translate, $q) {
+ .controller('zmApp.MonitorCtrl', ['$ionicPopup', 'zm', '$scope', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', '$rootScope', '$timeout', '$ionicHistory', '$ionicPlatform', '$translate', '$q',
+ function ($ionicPopup, zm, $scope, NVRDataModel, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout, $ionicHistory, $ionicPlatform, $translate, $q) {
- //-----------------------------------------------------------------------
- // Controller Main
- //-----------------------------------------------------------------------
-
- // var isModalOpen = false;
-
- // console.log("***EVENTS: Waiting for Monitors to load before I proceed");
var loginData;
+ $scope.monitorLoadStatus = "...";
// --------------------------------------------------------
// Handling of back button in case modal is open should
@@ -48,6 +42,8 @@ angular.module('zmApp.controllers')
$ionicSideMenuDelegate.toggleLeft();
};
+
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -251,6 +247,20 @@ angular.module('zmApp.controllers')
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+ $scope.$on('$ionicView.beforeEnter', function() {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MonitorCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** Monitor Ctrl Entered");
NVRDataModel.setAwake(false);
@@ -260,24 +270,15 @@ angular.module('zmApp.controllers')
$scope.$on('$ionicView.afterEnter', function () {
// console.log("**VIEW ** Monitor Ctrl Entered");
+
+ NVRDataModel.debug ("Monitor Control afterEnter");
$scope.monitors = [];
- $scope.monitors = message;
+ $scope.monitorLoadStatus = $translate.instant ('kPleaseWait')+'...';
+
//console.log (">>>>>>>>>>>> MONITOR CTRL " + JSON.stringify($scope.monitors));
- if ($scope.monitors.length == 0) {
- $rootScope.zmPopup = $ionicPopup.alert({
- title: $translate.instant('kNoMonitors'),
- template: $translate.instant('kPleaseCheckCredentials')
- });
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
- $state.go("app.login", {
- "wizard": false
- });
- return;
- }
+
loginData = NVRDataModel.getLogin();
monitorStateCheck();
@@ -292,15 +293,21 @@ angular.module('zmApp.controllers')
var tm = $rootScope.tappedMid;
$rootScope.tappedMid = 0;
var monitem;
- for (var m = 0; m < $scope.monitors.length; m++) {
- if ($scope.monitors[m].Monitor.Id == tm) {
- monitem = $scope.monitors[m];
- break;
- }
- }
+ NVRDataModel.getMonitors(0)
+ .then ( function (data) {
+ $scope.monitors = data;
+ for (var m = 0; m < $scope.monitors.length; m++) {
+ if ($scope.monitors[m].Monitor.Id == tm) {
+ monitem = $scope.monitors[m];
+ break;
+ }
+ }
+ openModal(monitem.Monitor.Id, monitem.Monitor.Controllable, monitem.Monitor.ControlId, monitem.Monitor.connKey, monitem);
+ });
+
- openModal(monitem.Monitor.Id, monitem.Monitor.Controllable, monitem.Monitor.ControlId, monitem.Monitor.connKey, monitem);
+
}
});
@@ -399,8 +406,67 @@ angular.module('zmApp.controllers')
//-----------------------------------------------------------------------
function monitorStateCheck() {
+
+ // console.log ("Checking monitors");
+ var ld = NVRDataModel.getLogin();
+ // force get for latest status of monitors if av.
+ NVRDataModel.getMonitors(1)
+ .then (function (data) {
+
+ $scope.monitors = data;
+
+ if (!$scope.monitors.length) {
+ $scope.monitorLoadStatus = $translate.instant ('kNoMonitors');
+ }
+
+ if (!$scope.monitors[0].Monitor_Status ) {
+ NVRDataModel.debug ("no Monitor_Status found reverting to daemonCheck...");
+ forceDaemonCheck();
+ }
+ else {
+ NVRDataModel.debug ("reporting status of monitors from multi-server API");
+ processMonitorStatus();
+ }
+
+ },
+ function (err) {
+ NVRDataModel.debug ("Monitor fetch error, reverting to daemonCheck...");
+ $scope.monitorLoadStatus = $translate.instant ('kNoMonitors');
+ forceDaemonCheck();
+ });
+
+ }
+
+ function processMonitorStatus () {
+
+ //array('Unknown','NotRunning','Running','NoSignal','Signal'),
+
+
+ // console.log (JSON.stringify($scope.monitors));
+ for (var j=0; j < $scope.monitors.length; j++) {
+
+ if ($scope.monitors[j].Monitor_Status.Status == 'Connected') {
+ $scope.monitors[j].Monitor.isRunning = "true";
+ $scope.monitors[j].Monitor.color = zm.monitorRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
+ $scope.monitors[j].Monitor.isRunningText = $scope.monitors[j].Monitor_Status.Status;
+ }
+ else {
+ $scope.monitors[j].Monitor.isRunning = "false";
+ $scope.monitors[j].Monitor.color = zm.monitorNotRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-close-circled";
+ $scope.monitors[j].Monitor.isRunningText = $scope.monitors[j].Monitor_Status.Status;
+ }
+
+ }
+
+ }
+
+ function forceDaemonCheck() {
var apiMonCheck;
+ $scope.loginData = NVRDataModel.getLogin();
+
// The status is provided by zmdc.pl
// "not running", "pending", "running since", "Unable to connect"
var i;
@@ -409,13 +475,10 @@ angular.module('zmApp.controllers')
$scope.monitors[j].Monitor.isRunningText = "...";
$scope.monitors[j].Monitor.isRunning = "...";
$scope.monitors[j].Monitor.color = zm.monitorCheckingColor;
- $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
- apiMonCheck = loginData.apiurl + "/monitors/daemonStatus/id:" + $scope.monitors[j].Monitor.Id + "/daemon:zmc.json";
-
- //apiMonCheck = apiMonCheck.replace(loginData.url, $scope.monitors[j].Monitor.baseURL);
-
- // in multiserver replace apiurl with baseurl
+ $scope.monitors[j].Monitor.char = "ion-help-circled";
+ apiMonCheck = $scope.loginData.apiurl + "/monitors/daemonStatus/id:" + $scope.monitors[j].Monitor.Id + "/daemon:zmc.json";
+
NVRDataModel.debug("MonitorCtrl:monitorStateCheck: " + apiMonCheck);
//console.log("**** ZMC CHECK " + apiMonCheck);
$http.get(apiMonCheck)
@@ -432,6 +495,7 @@ angular.module('zmApp.controllers')
} else if (data.statustext.indexOf("running since") > -1) {
$scope.monitors[j].Monitor.isRunning = "true";
$scope.monitors[j].Monitor.color = zm.monitorRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
} else if (data.statustext.indexOf("Unable to connect") > -1) {
$scope.monitors[j].Monitor.isRunning = "false";
$scope.monitors[j].Monitor.color = zm.monitorNotRunningColor;
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index 161a1025..0e3d34d0 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -47,6 +47,10 @@ angular.module('zmApp.controllers')
var broadcastHandles = [];
+
+
+
+
var as = $scope.$on("auth-success", function () {
/* var tnow = new Date();
@@ -218,13 +222,6 @@ angular.module('zmApp.controllers')
"view": 'app.montage'
});
-
- /* $state.transitionTo($state.current, $stateParams, {
- reload: true,
- inherit: false,
- notify: true
- });*/
-
});
@@ -1823,6 +1820,19 @@ angular.module('zmApp.controllers')
// minimal has to be beforeEnter or header won't hide
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MontageCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
timeInMontage = new Date();
broadcastHandles = [];
randToAvoidCacheMem = new Date().getTime();
@@ -2019,6 +2029,11 @@ angular.module('zmApp.controllers')
currentStreamState = streamState.STOPPED;
viewCleanup();
viewCleaned = true;
+ //NVRDataModel.debug("Deregistering broadcast handles");
+ for (var i = 0; i < broadcastHandles.length; i++) {
+ broadcastHandles[i]();
+ }
+ broadcastHandles = [];
});
diff --git a/www/js/MontageHistoryCtrl.js b/www/js/MontageHistoryCtrl.js
index e2782387..0373adcd 100644
--- a/www/js/MontageHistoryCtrl.js
+++ b/www/js/MontageHistoryCtrl.js
@@ -11,6 +11,9 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc
var viewCleaned = false;
$scope.isScreenReady = false;
+
+
+
//--------------------------------------------------------------------------------------
// Handles bandwidth change, if required
//
@@ -1064,6 +1067,18 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc
}
}
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MontageHistoryCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
// This rand is really used to reload the monitor image in img-src so it is not cached
// I am making sure the image in montage view is always fresh
// I don't think I am using this anymore FIXME: check and delete if needed
diff --git a/www/js/NewsCtrl.js b/www/js/NewsCtrl.js
index ba45fb0e..180f70d7 100644
--- a/www/js/NewsCtrl.js
+++ b/www/js/NewsCtrl.js
@@ -27,6 +27,8 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro
}
};
+
+
//-------------------------------------------------------------------------
// Lets make sure we set screen dim properly as we enter
// The problem is we enter other states before we leave previous states
@@ -34,6 +36,22 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on ('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> NewsCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** News Ctrl Entered");
NVRDataModel.setAwake(false);
diff --git a/www/js/PortalLoginCtrl.js b/www/js/PortalLoginCtrl.js
index 7fb4cc50..22bb46f8 100644
--- a/www/js/PortalLoginCtrl.js
+++ b/www/js/PortalLoginCtrl.js
@@ -5,33 +5,74 @@
/* global vis,cordova,StatusBar,angular,console,moment */
angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionicPlatform', '$scope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', '$q', '$state', '$ionicLoading', '$ionicPopover', '$ionicScrollDelegate', '$ionicModal', '$timeout', 'zmAutoLogin', '$ionicHistory', 'EventServer', '$translate', '$ionicPopup', function ($ionicPlatform, $scope, zm, NVRDataModel, $ionicSideMenuDelegate, $rootScope, $http, $q, $state, $ionicLoading, $ionicPopover, $ionicScrollDelegate, $ionicModal, $timeout, zmAutoLogin, $ionicHistory, EventServer, $translate, $ionicPopup) {
- var processPush = false;
+
var broadcastHandles = [];
+ var processPush = false;
+ var alreadyTransitioned = false;
$scope.$on('$ionicView.beforeLeave', function () {
- //processPush = false;
- // NVRDataModel.debug ("BeforeEnter in Portal: setting ProcessPush to false");
+ processPush = false;
+
});
+
+
$scope.$on('$ionicView.beforeLeave', function () {
- NVRDataModel.debug("Portal: Deregistering broadcast handles");
+ //NVRDataModel.debug("Portal: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
//broadcastHandles[i]();
}
broadcastHandles = [];
});
+
+ $scope.$on('$ionicView.beforeEnter',
+ function () {
+ alreadyTransitioned = false;
+
+ });
+
+
$scope.$on('$ionicView.enter',
function () {
+
+
+ $scope.$on ( "process-push", function () {
+ processPush = true;
+
+ if (!alreadyTransitioned) {
+ NVRDataModel.debug (">> PortalLogin: push handler, marking to resolve later");
+
+ }
+ else {
+ NVRDataModel.debug (">> PortalLoginCtrl: push handler");
+ processPush = false;
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ return;
+
+ }
+
+ });
+
+
NVRDataModel.setJustResumed(false);
NVRDataModel.debug("Inside Portal login Enter handler");
loginData = NVRDataModel.getLogin();
$ionicHistory.nextViewOptions({
+ disableAnimate:true,
disableBack: true
});
+
+
$scope.pindata = {};
if ($ionicSideMenuDelegate.isOpen()) {
$ionicSideMenuDelegate.toggleLeft();
@@ -153,6 +194,7 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
disableAnimate: true,
disableBack: true
});
+
$state.go("app.login", {
"wizard": false
});
@@ -244,6 +286,8 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
//NVRDataModel.debug ("logging state transition");
NVRDataModel.debug("2nd Auth: Transitioning state to: " +
statetoGo + " with param " + JSON.stringify($rootScope.lastStateParam));
+
+ alreadyTransitioned = true;
$state.go(statetoGo, $rootScope.lastStateParam);
return;
@@ -266,100 +310,8 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
}
- //this needs to be rootScope so it lives even when we are out of view
- var pp = $rootScope.$on("process-push", function () {
- NVRDataModel.debug("*** PROCESS PUSH HANDLER CALLED INSIDE PORTAL LOGIN, setting ProcessPush to true");
- processPush = true;
- evaluateTappedNotification();
-
-
- });
- broadcastHandles.push(pp);
-
- function evaluateTappedNotification() {
- var ld = NVRDataModel.getLogin();
-
- // give enough time for state conflicts to work out
- // that way PortalLogin doesn't override this
- // and I thought I was eliminating hacks....
- $timeout(function () {
- processPush = false;
- }, 1000);
-
-
- if ($rootScope.tappedNotification == 2) { // url launch
- NVRDataModel.debug("Came via app url launch with mid=" + $rootScope.tappedMid);
- NVRDataModel.debug("Came via app url launch with eid=" + $rootScope.tappedEid);
- $rootScope.tappedNotification = 0;
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
-
- if (parseInt($rootScope.tappedMid) > 0) {
- NVRDataModel.debug("Going to live view ");
- $state.go("app.monitors");
- return;
-
- } else if (parseInt($rootScope.tappedEid) > 0) {
- NVRDataModel.debug("Going to events with EID=" + $rootScope.tappedEid);
- $state.go("app.events", {
- //"id": $rootScope.tappedEid,
- "id": 0,
- "playEvent": true
- }, {
- reload: true
- });
- return;
- }
- // go with monitor first, then event - just because I feel like ;)
-
-
- } else if ($rootScope.tappedNotification == 1) // push
- {
-
-
- NVRDataModel.log("Came via push tap. onTapScreen=" + ld.onTapScreen);
- $rootScope.pushOverride = true;
- //console.log ("***** NOTIFICATION TAPPED ");
- $rootScope.tappedNotification = 0;
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
-
- if (ld.onTapScreen == $translate.instant('kTapMontage')) {
- NVRDataModel.debug("Going to montage");
- $state.go("app.montage");
-
- return;
- } else if (ld.onTapScreen == $translate.instant('kTapEvents')) {
- NVRDataModel.debug("Going to events");
- $state.go("app.events", {
- "id": 0,
- "playEvent": false
- });
- return;
- } else // we go to live
- {
- NVRDataModel.debug("Going to live view ");
- $state.go("app.monitors");
- return;
- }
- } else {
- /* NVRDataModel.debug ("Inside evaluateTapped, but no tap occured.");
- NVRDataModel.debug ("This can happen if timing mismatch and holy foo happens");
- $state.go("app.montage",
- {},
- {
- reload: true
- });
- return;*/
-
- }
-
- }
-
-
+ //broadcastHandles.push(pp);
function unlock(idVerified) {
/*
@@ -438,7 +390,7 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
NVRDataModel.zmPrivacyProcessed()
.then(function (val) {
- console.log(">>>>>>>>>>>>>>>>>>> PRIVACY PROCEESSED:" + val);
+ // console.log(">>>>>>>>>>>>>>>>>>> PRIVACY PROCESSED:" + val);
if (!val) {
var alertPopup = $ionicPopup.alert({
title: $translate.instant('kNote'),
@@ -456,21 +408,34 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
// if push happens AFTER this, then while going to
// lastState, it will interrupt and go to onTap
// (I HOPE...)
- if (!processPush) {
+
//console.log ("NOTIFICATION TAPPED INSIDE CHECK IS "+$rootScope.tappedNotification);
var statetoGo = $rootScope.lastState ? $rootScope.lastState : 'app.montage';
// NVRDataModel.debug("logging state transition");
- NVRDataModel.debug("Transitioning state to: " +
+
+ if (!processPush) {
+ alreadyTransitioned = true;
+ NVRDataModel.debug("Transitioning state to: " +
statetoGo + " with param " + JSON.stringify($rootScope.lastStateParam));
$state.go(statetoGo, $rootScope.lastStateParam);
return;
+ }
+ else {
+ NVRDataModel.debug ("Deferred handling of push:");
+ processPush = false;
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ return;
+ }
+
- }
- // else
- // evaluateTappedNotification();
-
-
+
},
function (error) { // API Error
NVRDataModel.log("API Error handler: going to login getAPI returned error: " + JSON.stringify(error));
diff --git a/www/js/StateCtrl.js b/www/js/StateCtrl.js
index 62bffb81..34255287 100644
--- a/www/js/StateCtrl.js
+++ b/www/js/StateCtrl.js
@@ -26,27 +26,59 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
var apiRun = loginData.apiurl + "/host/daemonCheck.json";
var apiLoad = loginData.apiurl + "/host/getLoad.json";
- var apiDisk = loginData.apiurl + "/host/getDiskPercent.json";
+ var apiStorage = loginData.apiurl + "/storage.json";
+ var apiServer = loginData.apiurl + "/servers.json";
var apiCurrentState = loginData.apiurl + "/States.json";
var apiExec = loginData.apiurl + "/states/change/";
var inProgress = 0; // prevents user from another op if one is in progress
getRunStatus();
+ getLoadStatus();
+ getCurrentState();
+ getStorageStatus();
+ getServerStatus();
+
+
+// credit https://stackoverflow.com/a/14919494/1361529
+ $scope.humanFileSize = function(bytes, si) {
+ var thresh = si ? 1000 : 1024;
+ bytes = parseFloat(bytes);
+ if (isNaN(bytes)) bytes=0;
+ if(Math.abs(bytes) < thresh) {
+ return bytes + ' B';
+ }
+ var units = si? ['kB','MB','GB','TB','PB','EB','ZB','YB']:['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
+ var u = -1;
+ do {
+ bytes /= thresh;
+ ++u;
+ } while(Math.abs(bytes) >= thresh && u < units.length - 1);
+ return bytes.toFixed(1)+' '+units[u];
+};
+
+$scope.matchServer = function (id) {
+ var str = id;
+ var name = "";
+ for (var i=0; i< $scope.servers.length; i++) {
+ if ($scope.servers[i].Server.Id == id) {
+ name = $scope.servers[i].Server.Name;
+ break;
+ }
+ }
+ if (name) {
+ str = name + " ("+id+")";
+ }
+ return str;
+};
- // Let's stagger this by 500ms each to see if Chrome lets these through
- // This may also help if your Apache is not configured to let multiple connections through
-
- $timeout(function () {
- NVRDataModel.debug("invoking LoadStatus...");
- getLoadStatus();
- }, 2000);
-
- $timeout(function () {
- NVRDataModel.debug("invoking CurrentState...");
- getCurrentState();
- }, 4000);
+$scope.toggleStorage = function() {
+ $scope.showStorage = !$scope.showStorage;
+};
+$scope.toggleServer = function() {
+ $scope.showServer = !$scope.showServer;
+};
/*
$timeout(function () {
NVRDataModel.debug("invoking DiskStatus...");
@@ -60,6 +92,25 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on ('$ionicView.beforeEnter', function () {
+
+ $scope.showStorage = true;
+ $scope.showServer = true;
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> StateCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** Montage Ctrl Entered");
NVRDataModel.setAwake(false);
@@ -175,22 +226,46 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
}
//----------------------------------------------------------------------
- // returns disk space in gigs taken up by events
+ // returns Storage data
//----------------------------------------------------------------------
- function getDiskStatus() {
- NVRDataModel.debug("StateCtrl/getDiskStatus: " + apiDisk);
- $http.get(apiDisk)
+ function getStorageStatus() {
+
+ $scope.storage = [];
+ NVRDataModel.debug("StorageStatus: " + apiStorage);
+ $http.get(apiStorage)
.then(
function (success) {
- NVRDataModel.debug("StateCtrl/getDiskStatus: success");
- NVRDataModel.debug("Disk results: " + JSON.stringify(success));
- var obj = success.data.usage;
- if (obj.Total.space != undefined) {
- $scope.zmDisk = parseFloat(obj.Total.space).toFixed(1).toString() + "G";
- } else {
- $scope.zmDisk = "unknown";
- NVRDataModel.log("Error retrieving disk space, API returned null for obj.Total.space");
+
+ $scope.storage = success.data.storage;
+ //console.log (JSON.stringify($scope.storage));
+
+ },
+ function (error) {
+ $scope.zmDisk = "unknown";
+ // console.log("ERROR:" + JSON.stringify(error));
+ NVRDataModel.log("Error retrieving DiskStatus: " + JSON.stringify(error), "error");
+ }
+ );
+ }
+
+
+ //----------------------------------------------------------------------
+ // returns Storage data
+ //----------------------------------------------------------------------
+ function getServerStatus() {
+
+ $scope.servers = [];
+ NVRDataModel.debug("ServerStatus: " + apiStorage);
+ $http.get(apiServer)
+ .then(
+ function (success) {
+
+ $scope.servers = success.data.servers;
+ if ($scope.servers.length > 0) {
+ $scope.zmRun =$translate.instant('kStateMultiServer');
+ $scope.color = 'grey';
}
+ // console.log (JSON.stringify($scope.storage));
},
function (error) {
@@ -205,6 +280,10 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
// returns ZM running status
//----------------------------------------------------------------------
function getRunStatus() {
+
+
+
+
NVRDataModel.debug("StateCtrl/getRunStatus: " + apiRun);
$http.get(apiRun)
.then(
@@ -367,9 +446,10 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
//console.log("***Pull to Refresh");
NVRDataModel.debug("StateCtrl/refresh: calling getRun/Load/Disk/CurrentState");
getRunStatus();
- $timeout(getLoadStatus, 2000);
- $timeout(getCurrentState, 4000);
- //$timeout (getDiskStatus,6000);
+ getLoadStatus();
+ getCurrentState();
+ getStorageStatus();
+ getServerStatus();
$scope.$broadcast('scroll.refreshComplete');
};
diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js
index e1fbc4ef..bfcb34da 100644
--- a/www/js/TimelineCtrl.js
+++ b/www/js/TimelineCtrl.js
@@ -20,6 +20,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
$ionicSideMenuDelegate.toggleLeft();
};
+
//---------------------------------------f-------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -283,9 +284,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
}
- NVRDataModel.debug("Timeline: Deregistering broadcast handles");
+ //NVRDataModel.debug("Timeline: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
- // broadcastHandles[i]();
+ broadcastHandles[i]();
}
broadcastHandles = [];
@@ -306,6 +307,19 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
$scope.$on('$ionicView.beforeEnter', function () {
+
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> TimelineCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
//$ionicHistory.clearCache();
//$ionicHistory.clearHistory();
timeline = '';
@@ -864,11 +878,11 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
myevents[j].Event.MonitorName = NVRDataModel.getMonitorName(myevents[j].Event.MonitorId);
myevents[j].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[j].Event.MonitorId);
- myevents[j].Event.baseURL = NVRDataModel.getBaseURL(myevents[j].Event.MonitorId);
+ myevents[j].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[j].Event.MonitorId);
myevents[j].Event.imageMode = NVRDataModel.getImageMode(myevents[j].Event.MonitorId);
- if (NVRDataModel.getLogin().url != myevents[j].Event.baseURL) {
+ if (NVRDataModel.getLogin().url != myevents[j].Event.recordingURL) {
- myevents[j].Event.baseURL = NVRDataModel.getLogin().url;
+ myevents[j].Event.recordingURL = NVRDataModel.getLogin().url;
}
if (typeof myevents[j].Event.DefaultVideo === 'undefined')
@@ -1168,16 +1182,14 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
// now construct base path
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
- if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) {
+ if (NVRDataModel.getLogin().url != myevents[i].Event.recordingURL) {
//NVRDataModel.debug ("Multi server, changing base");
- myevents[i].Event.baseURL = NVRDataModel.getLogin().url;
+ myevents[i].Event.recordingURL = NVRDataModel.getLogin().url;
}
- // console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
-
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+
if (idfound) {
diff --git a/www/js/TimelineModalCtrl.js b/www/js/TimelineModalCtrl.js
index 238d271a..11c604f1 100644
--- a/www/js/TimelineModalCtrl.js
+++ b/www/js/TimelineModalCtrl.js
@@ -47,15 +47,11 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
$scope.constructFrames = function (event, alarm) {
var stream = "";
- if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL + "/index.php?view=image" +
- "&path=" + event.Event.relativePath + alarm.fname +
- "&height=380";
- } else if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL + "/index.php?view=image" +
+
+ stream = event.Event.recordingURL + "/index.php?view=image" +
"&fid=" + alarm.id;
- }
+
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
@@ -125,13 +121,10 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
$scope.showImage = function (p, r, f, fid, e, imode, id) {
var img;
//console.log("Image Mode " + imode);
- if (imode == 'path')
-
- img = "<img width='100%' ng-src='" + p + "/index.php?view=image&path=" + r + f + "'>";
- else {
+
img = "<img width='100%' ng-src='" + p + "/index.php?view=image&fid=" + id + "'>";
// console.log ("IS MULTISERVER SO IMAGE IS " + img);
- }
+
$rootScope.zmPopup = $ionicPopup.alert({
title: 'frame:' + fid + '/Event:' + e,
template: img,
@@ -300,7 +293,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
fid: event.event.Frame[i].FrameId,
id: event.event.Frame[i].Id,
//group:i,
- relativePath: computeRelativePath(event.event),
+
score: event.event.Frame[i].Score,
fname: padToN(event.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg",
@@ -317,7 +310,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
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",
id: event.event.Frame[i].Id,
@@ -361,10 +354,10 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
//console.log ("You tapped " + ndx);
$scope.alarm_images = [];
- $scope.playbackURL = $scope.event.Event.baseURL;
+ $scope.playbackURL = $scope.event.Event.recordingURL;
var items = current_data.datasets[0].frames[ndx];
$scope.alarm_images.push({
- relativePath: items.relativePath,
+
fid: items.fid,
id: items.id,
fname: items.fname,
@@ -376,56 +369,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
}
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeRelativePath(event) {
- var relativePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
- relativePath = event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return relativePath;
-
- }
-
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeBasePath(event) {
- var basePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
-
- basePath = loginData.url + "/events/" +
- event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return basePath;
- }
+
function humanizeTime(str) {
return moment.tz(str, NVRDataModel.getTimeZoneNow()).fromNow();
diff --git a/www/js/WizardCtrl.js b/www/js/WizardCtrl.js
index f4b3d456..8a5f1ac4 100644
--- a/www/js/WizardCtrl.js
+++ b/www/js/WizardCtrl.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
/* global cordova,StatusBar,angular,console, Masonry, URI */
-angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$rootScope', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicHistory', '$state', '$ionicPopup', 'SecuredPopups', '$http', '$q', 'zm', '$ionicLoading', 'WizardHandler', '$translate', function ($scope, $rootScope, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $ionicHistory, $state, $ionicPopup, SecuredPopups, $http, $q, zm, $ionicLoading, WizardHandler, $translate) {
+angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$rootScope', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicHistory', '$state', '$ionicPopup', 'SecuredPopups', '$http', '$q', 'zm', '$ionicLoading', 'WizardHandler', '$translate', '$cookies', function ($scope, $rootScope, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $ionicHistory, $state, $ionicPopup, SecuredPopups, $http, $q, zm, $ionicLoading, WizardHandler, $translate, $cookies) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -342,6 +342,26 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
function logout(u) {
var d = $q.defer();
+ NVRDataModel.debug ("Clearing cookies");
+ if (window.cordova) {
+ // we need to do this or ZM will send same auth hash
+ // this was fixed in a PR dated Oct 18
+
+ cordova.plugin.http.clearCookies();
+ }
+ else {
+ angular.forEach($cookies, function (v, k) {
+ $cookies.remove(k);
+ });
+ }
+
+ if ($scope.wizard.useauth && $scope.wizard.usebasicauth) {
+ NVRDataModel.debug ("setting basic auth with "+$scope.wizard.basicuser+":"+$scope.wizard.basicpassword);
+ cordova.plugin.http.useBasicAuth($scope.wizard.basicuser, $scope.wizard.basicpassword);
+
+ }
+
+
$http({
method: 'POST',
diff --git a/www/js/app.js b/www/js/app.js
index fef31358..cf64c31b 100755
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -28,7 +28,8 @@ angular.module('zmApp', [
'uk.ac.soton.ecs.videogular.plugins.cuepoints',
'dcbImgFallback',
'ngImageAppear',
- 'angular-websocket'
+ 'angular-websocket',
+ 'ngCookies'
])
@@ -41,7 +42,7 @@ angular.module('zmApp', [
.constant('zm', {
minAppVersion: '1.28.107', // if ZM is less than this, the app won't work
recommendedAppVersion: '1.32.0',
- minEventServerVersion: '2.0',
+ minEventServerVersion: '2.4',
castAppId: 'BA30FB4C',
alarmFlashTimer: 20000, // time to flash alarm
gcmSenderId: '710936220256',
@@ -49,7 +50,7 @@ angular.module('zmApp', [
largeHttpTimeout: 30000,
logFile: 'zmNinjaLog.txt',
authoremail: 'pliablepixels+zmNinja@gmail.com',
- logFileMaxSize: 30000, // after this limit log gets reset
+ logFileMaxSize: 100000, // after this limit log gets reset
updateCheckInterval: 86400000, // 24 hrs
loadingTimeout: 15000,
@@ -714,6 +715,14 @@ angular.module('zmApp', [
}
//console.log ("HTTP response");
+
+
+ if (response.data && typeof(response.data) == 'string' && response.data.startsWith("<pre class=\"cake-error\">")) {
+ console.log ("cake error detected, attempting fix...");
+ response.data = JSON.parse(response.data.replace(/<pre class=\"cake-error\">[\s\S]*<\/pre>/,''));
+ //console.log ("FIXED="+response.data);
+ }
+ //"data":"<pre class=\"cake-error\">
return response;
}
@@ -852,7 +861,7 @@ angular.module('zmApp', [
// This service automatically logs into ZM at periodic intervals
//------------------------------------------------------------------
- .factory('zmAutoLogin', function ($interval, NVRDataModel, $http, zm, $browser, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate) {
+ .factory('zmAutoLogin', ['$interval', 'NVRDataModel', '$http', 'zm', '$timeout', '$q', '$rootScope', '$ionicLoading', '$ionicPopup', '$state', '$ionicContentBanner', 'EventServer', '$ionicHistory', '$translate', '$cookies',function ($interval, NVRDataModel, $http, zm, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate, $cookies) {
var zmAutoLoginHandle;
//------------------------------------------------------------------
@@ -956,17 +965,34 @@ angular.module('zmApp', [
// which actually means auth failed, but ZM treats it as a success
//------------------------------------------------------------------
+ function _doLoginNoLogout (str) {
+
+ return _doLogin(str);
+ }
+
+ function _doLogoutAndLogin(str) {
+ NVRDataModel.debug ("Clearing cookies");
- function doLogoutAndLogin(str) {
+ if (window.cordova) {
+ // we need to do this or ZM will send same auth hash
+ // this was fixed in a PR dated Oct 18
+
+ cordova.plugin.http.clearCookies();
+ }
+ /* else {
+ angular.forEach($cookies, function (v, k) {
+ $cookies.remove(k);
+ });
+ }*/
return NVRDataModel.logout()
.then(function (ans) {
- return doLogin(str);
+ return _doLogin(str);
});
}
- function doLogin(str) {
+ function _doLogin(str) {
var d = $q.defer();
var ld = NVRDataModel.getLogin();
@@ -979,13 +1005,6 @@ angular.module('zmApp', [
return d.promise;
}
-
- if ($rootScope.isDownloading) {
- NVRDataModel.log("Skipping login process as we are downloading...");
- d.resolve("success");
- return d.promise;
- }
-
NVRDataModel.debug("Resetting zmCookie...");
$rootScope.zmCookie = '';
// first try to login, if it works, good
@@ -995,7 +1014,7 @@ angular.module('zmApp', [
proceedWithLogin()
.then(function (success) {
- NVRDataModel.debug("Storing login time as " + moment().toString());
+ //NVRDataModel.debug("Storing login time as " + moment().toString());
localforage.setItem("lastLogin", moment().toString());
d.resolve(success);
return d.promise;
@@ -1115,7 +1134,7 @@ angular.module('zmApp', [
if (!succ.version) {
NVRDataModel.debug("API login returned fake success, going back to webscrape");
- var ld = NVRDataModel.getLogin();
+ ld = NVRDataModel.getLogin();
ld.loginAPISupported = false;
NVRDataModel.setLogin(ld);
@@ -1132,6 +1151,7 @@ angular.module('zmApp', [
return d.promise;
}
NVRDataModel.debug("API based login returned... ");
+ console.log (JSON.stringify(succ));
NVRDataModel.setCurrentServerVersion(succ.version);
$ionicLoading.hide();
//$rootScope.loggedIntoZm = 1;
@@ -1157,11 +1177,12 @@ angular.module('zmApp', [
d.resolve("Login Success");
-
$rootScope.$broadcast('auth-success', succ);
+ return d.promise;
+
} catch (e) {
NVRDataModel.debug("Login API approach did not work...");
- var ld = NVRDataModel.getLogin();
+ ld = NVRDataModel.getLogin();
ld.loginAPISupported = false;
NVRDataModel.setLogin(ld);
loginWebScrape()
@@ -1217,7 +1238,7 @@ angular.module('zmApp', [
}
- );
+ ); // post
@@ -1380,7 +1401,7 @@ angular.module('zmApp', [
$interval.cancel(zmAutoLoginHandle);
//doLogin();
zmAutoLoginHandle = $interval(function () {
- doLogin("");
+ _doLogin("");
}, zm.loginInterval); // Auto login every 5 minutes
// PHP timeout is around 10 minutes
@@ -1400,9 +1421,11 @@ angular.module('zmApp', [
return {
start: start,
stop: stop,
- doLogin: doLogoutAndLogin
+ doLogin: _doLogoutAndLogin,
+ doLoginNoLogout: _doLoginNoLogout
+
};
- })
+ }])
//====================================================================
// First run in ionic
@@ -1414,6 +1437,7 @@ angular.module('zmApp', [
$ionicPlatform.ready(function () {
//console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>INSIDE RUN");
+ NVRDataModel.log("******* app .run device ready");
$fileLogger.setStorageFilename(zm.logFile);
$fileLogger.setTimestampFormat('MMM d, y ' + NVRDataModel.getTimeFormatSec());
@@ -1452,26 +1476,6 @@ angular.module('zmApp', [
NVRDataModel.log("You are running on " + $rootScope.platformOS);
- /*if (window.cordova && $rootScope.platformOS == 'android') {
-
- cordova.plugins.diagnostic.isExternalStorageAuthorized(function (authorized) {
- if (!authorized) cordova.plugins.diagnostic.requestExternalStorageAuthorization(okperm, nopermerr);
- }, function (err) {
- console.log("diagnostic external storage error " + err);
- });
-
-
- }*/
-
-
- function nopermerr() {
- NVRDataModel.displayBanner('error', ['Storage permission must be allowed'], "", 4000);
- }
-
- function okperm() {
- //console.log("cool");
- NVRDataModel.displayBanner('success', ['Storage permission acquired'], "", 4000);
- }
$rootScope.appName = "zmNinja";
$rootScope.zmGlobalCookie = "";
@@ -1508,12 +1512,16 @@ angular.module('zmApp', [
//navigator.app.exitApp();
};
-
+
// This is a global exception interceptor
$rootScope.exceptionMessage = function (error) {
NVRDataModel.debug("**EXCEPTION**" + error.reason + " caused by " + error.cause);
};
+ // for .config block
+ $rootScope.debug = function (msg) {
+ NVRDataModel.debug(msg);
+ };
if ($rootScope.platformOS == 'desktop' && 0) {
@@ -1656,29 +1664,37 @@ angular.module('zmApp', [
// lets see if it really works
$rootScope.online = navigator.onLine;
- document.addEventListener("offline", function () {
- //console.log ("OFFLINE------------------------------------");
+ // set up network state handlers after 3secs
+ // android seems to howl about this at app start?
+ $timeout (function() {
+
+ NVRDataModel.log ("--------->Setting up network state handlers....");
+ document.addEventListener("offline", onOffline, false);
+ document.addEventListener("online", onOnline, false);
+
+ },3000);
+
+
+ function onOffline() {
$timeout(function () {
$rootScope.online = false;
- NVRDataModel.log("Your network went offline");
+ NVRDataModel.log("************** Your network went offline");
//$rootScope.$emit('network-change', "offline");
});
- }, false);
+ }
- document.addEventListener("online", function () {
- //console.log ("ONLINE------------------------------------");
+ function onOnline() {
$timeout(function () {
-
-
- NVRDataModel.log("Your network came back online");
+ if ($rootScope.online == true) {
+ NVRDataModel.log ("**** network online, but looks like it was not offline, not doing anything");
+ return;
+ }
+ NVRDataModel.log("************ Your network came back online");
$rootScope.online = true;
-
- $timeout(function () {
- // NVRDataModel.debug ("Ignoring - Alex R. Hack");
- if (0) {
+
var networkState = "browser not supported";
if (navigator.connection) networkState = navigator.connection.type;
NVRDataModel.debug("Detected network type as: " + networkState);
@@ -1693,15 +1709,13 @@ angular.module('zmApp', [
NVRDataModel.debug("Not changing bandwidth state, as auto change is not on");
}
NVRDataModel.log("Your network is online, re-authenticating");
- zmAutoLogin.doLogin($translate.instant('kReAuthenticating'));
- }
-
- }, 1000); // need a time gap, seems network type registers late
-
-
+ zmAutoLogin.doLoginNoLogout($translate.instant('kReAuthenticating'));
+
});
- }, false);
+
+ }
+
// This code takes care of trapping the Android back button
// and takes it to the menu.
@@ -1787,7 +1801,7 @@ angular.module('zmApp', [
toState.name != "app.zm-portal-login"
) {
- NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState));
+ // NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState));
localforage.setItem('last-desktop-state', {
'name': toState.name,
'params': toState.params
@@ -1826,7 +1840,7 @@ angular.module('zmApp', [
// to work in Windows
- NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState) + " with params:" + JSON.stringify(toParams));
+ //NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState) + " with params:" + JSON.stringify(toParams));
localforage.setItem('last-desktop-state', {
'name': toState,
'params': toParams
@@ -1998,7 +2012,7 @@ angular.module('zmApp', [
$rootScope.$stateParams = $stateParams;
if (window.cordova) {
- console.log("------------->Keyboard foonone");
+
//window.cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
@@ -2082,7 +2096,7 @@ angular.module('zmApp', [
localforage.getItem('last-desktop-state')
.then(function (succ) {
- console.log("FOUND STATE" + JSON.stringify(succ) + ":" + succ);
+// console.log("FOUND STATE" + JSON.stringify(succ) + ":" + succ);
// sanitize this
if (!succ.name || typeof succ.name !== 'string') {
@@ -2157,10 +2171,19 @@ angular.module('zmApp', [
function resumeHandler() {
+
NVRDataModel.setBackground(false);
NVRDataModel.setJustResumed(true);
$ionicPlatform.ready(function () {
+
+ NVRDataModel.log("******* resumeHandler device ready");
NVRDataModel.log("App is resuming from background");
+
+ NVRDataModel.log ("-->Re-registering online/offine");
+ document.addEventListener("offline", onOffline, false);
+ document.addEventListener("online", onOnline, false);
+
+
$rootScope.isDownloading = false;
var ld = NVRDataModel.getLogin();
@@ -2178,8 +2201,8 @@ angular.module('zmApp', [
$rootScope.lastState = $ionicHistory.currentView().stateName;
$rootScope.lastStateParam =
$ionicHistory.currentView().stateParams;
- NVRDataModel.debug("Last State recorded:" +
- JSON.stringify($ionicHistory.currentView()));
+ //NVRDataModel.debug("Last State recorded:" +
+ //JSON.stringify($ionicHistory.currentView()));
if ($rootScope.lastState == "app.zm-portal-login") {
NVRDataModel.debug("Last state was portal-login, so forcing montage");
@@ -2208,6 +2231,11 @@ angular.module('zmApp', [
}
function pauseHandler() {
+
+ NVRDataModel.log ("-->Clearing online/offine");
+ document.removeEventListener("offline", onOffline, false);
+ document.removeEventListener("online", onOnline, false);
+
NVRDataModel.setBackground(true);
NVRDataModel.setJustResumed(false);
// NVRDataModel.setJustResumed(true); // used for window stop
@@ -2255,7 +2283,7 @@ angular.module('zmApp', [
//------------------------------------------------------------------
// My route map connecting menu options to their respective templates and controllers
- .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, /*$ionicNativeTransitionsProvider,*/ $logProvider, $translateProvider) {
+ .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, /*$ionicNativeTransitionsProvider,*/ $logProvider, $translateProvider, $injector) {
//$logProvider.debugEnabled(false);
//$compileProvider.debugInfoEnabled(false);
@@ -2286,9 +2314,10 @@ angular.module('zmApp', [
// a) https://www.exratione.com/2013/08/angularjs-wrapping-http-for-fun-and-profit/
// b) https://gist.github.com/adamreisnz/354364e2a58786e2be71
- $provide.decorator('$http', ['$delegate', '$q', function ($delegate, $q) {
+ $provide.decorator('$http', ['$delegate', '$q', '$injector', function ($delegate, $q, $injector) {
// create function which overrides $http function
var $http = $delegate;
+ var logger = $injector.get("$rootScope");
var wrapper = function () {
var url;
@@ -2300,19 +2329,31 @@ angular.module('zmApp', [
if (window.cordova && isOutgoingRequest) {
+
var d = $q.defer();
var options = {
method: method,
data: arguments[0].data,
headers: arguments[0].headers,
- timeout: arguments[0].timeout,
+ // timeout: arguments[0].timeout,
responseType: arguments[0].responseType
};
+
+ if (arguments[0].timeout) options.timeout = arguments[0].timeout;
// console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)+" payload:"+JSON.stringify(options));
cordova.plugin.http.sendRequest(encodeURI(url), options,
function (succ) {
// automatic JSON parse if no responseType: text
// fall back to text if JSON parse fails too
+
+ // work around for cake-error leak
+
+ // console.log ("HTTP RESPONSE:" + JSON.stringify(succ.data));
+ if (succ.data && succ.data.startsWith("<pre class=\"cake-error\">") ) {
+ logger.debug ("**** Native: cake-error in message, trying fix...");
+ succ.data = JSON.parse(succ.data.replace(/<pre class=\"cake-error\">[\s\S]*<\/pre>/,''));
+ }
+
if (options.responseType == 'text') {
// don't parse into JSON
d.resolve({
@@ -2320,6 +2361,9 @@ angular.module('zmApp', [
});
return d.promise;
} else {
+
+
+
try {
d.resolve({
"data": JSON.parse(succ.data)
@@ -2337,7 +2381,7 @@ angular.module('zmApp', [
}
},
function (err) {
- console.log("*** Inside native HTTP error: " + JSON.stringify(err));
+ logger.debug("*** Inside native HTTP error: " + JSON.stringify(err));
d.reject(err);
return d.promise;
@@ -2495,12 +2539,12 @@ angular.module('zmApp', [
data: {
requireLogin: true
},
- resolve: {
+ /*resolve: {
message: function (NVRDataModel) {
// console.log("Inside app.montage resolve");
return NVRDataModel.getMonitors(0);
}
- },
+ },*/
url: "/monitors",
cache: false,
templateUrl: "templates/monitors.html",
diff --git a/www/lang/locale-ar.json b/www/lang/locale-ar.json
index 662bbc41..fc190a8c 100644
--- a/www/lang/locale-ar.json
+++ b/www/lang/locale-ar.json
@@ -250,7 +250,6 @@
"kSelectLanguage" :"اختيار اللغة",
"kSelectRunState" :"إختار وضع التشغيل",
"kSendingPTZ" :"Sending PTZ",
- "kSensitiveBody" :"will modify the logs when creating the final output to remove sensitive data like urls and passwords. However it is eventually your responsibility to make sure there is no sensitive data in the logs. Please make sure you review and edit the logs before you send it out",
"kSensitiveTitle" :"معلومات حساسة",
"kServerAdd" :"إضافة",
"kServerEmptyError" :"اسم الخادم لايمكن ان يكون فارغاً",
diff --git a/www/lang/locale-ba.json b/www/lang/locale-ba.json
index 6b0bef08..9ba1aa05 100644
--- a/www/lang/locale-ba.json
+++ b/www/lang/locale-ba.json
@@ -419,4 +419,3 @@
"kZMStopped" :"zaustavljeno",
"kZMUndetermined" :"neodređeno",
"kZMUpgradeNeeded" :"Potrebno ažurirati ZoneMinder"
-} \ No newline at end of file
diff --git a/www/lang/locale-de.json b/www/lang/locale-de.json
index 3292a558..b2cf65ed 100644
--- a/www/lang/locale-de.json
+++ b/www/lang/locale-de.json
@@ -15,6 +15,7 @@
"kApplyingChanges" :"Wende Änderungen an. Bitte warten",
"kArrangingImages" :"Ordne Kameras",
"kAt" :"um",
+ "kAuthHashDisabled" :"AUTH_HASH_LOGINS muss aktiviert werden, damit Bilder angezeigt werden. Starte bitte nach dem Aktivieren ZM neu.",
"kAuthSuccess" :"Authentifizierung erfolgreich",
"kAuthenticating" :"verbinde ",
"kAuthenticatingWebScrape" :"verbinde über Web Scrape",
@@ -73,7 +74,10 @@
"kDiscoveringAPI" :"Suche API",
"kDiscoveringCGI" :"Suche CGI",
"kDiscoveringPortal" :"Suche Portal",
+ "kDismiss" :"verwerfen",
"kDone" :"Erledigt",
+ "kDownload" :"Herunterladen",
+ "kDownloadVideoImage" :"Drücke den Knopf um das Video herunterzuladen. Bitte achte auf die Dateigröße, da es kein Fortschrittsbalken während des Downloads gibt.",
"kEmailNotConfigured" :"Email nicht eingerichtet",
"kEnable24hr" :"24-Stunden Zeitformat aktivieren",
"kEnableDebug" :"Aktiviere Debug Logs",
@@ -216,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"None",
+ "kMonPortalURL" :"Portal URL",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"Record",
+ "kMonRecordingURL" :"Aufnahme URL",
+ "kMonStreamingURL" :"Streaming URL",
"kMonitorSingleImageScale" :"Livebild Einzelbildgröße",
"kMonitors" :"Kameras",
"kMontage" :"Übersicht",
@@ -293,8 +300,8 @@
"kProfileChangeNotification" :"Du hast von {{oldName}} zu {{newName}} gewechselt. Bitte zuerst dieses Profil speichern",
"kProtect" :"Schutz",
"kPullToReload" :"Ziehen um Daten neu zu laden",
- "kReachabilityFailed" :"Anmeldung am Hauptserver fehlgeschlagen,versuche Reservesystem",
"kReAuthenticating" :"Erneute Authentifizierung",
+ "kReachabilityFailed" :"Anmeldung am Hauptserver fehlgeschlagen,versuche Reservesystem",
"kRecaptcha" :"Scheint so, dass Du reCaptcha aktiviert hast. Bitte schalte es aus, damit diese App funktioniert",
"kReconfirmPin" :"PIN bestätigen",
"kRecordingProgress" :"Aufnahme im Gange",
@@ -308,10 +315,11 @@
"kResumeDelay" :"Verzögerung resumen",
"kRetrievingProfileData" :"empfange Profildaten",
"kSave" :"Speichern",
- "kSavingSnapshot" :"Sichere Einzelbild ",
"kSaveToCloud" :"mit der Cloud synchronisieren",
- "kSaveToCloudIOS" :"sichere Einstellungen in Dein iCloud-Konto. Der Synchronisationsvorgang kann einige Stunden dauern",
"kSaveToCloudANDROID" :"sichere Einstellungen über den Backup Service von Android. Der Synchronisationsvorgang kann einige Stunden dauern",
+ "kSaveToCloudIOS" :"sichere Einstellungen in Dein iCloud-Konto. Der Synchronisationsvorgang kann einige Stunden dauern",
+ "kSavingSnapshot" :"Sichere Einzelbild ",
+ "kScheme" :"Schema",
"kScore" :"Punktzahl",
"kScrub" :"Analyse",
"kSearch" :"Suche",
@@ -324,7 +332,7 @@
"kSelectRunState" :"Status auswählen",
"kSelectSwitch" :"Ausgewähltes Profil wird geladen",
"kSendingPTZ" :"Sende PTZ",
- "kSensitiveBody" :"In der Log-Datei, welche nun zum verschicken erstellt wird, werden sensible Daten, wie URLs und Passwörter, entfernt. Überprüfe trotzdem, dass keine sensiblen Daten in dem Log sind, bevor Du die Datei verschickst.",
+ "kSensitiveBody" :"*** Bitte mache vor dem Versenden der Logdatei alle vertraulichen Daten unkenntlich. zmNinja versucht bereits Passwörter herauszufiltern, allerdings kann es sein, dass Passwörter erhalten bleiben, wenn Sie z.B. im URL enthalten sind. ***",
"kSensitiveTitle" :"Vertrauliche Daten",
"kServerAdd" :"Hinzufügen",
"kServerEmptyError" :"Servername darf nicht leer sein",
@@ -342,13 +350,22 @@
"kSpeed" :"Geschwindigkeit",
"kStart" :"Start",
"kStateAreYouSure" :"Bist Du sicher, dass Du folgendes tun möchtest ",
+ "kStateCpuLoad" :"CPU Auslastung",
+ "kStateDiskUsed" :"Festplatte benutzt",
+ "kStateFreeMem" :"Arbeitsspeicher frei",
"kStateHideControls" :"Verstecke ZoneMinder Bedienelemente",
+ "kStateHost" :"Host",
+ "kStatePath" :"Pfad",
+ "kStateServer" :"Server",
"kStateShowControls" :"Zeige ZoneMinder Bedienelemente",
+ "kStateStorage" :"Speicherplatz",
+ "kStateTotalMem" :"Arbeitsspeicher gesamt",
"kStatus" :"Status",
"kStop" :"Stop",
"kSuccess" :"erledigt",
"kSwitchingEvents" :"wechsle Ereignisse",
"kSystemStatus" :"Systemstatus",
+ "kTapDownloadLogs" :"Klicke auf den Button um die Logdateien herunterzuladen.",
"kTapEvents" :"Ereignisse",
"kTapLiveMonitor" :"Livebild",
"kTapMontage" :"Livebild",
@@ -366,6 +383,7 @@
"kToDate" :"Datum bis",
"kToTime" :"Zeit bis",
"kToastSearchingPage" :"Suchseite",
+ "kToggleSummary" :"Ergebnis durchschalten",
"kTrue" :"an",
"kTrying" :"versuche",
"kType" :"Typ",
@@ -384,7 +402,6 @@
"kVibrateOnPush" :"Bei Push vibrieren",
"kVideo" :"Video",
"kVideoError" :"Video nicht abspielbar.",
- "kVideoErrorMobile" :"Video nicht abspielbar. Versuche 'force image path for events' in den Entwicklereinstellungen zu aktivieren. Der Format kann auch inkompatibel mit einem mobilen Systenview sein",
"kVideoLoading" :"Lade Video",
"kVideoMp4Warning" :"Es ist aktuell nicht erkennbar, wann das Video komplett heruntergeladen ist. Bitte Downloadgröße verfolgen.",
"kWarningBasicAuth" :"Basisauthentifizierung kann das Abspielen des Livebilds stören. Bitte FAQ lesen",
diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json
index b30f2d23..123a3445 100644
--- a/www/lang/locale-en.json
+++ b/www/lang/locale-en.json
@@ -18,7 +18,7 @@
"kAuthHashDisabled" :" AUTH_HASH_LOGINS needs to be enabled to display images. Please restart ZM afer enabling it.",
"kAuthSuccess" :"authentication success",
"kAuthenticating" :"authenticating",
- "kAuthenticatingWebScrape" : "authenticating via web scrape",
+ "kAuthenticatingWebScrape" :"authenticating via web scrape",
"kAutoSwitchBW" :"auto switch bandwidth",
"kAwake1" :"Keep display on",
"kAwake2" :"(when viewing footage)",
@@ -52,7 +52,7 @@
"kCycleMonitorsInterval" :"monitor cycle interval",
"kCycleMontageInterval" :"montage cycle interval",
"kDataPrivacy" :"Data Privacy",
- "kDataPrivacyZM" : "zmNinja will not function properly till your process ZoneMinder's Privacy Policy. Please open ZoneMinder web console and accept or reject it.",
+ "kDataPrivacyZM" :"zmNinja will not function properly till your process ZoneMinder's Privacy Policy. Please open ZoneMinder web console and accept or reject it.",
"kDay" :"Day",
"kDecreaseSize" :"decrease size",
"kDelete" :"Delete",
@@ -74,10 +74,10 @@
"kDiscoveringAPI" :"discovering api",
"kDiscoveringCGI" :"discovering cgi",
"kDiscoveringPortal" :"discovering portal",
- "kDismiss" : "Dismiss",
+ "kDismiss" :"Dismiss",
"kDone" :"done",
"kDownload" :"Download",
- "kDownloadVideoImage" : "Tap the button below to download. If you are downloading a video, there is no progress indication, so please monitor file size",
+ "kDownloadVideoImage" :"Tap the button below to download. If you are downloading a video, there is no progress indication, so please monitor file size",
"kEmailNotConfigured" :"Email not configured",
"kEnable24hr" :"enable 24hr time format",
"kEnableDebug" :"Enable debug logs",
@@ -220,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"None",
+ "kMonPortalURL" :"Portal url",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"record",
+ "kMonRecordingURL" :"Recording url",
+ "kMonStreamingURL" :"Streaming url",
"kMonitorSingleImageScale" :"Live view single image scale",
"kMonitors" :"Monitors",
"kMontage" :"Montage",
@@ -297,8 +300,8 @@
"kProfileChangeNotification" :"You have changed from {{oldName}} to {{newName}}. Please save this profile first",
"kProtect" :"protect",
"kPullToReload" :"pull to reload data",
- "kReachabilityFailed" : "primary login failed, trying fallbacks",
"kReAuthenticating" :"re-authenticating",
+ "kReachabilityFailed" :"primary login failed, trying fallbacks",
"kRecaptcha" :"Looks like you have enabled reCaptcha. It needs to be turned off for the app to work",
"kReconfirmPin" :"Reconfirm PIN",
"kRecordingProgress" :"recording in progress",
@@ -312,10 +315,11 @@
"kResumeDelay" :"resume delay",
"kRetrievingProfileData" :"retrieving profile data",
"kSave" :"Save",
- "kSavingSnapshot" :"saving snapshot",
"kSaveToCloud" :"sync with cloud",
- "kSaveToCloudIOS" :"saves settings to your personal iCloud account. May take several hours to sync",
"kSaveToCloudANDROID" :"saves settings via Android's Backup Service. May take several hours to sync",
+ "kSaveToCloudIOS" :"saves settings to your personal iCloud account. May take several hours to sync",
+ "kSavingSnapshot" :"saving snapshot",
+ "kScheme" :"Scheme",
"kScore" :"score",
"kScrub" :"Scrub",
"kSearch" :"search",
@@ -328,7 +332,7 @@
"kSelectRunState" :"Select run state",
"kSelectSwitch" :"Selected profile will be loaded",
"kSendingPTZ" :"Sending PTZ",
- "kSensitiveBody" :"will modify the logs when creating the final output to remove sensitive data like urls and passwords. However it is eventually your responsibility to make sure there is no sensitive data in the logs. Please make sure you review and edit the logs before you send it out",
+ "kSensitiveBody" :"*** Before you send the logs, please make sure you remove any sensitive information. zmNinja tries to filter out passwords, but it is possible that passwords will be included if you include them in URLs, for example ***",
"kSensitiveTitle" :"Sensitive Information",
"kServerAdd" :"Add",
"kServerEmptyError" :"Server Name cannot be empty",
@@ -346,13 +350,23 @@
"kSpeed" :"speed",
"kStart" :"Start",
"kStateAreYouSure" :"Are you sure you want to ",
+ "kStateCpuLoad" :"CPU Load",
+ "kStateDiskUsed" :"Disk Used",
+ "kStateFreeMem" :"Free Memory",
"kStateHideControls" :"Hide ZoneMinder Controls",
+ "kStateHost" :"Host",
+ "kStateMultiServer" :"multi server",
+ "kStatePath" :"Path",
+ "kStateServer" :"Server",
"kStateShowControls" :"Show ZoneMinder Controls",
+ "kStateStorage" :"Storage",
+ "kStateTotalMem" :"Total Memory",
"kStatus" :"Status",
"kStop" :"Stop",
"kSuccess" :"Success",
"kSwitchingEvents" :"switching events",
"kSystemStatus" :"System Status",
+ "kTapDownloadLogs" :"Tap the button to download logs",
"kTapEvents" :"Events",
"kTapLiveMonitor" :"Live Monitor",
"kTapMontage" :"Montage",
@@ -370,6 +384,7 @@
"kToDate" :"To Date",
"kToTime" :"To Time",
"kToastSearchingPage" :"searching page ",
+ "kToggleSummary" :"toggle summary",
"kTrue" :"true",
"kTrying" :"trying",
"kType" :"type",
@@ -387,8 +402,7 @@
"kVersionIncompatible" :"I am incompatible with your ZoneMinder version",
"kVibrateOnPush" :"Vibrate on push",
"kVideo" :"Video",
- "kVideoError" :"Video not playable.",
- "kVideoErrorMobile" :"Video not playable. Try enabling 'force image path for events' in Dev Settings. The format may also be incompatible with a mobile system view",
+ "kVideoError" :"Video not playable",
"kVideoLoading" :"Loading Video",
"kVideoMp4Warning" :"It is currently not possible to know when video is fully downloaded. Please track file size of download.",
"kWarningBasicAuth" :"Basic auth may interfere with live streaming. Please read FAQ",
diff --git a/www/lang/locale-es.json b/www/lang/locale-es.json
index 95375571..d4fb53a6 100644
--- a/www/lang/locale-es.json
+++ b/www/lang/locale-es.json
@@ -324,7 +324,6 @@
"kSelectRunState" :"Seleccionar estado de funcionamiento",
"kSelectSwitch" :"El perfil seleccionado será cargado",
"kSendingPTZ" :"Enviando PTZ",
- "kSensitiveBody" :"Se modificarán los registros cuando se cree la salida final para remover información sensible como urls y contraseñas. Sin embargo eventualmente es su responsabilidad el asegurarse que no haya información sensible en los registros. Por favor asegúrese de haber revisado y editado los registros antes de enviarlos.",
"kSensitiveTitle" :"Información Sensible",
"kServerAdd" :"Añadir",
"kServerEmptyError" :"El servidor debe tener un nombre válido.",
@@ -384,7 +383,6 @@
"kVibrateOnPush" :"Vibrar en notificaciones push",
"kVideo" :"Vídeo",
"kVideoError" :"El vídeo no se puede reproducir.",
- "kVideoErrorMobile" :"El vídeo no se puede reproducir. Trata de habilitar 'forzar el directorio para los eventos' en Opc de Desarrollador. El formato también podría ser incompatible con la vista en sistemas móviles",
"kVideoLoading" :"Cargando Vídeo",
"kVideoMp4Warning" :"Actualmente no es posible saber cuando el vídeo se ha descargado completamente. Por favor fíjese en el tamaño del archivo para tener un estimado.",
"kWarningBasicAuth" :"La autenticación básica puede interferir con stremings en vivo. Por favor lea las preguntas frecuentes.",
diff --git a/www/lang/locale-fr.json b/www/lang/locale-fr.json
index 8d507b0d..0b5dd537 100644
--- a/www/lang/locale-fr.json
+++ b/www/lang/locale-fr.json
@@ -287,7 +287,6 @@
"kSelectRunState" :"Choix du mode de fonctionnement",
"kSelectSwitch" :"Profil à charger",
"kSendingPTZ" :"Envoi PTZ",
- "kSensitiveBody" :"modifiera les logs lors de la création du rapport afin de supprimer les informations sensibles (mots de passe, URLs, etc.). Cependant il est de votre responsabilité de vérifier que les logs ne contiennent aucun information sensible. Merci de le faire avant l'envoi.",
"kSensitiveTitle" :"Informations sensibles",
"kServerAdd" :"Ajouter",
"kServerEmptyError" :"Le nom du serveur ne peut être vide",
@@ -341,7 +340,6 @@
"kVibrateOnPush" :"Vibrer en cas de notification",
"kVideo" :"Vidéo",
"kVideoError" :"Impossible de lire la vidéo.",
- "kVideoErrorMobile" :"Impossible de lire la vidéo. Essayez d'activer l'option 'Forcer le chemin des événements' dans les options développeur. Il se peut que le format soit incompatible avec les appareils mobiles",
"kVideoLoading" :"Chargement de la vidéo",
"kVideoMp4Warning" :"Impossible de déterminer l'avancement du téléchargement de la vidéo. Veuillez suivre la taille du fichier.",
"kWarningLargeTimeline" :"Une valeur élevée peut réduire les performances. Si vous trouvez le calendrier lent, essayez de réduire à la valeur 200 puis augmentez progressivement.",
diff --git a/www/lang/locale-hu.json b/www/lang/locale-hu.json
index 77a09b46..4f4db929 100644
--- a/www/lang/locale-hu.json
+++ b/www/lang/locale-hu.json
@@ -290,7 +290,6 @@
"kSelectRunState" :"Válassza ki a futási állapotot",
"kSelectSwitch" :"A kiválasztott profil betöltődik",
"kSendingPTZ" :"PTZ küldése",
- "kSensitiveBody" :"Módosítja a naplókat, amikor létrehozza a végső kimenetet az érzékeny adatok - például urls és jelszavak - eltávolításához. Végül azonban az Ön felelőssége, hogy győződjön meg arról, hogy nincsenek érzékeny adatok a naplókban. Kérjük, győződjön meg róla, hogy a naplófájlokat ellenőrizze és szerkesztette, mielőtt elküldené",
"kSensitiveTitle" :"Érzékeny információ",
"kServerAdd" :"Hozzáad",
"kServerEmptyError" :"A kiszolgáló neve nem lehet üres",
@@ -344,7 +343,6 @@
"kVibrateOnPush" :"Rezgés érintéskor",
"kVideo" :"Videó",
"kVideoError" :"A videó nem játszható le.",
- "kVideoErrorMobile" :"A videó nem játszható. Próbálja engedélyezni a 'Elérési út az eseményekhez' lehetőséget az eszköz beállításaiban. A formátum is összeegyeztethetetlen a mobil rendszer nézettel",
"kVideoLoading" :"Videó betöltése",
"kVideoMp4Warning" :"Jelenleg nem lehet tudni, hogy a videó teljesen letöltődik-e. Kérjük, kövesse nyomon a letöltés fájlméretét.",
"kWarningLargeTimeline" :"Nagy érték befolyásolhatja az idővonal teljesítményét. Ha az idővonal teljesítményét lassunak találja, próbálja csökkenteni a 200-as értéket, és folytassa tovább.",
diff --git a/www/lang/locale-it.json b/www/lang/locale-it.json
index a0e2ca06..930792c1 100644
--- a/www/lang/locale-it.json
+++ b/www/lang/locale-it.json
@@ -249,7 +249,6 @@
"kSelectLanguage" :"Seleziona Lingua",
"kSelectRunState" :"Seleziona modo operativo",
"kSendingPTZ" :"Invio PTZ",
- "kSensitiveBody" :"Dovrai modificare il log,quando lo vorrai inviare, dovrai togliere i tuoi dati sensibili. In ogni caso sarà tua responsabilità assicurarti che non ci siano dati sensibili. Fai attenzione a rimuovere i dati sensibili quando invii il log",
"kSensitiveTitle" :"Informazioni sensibili",
"kServerAdd" :"Aggiungi",
"kServerEmptyError" :"Il nome del server non può rimanere vuoto",
diff --git a/www/lang/locale-nl.json b/www/lang/locale-nl.json
index ab09023e..a6367952 100755
--- a/www/lang/locale-nl.json
+++ b/www/lang/locale-nl.json
@@ -282,7 +282,6 @@
"kSelectRunState" :"Uitvoerings modus selecteren",
"kSelectSwitch" :"Geselecteerde profiel wordt geladen",
"kSendingPTZ" :"PTZ zenden",
- "kSensitiveBody" :"in de opgeslagen log bestanden worden gevoelige gegevens zoals urls en wachtwoorden verwijderd. Het is echter uw verantwoordelijkheid om er zeker van te zijn dat er geen gevoelige gegevens achterblijven. Voordat u de bestanden verzendt verzeker u hiervan door deze na te kijken en indien nodig te bewerken.",
"kSensitiveTitle" :"Gevoelige informatie",
"kServerAdd" :"Toevoegen",
"kServerEmptyError" :"Server naam mag niet leeg zijn",
@@ -336,7 +335,6 @@
"kVibrateOnPush" :"Trillen bij push",
"kVideo" :"Video",
"kVideoError" :"Kan video niet afspelen.",
- "kVideoErrorMobile" :"Kan video niet afspelen. Probeer 'Dwing gebeurtenissen bestands map te gebruiken' te activeren in ontwikkelaars instellingen. Het formaat is wellicht ook niet compatible met mobiel systeem beeld",
"kVideoLoading" :"Video laden",
"kVideoMp4Warning" :"Het is niet mogelijk te detecteren wanneer video volledig is gedownload. Vergelijk grootte van de download.",
"kWarningLargeTimeline" :"Een hoge waarde kan de tijdlijn prestatie beïnvloeden. Bij slechte prestaties van de tijdlijn start met een waarde van 200 en verhoog deze langzaam.",
diff --git a/www/lang/locale-pl.json b/www/lang/locale-pl.json
index 486d0e0d..6a24dfcd 100644
--- a/www/lang/locale-pl.json
+++ b/www/lang/locale-pl.json
@@ -220,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"Żaden",
+ "kMonPortalURL" :"url Portalu",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"Record",
+ "kMonRecordingURL" :"url Nagrywania",
+ "kMonStreamingURL" :"url Streamingu",
"kMonitorSingleImageScale" :"Skalowanie pojedynczego obrazy Podglądu na żywo",
"kMonitors" :"Monitory",
"kMontage" :"Podgląd",
@@ -297,8 +300,8 @@
"kProfileChangeNotification" :"Zmieniłeś z {{oldName}} na {{newName}}. Zapisz wcześniej ten profil.",
"kProtect" :"zabezpiecz",
"kPullToReload" :"przeciągnij by przeładować dane",
- "kReachabilityFailed" :"podstawowe logowanie nie powiodło się, próbuję zapasowego",
"kReAuthenticating" :"ponowne uwierzytelnianie",
+ "kReachabilityFailed" :"podstawowe logowanie nie powiodło się, próbuję zapasowego",
"kRecaptcha" :"Wygląda na to, że właczyłeś reCaptcha. Powinna być wyłączona, żeby aplikacja działała.",
"kReconfirmPin" :"Potwierdź PIN",
"kRecordingProgress" :"trwa nagrywanie",
@@ -313,9 +316,10 @@
"kRetrievingProfileData" :"pobieranie danych profilu",
"kSave" :"Zapisz",
"kSaveToCloud" :"synchronizuj z chmurą",
- "kSaveToCloudIOS" :"zapisuje ustawienia na twoim koncie iCloud. Synchronizacja może zająć kilka godzin",
"kSaveToCloudANDROID" :"zapisuje ustawienia przez Serwis Backup Android'a. Synchronizacja może zająć kilka godzin",
+ "kSaveToCloudIOS" :"zapisuje ustawienia na twoim koncie iCloud. Synchronizacja może zająć kilka godzin",
"kSavingSnapshot" :"zapisuję obraz",
+ "kScheme" :"Schemat",
"kScore" :"punkty",
"kScrub" :"Podgląd",
"kSearch" :"szukaj",
@@ -328,7 +332,7 @@
"kSelectRunState" :"Wybierz stan działania",
"kSelectSwitch" :"Wybrany profil zostanie załadowany",
"kSendingPTZ" :"Wysyła PTZ",
- "kSensitiveBody" :"tworząc finalny log zmodyfikuje jego zawartość, aby usunąć wrażliwe dane takie jak linki czy hasła. Jednak na Tobie spoczywa odpowiedzialność upewnienia się, że wszystkie dane wrażliwe zostały usunięte. Upewnij się, że przeglądnąłeś i edytowałeś log przed jego wysłaniem",
+ "kSensitiveBody" :"*** Zanim wyślesz log, upewnij się, że usunąłeś wszystkie wrażliwe dane. zmNinja spróbuje usunąć hasła, jednak możliwe, że część z nich pozostanie, np. te umieszczone w adresach URL ***",
"kSensitiveTitle" :"Dane Wrażliwe",
"kServerAdd" :"Dodaj",
"kServerEmptyError" :"Nazwa serwera nie może być pusta",
@@ -346,13 +350,23 @@
"kSpeed" :"prędkość",
"kStart" :"Start",
"kStateAreYouSure" :"Jesteś pewien, że chcesz ",
+ "kStateCpuLoad" :"Obciążenie CPU",
+ "kStateDiskUsed" :"Dysku w użyciu",
+ "kStateFreeMem" :"Wolnej pamięci",
"kStateHideControls" :"Ukryj Przyciski ZoneMinder",
+ "kStateHost" :"Host",
+ "kStateMultiServer" :"wiele serwerów",
+ "kStatePath" :"Ścieżka",
+ "kStateServer" :"Serwer",
"kStateShowControls" :"Pokaż Przyciski ZoneMinder",
+ "kStateStorage" :"Pamięć",
+ "kStateTotalMem" :"Całość pamięci",
"kStatus" :"Stan",
"kStop" :"Stop",
"kSuccess" :"Sukces",
"kSwitchingEvents" :"przełączam zdarzenia",
"kSystemStatus" :"Stan Systemu",
+ "kTapDownloadLogs" :"Wciśnij przycisk by pobrać logi",
"kTapEvents" :"Zdarzenia",
"kTapLiveMonitor" :"Podgląd na żywo",
"kTapMontage" :"Podgląd",
@@ -370,6 +384,7 @@
"kToDate" :"Do Daty",
"kToTime" :"Do Czasu",
"kToastSearchingPage" :"szuka strony ",
+ "kToggleSummary" :"przełącz Zdarzenia na podsumowanie",
"kTrue" :"prawda",
"kTrying" :"próbuję",
"kType" :"typ",
@@ -387,8 +402,7 @@
"kVersionIncompatible" :"Jestem niekompatybilny z wersją Twojego ZoneMinder'a",
"kVibrateOnPush" :"Wibruj przy dotknięciu",
"kVideo" :"Wideo",
- "kVideoError" :"Wideo nie odtwarzalne.",
- "kVideoErrorMobile" :"Wideo nie odtwarzalne. Spróbuj włączyć 'wymuś ścieżkę obrazu dla zdarzenia' w Ustawieniach Zaawansowanych. Format może być też niekompatybilny z przeglądarką systemu mobilnego",
+ "kVideoError" :"Wideo nie odtwarzalne",
"kVideoLoading" :"Ładuję Wideo",
"kVideoMp4Warning" :"Obecnie nie ma możliwości stwierdzenia, czy wideo zostało w pełni ściągnięte. Sprawdź wielkość pliku do ściągnięcia.",
"kWarningBasicAuth" :"Prosta autoryzacja może powodować konflikt ze streamingiem na żywo. Proszę, przeczytaj FAQ",
diff --git a/www/lang/locale-pt.json b/www/lang/locale-pt.json
index 703f9048..276ff573 100644
--- a/www/lang/locale-pt.json
+++ b/www/lang/locale-pt.json
@@ -261,7 +261,6 @@
"kSelectLanguage" :"Escolher Linguagem",
"kSelectRunState" :"Escolher estado de execução",
"kSendingPTZ" :"Enviando PTZ",
- "kSensitiveBody" :"modificará os logs ao criar o resultado final para remover os dados sensíveis, como URLs e senhas. No entanto, é, eventualmente, da sua responsabilidade certificar-se de que não há dados sensíveis nos logs. Por favor, certifique-se de rever e editar os registos antes de enviá-lo para fora",
"kSensitiveTitle" :"Informação Sensivel",
"kServerAdd" :"Adicionar",
"kServerEmptyError" :"O Nome do Servidor tem de estar preenchido",
@@ -313,7 +312,6 @@
"kVibrateOnPush" :"Vibrar ao premir",
"kVideo" :"Vídeo",
"kVideoError" :"Vídeo não reproduzível.",
- "kVideoErrorMobile" :"Vídeo não reproduzível. Experimente ativar 'forçar o caminho da imagem para eventos' em Configurações Dev. O formato também pode ser incompatível com o sistema de visualização do equipamento móvel",
"kVideoLoading" :"Carregando Vídeo",
"kVideoMp4Warning" :"Não é possível de momento saber quando o vídeo está totalmente carregado. Por favor, verifique o tamnho do arquivo de download.",
"kWarningLargeTimeline" :"Um valor elevado pode afetar o desempenho da timeline. Se você achar o desempenho da timeline lento, tente reduzir o valor para 200 e trabalhe a partir daí.",
diff --git a/www/lang/locale-ru.json b/www/lang/locale-ru.json
index a359eb58..b79de803 100644
--- a/www/lang/locale-ru.json
+++ b/www/lang/locale-ru.json
@@ -266,7 +266,6 @@
"kSelectRunState" :"Выбрать состояние запуска",
"kSelectSwitch" :"Выбранный профиль будет загружен",
"kSendingPTZ" :"Отправка PTZ",
- "kSensitiveBody" :"пытается модифицировать логи когда создает отчет для обезличивания персональной информации например ссылок и паролей. Однако это ваша ответственность быть уверенным что логи не содержат конфиденциальную информацию. Перед тем как отправлять емейл, пожалуйста проверьте логи и подкорректируйте их если потребуется",
"kSensitiveTitle" :"Персональная Информация",
"kServerAdd" :"Добавить",
"kServerEmptyError" :"Имя сервера не может быть пустым",
@@ -318,7 +317,6 @@
"kVibrateOnPush" :"Вибрировать при нажатии",
"kVideo" :"Видео",
"kVideoError" :"Не возможно проиграть видео.",
- "kVideoErrorMobile" :"Не возможно проиграть видео. Попробуйте включить 'принудительный путь к картинкам для событий' в Настройках Разработчика. Формат может быть также не совместим с плеером мобильной системой",
"kVideoLoading" :"Загрузка Видео",
"kVideoMp4Warning" :"Сейчас не возможно определить когда видео будет полностью загружено. Пожалуйста следите за размером скачиваемого файла.",
"kWarningLargeTimeline" :"Большое значение может повлиять на производительность временной шкалы. Если производительность временной шкалы медленна, попробуйте уменьшить значение до 200.",
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
index 164c3f62..319f8366 100644
--- a/www/templates/events-modal.html
+++ b/www/templates/events-modal.html
@@ -33,14 +33,15 @@
</div>
-
+
<img ng-if="!liveFeedMid" image-spinner-src="{{constructStream()}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}"
on-double-tap="closeModal();" img-spinner-w="1024" img-spinner-h="768" image-spinner-loader="lines"
imageonload="modalImageLoaded()" on-swipe-left="onSwipeEvent(nextId,1)" on-swipe-right="onSwipeEvent(prevId,-1)" />
<div ng-if="liveFeedMid">
- <img image-spinner-src="{{loginData.streamingurl}}/nph-zms?mode=jpeg&monitor={{liveFeedMid}}&connkey={{connKey}}{{$root.authSession}}"
+
+ <img image-spinner-src="{{currentEvent.Event.streamingURL}}/nph-zms?mode=jpeg&monitor={{liveFeedMid}}&connkey={{connKey}}{{$root.authSession}}"
ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-double-tap="closeModal();"
img-spinner-w="1024" img-spinner-h="768" image-spinner-loader="lines" imageonload="modalImageLoaded()"
on-swipe-left="onSwipeEvent(nextId,1)" on-swipe-right="onSwipeEvent(prevId,-1)" />
diff --git a/www/templates/events-popover.html b/www/templates/events-popover.html
index d61f8f5b..2620c9b3 100644
--- a/www/templates/events-popover.html
+++ b/www/templates/events-popover.html
@@ -11,8 +11,13 @@
</a>
<a class="item" ng-href="" ng-click="popover.hide();toggleMinAlarmFrameCount();" ng-if="loginData.enableAlarmCount">{{'kShowAllEvents'
| translate}}</a>
+
<a class="item" ng-href="" ng-click="popover.hide();toggleMinAlarmFrameCount();" ng-if="!loginData.enableAlarmCount">
{{'kShowAlarmedEvents' | translate}}</a>
+
+ <a class="item" ng-href="" ng-click="popover.hide();footerToggle();" >
+ {{ 'kToggleSummary' | translate}}</a>
+
</div>
</ion-content>
</ion-popover-view>
diff --git a/www/templates/events.html b/www/templates/events.html
index b312a79c..71522fa0 100644
--- a/www/templates/events.html
+++ b/www/templates/events.html
@@ -152,13 +152,13 @@
<span ng-repeat="alarm in alarm_images | selectFrames: typeOfFrames">
<figure class="animated slideInLeft" style="display:inline-block">
- <!--{{event.Event.baseURL}} p:{{event.Event.imageMode}}-->
+ <!--{{event.Event.recordingURL}} p:{{event.Event.imageMode}}-->
<figcaption class="smallnote">
<span translate="kFrame"></span>:{{alarm.frameid}},
<span translate="kScore"></span>:{{alarm.score}},
<span translate="kTime"></span>: {{prettifyTimeSec(alarm.time)}}</figcaption>
<img ng-src="{{constructAlarmFrame(event,alarm,true)}}" fallback-src="{{constructAlarmFrame(event,alarm,false)}}"
- style="width: auto; height: auto;max-width: 100%;max-height: 170px" on-tap="showImage(event.Event.baseURL,event.Event.relativePath,alarm.fname, alarm.frameid, event.Event.Id, event.Event.imageMode, alarm.id, alarm_images, $index)" />
+ style="width: auto; height: auto;max-width: 100%;max-height: 170px" on-tap="showImage(event.Event.recordingURL, alarm.fname, alarm.frameid, event.Event.Id, event.Event.imageMode, alarm.id, alarm_images, $index)" />
</figure>
diff --git a/www/templates/log.html b/www/templates/log.html
index 0ad840d8..2884c4bb 100644
--- a/www/templates/log.html
+++ b/www/templates/log.html
@@ -4,7 +4,10 @@
&nbsp;
<button ng-class="selectOn? 'button button-icon button-clear ion-ios-copy':'button button-icon button-clear ion-ios-copy-outline'"
- ng-click="selectToggle()"></button>
+ ng-click="selectToggle()"></button> &nbsp;
+
+
+
<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>
@@ -13,10 +16,10 @@
<a class="button button-icon icon ion-arrow-swap" ng-href="" ng-click="flipLogs()"></a>
<a ng-if="logEntity == $root.appName" class="button button-icon icon ion-trash-a" ng-href="" ng-click="deleteLogs()"></a>
<div ng-if="$root.platformOS!='desktop'">
- <a class="button button-icon icon ion-email" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ <a class="button button-icon icon ion-email" ng-href="" ng-click="attachLogs()"> </a>
</div>
<div ng-if="$root.platformOS=='desktop'">
- <a class="button button-icon icon ion-android-download" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ <a class="button button-icon icon ion-android-download" ng-href="" ng-click="downloadLogs()"> </a>
</div>
</ion-nav-buttons>
<ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
@@ -31,11 +34,14 @@
<button class="button button-small button-stable icon ion-chevron-left" ng-click="changePage(1)">
</button>
<button class="button button-small button-stable icon ion-chevron-right" ng-click="changePage(-1)">
- </button>
+ </button><br/>
+ <b>ZoneMinder {{'kVersion'|translate}}: {{zmVersion}} </b><br/>
+
</div>
<div ng-if="logEntity==$root.appName">
- <b>{{$root.appName}} {{'kVersion'|translate}}: {{zmAppVersion}} ({{$root.platformOS}})</b>
+ <b>{{$root.appName}} {{'kVersion'|translate}}: {{zmAppVersion}} ({{$root.platformOS}})</b><br/>
+ <b>ZoneMinder {{'kVersion'|translate}}: {{zmVersion}} </b>
</div>
<div ng-if="selectOn" class="aside-1">{{'kLogsCopyPaste' | translate }}</div>
diff --git a/www/templates/moment.html b/www/templates/moment.html
index 45cdbd13..0f0f55c4 100644
--- a/www/templates/moment.html
+++ b/www/templates/moment.html
@@ -113,7 +113,7 @@
ng-click="togglePin(moment.Event.Id)"></button>
</div>
- <!--on-tap="showThumbnail(moment.Event.baseURL,moment.Event.MaxScoreFrameId)"-->
+
<figcaption ng-if="showIcons" class="normal-figcaption">&nbsp;{{moment.Event.humanizeTime}}
<span style="float:right">{{hourmin(moment.Event.StartTime)}}&nbsp;</span>
</figcaption>
diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html
index f039780a..72ed2baa 100644
--- a/www/templates/monitors-modal.html
+++ b/www/templates/monitors-modal.html
@@ -7,6 +7,7 @@
zooming="true" direction="xy" style="width: 100%;" overflow-scroll="false">
<!-- android needs this 100vh - otherwise max- does not work -->
<!-- -->
+
<div id="monitorimage" style="height: 100vh;" class="main">
<div ng-if="$root.authSession!='undefined'">
<div ng-if="!animationInProgress">
diff --git a/www/templates/monitors.html b/www/templates/monitors.html
index fbd1ce26..5da6b8db 100644
--- a/www/templates/monitors.html
+++ b/www/templates/monitors.html
@@ -48,8 +48,11 @@
<br /> {{'kStatus' | translate}}: {{monitor.Monitor.isRunningText}}
<br /> {{'kId' | translate}}: {{monitor.Monitor.Id}}
<br /> {{'kEventRecording' | translate}}: {{(monitor.Monitor.VideoWriter>0?'kVideo':'kImages') | translate}}
- <br />
- <br />
+ <br />{{'kMonStreamingURL' | translate}}: {{monitor.Monitor.streamingURL}}
+ <br />{{'kMonPortalURL' | translate}}: {{monitor.Monitor.baseURL}}
+ <br />{{'kMonRecordingURL' | translate}}: {{monitor.Monitor.controlURL}}
+ <br /> <br/>
+
</p>
<div style="float:right;">
<a class="button button-small icon icon-left icon ion-gear-a" href="" ng-click="changeConfig(monitor.Monitor.Name, monitor.Monitor.Id,monitor.Monitor.Enabled,monitor.Monitor.Function);">{{'kConfiguration'
@@ -61,7 +64,7 @@
</div>
</div>
<ion-item ng-show="!monitors.length">
- {{'kNoMonitors' | translate}}
+ {{monitorLoadStatus}}
</ion-item>
</ion-content>
</ion-view>
diff --git a/www/templates/state.html b/www/templates/state.html
index f5bff536..b534b693 100644
--- a/www/templates/state.html
+++ b/www/templates/state.html
@@ -4,8 +4,27 @@
<button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge"
ng-click="handleAlarms();" ng-if="$root.isAlarm"></button>
</ion-nav-buttons>
- <ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll >
<ion-refresher pulling-text="{{'kPullToReload' | translate}}..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher>
+
+ <ion-item>
+
+ <div>
+ <div class="row">
+ <div class="col text-center">
+ <a class="button button-small button-outline button-dark " ng-click="selectCustomState();" href="">{{'kChangeState'|translate}}</a>
+ <a class="button button-small button-outline button-dark " ng-click="controlZM('restart');" href="">{{'kRestart'
+ | translate}}</a>
+ <a class="button button-small button-outline button-dark" href="" ng-click="controlZM('stop');">{{'kStop'
+ | translate}}</a>
+ <a class="button button-small button-outline button-dark" ng-click="controlZM('start');" href="">{{'kStart'
+ | translate}}</a>
+ </div>
+ </div>
+ </div>
+ </ion-item>
+
+
<ion-list>
<ion-item>
<div class="row">
@@ -35,23 +54,77 @@
</div>
</div>
</ion-item>
+ </ion-list>
- <ion-item>
+
+
+ <div class="list" >
- <div>
- <div class="row">
- <div class="col text-center">
- <a class="button button-small button-outline button-dark " ng-click="selectCustomState();" href="">{{'kChangeState'|translate}}</a>
- <a class="button button-small button-outline button-dark " ng-click="controlZM('restart');" href="">{{'kRestart'
- | translate}}</a>
- <a class="button button-small button-outline button-dark" href="" ng-click="controlZM('stop');">{{'kStop'
- | translate}}</a>
- <a class="button button-small button-outline button-dark" ng-click="controlZM('start');" href="">{{'kStart'
- | translate}}</a>
- </div>
- </div>
+ <!-- Storage -->
+ <div class="item item-divider item-icon-left item-icon-right" ng-click="toggleStorage()">
+ <i class="icon" ng-class="showStorage? 'ion-minus':'ion-plus'"></i>
+ <i class="icon ion-social-buffer"></i>
+ {{'kStateStorage' | translate}}
</div>
- </ion-item>
- </ion-list>
+ <div ng-repeat = "store in storage">
+ <div class="item item-accordion item-divider" ng-show="showStorage">
+
+ {{store.Storage.Name}} ({{store.Storage.Id}})
+ </div> <!-- divider -->
+ <div class="item item-accordion" ng-show="showStorage">
+
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStatePath' | translate }}: {{store.Storage.Path}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateDiskUsed' | translate }}: {{ humanFileSize(store.Storage.DiskSpace,true)}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kScheme' | translate }}: {{ store.Storage.Scheme}}
+ </div>
+ <div ng-if="store.Storage.ServerId" class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateServer' | translate }}: {{ matchServer(store.Storage.ServerId)}}
+ </div>
+
+ </div> <!-- item -->
+ </div> <!-- repeat -->
+
+ <!-- server -->
+ <div class="item item-divider item-icon-left item-icon-right" ng-click="toggleServer()">
+ <i class="icon" ng-class="showServer? 'ion-minus':'ion-plus'"></i>
+ <i class="icon ion-monitor"></i>
+ {{'kStateServer' | translate}}
+ </div>
+ <div ng-repeat = "server in servers">
+ <div class="item item-accordion item-divider" ng-show="showServer">
+
+ {{server.Server.Name}} ({{server.Server.Id}})
+ </div> <!-- divider -->
+ <div class="item item-accordion" ng-show="showServer">
+
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateHost' | translate }}: {{server.Server.Hostname}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStatus' | translate }}: {{ server.Server.Status}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateCpuLoad' | translate }}: {{ server.Server.CpuLoad}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateTotalMem' | translate }}: {{ humanFileSize(server.Server.TotalMem, true)}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateFreeMem' | translate }}: {{ humanFileSize(server.Server.FreeMem, true)}}
+ </div>
+
+ </div> <!-- item -->
+ </div> <!-- repeat -->
+ </div> <!-- list ---->
+
+
+
+
+
</ion-content>
</ion-view>
diff --git a/www/templates/timeline-modal.html b/www/templates/timeline-modal.html
index 3ae0aba7..5b6c8694 100644
--- a/www/templates/timeline-modal.html
+++ b/www/templates/timeline-modal.html
@@ -27,7 +27,7 @@
<figure style="display:inline-block">
<figcaption class="smallnote">f:{{alarm.fid}} scr:{{alarm.score}} @ {{alarm.time}}</figcaption>
<img image-spinner-src="{{constructFrames(event,alarm)}}" style="width: auto; height: auto;max-width: 100%;max-height: 170px"
- on-tap="showImage(event.Event.baseURL,event.Event.relativePath,alarm.fname, alarm.fid, event.Event.Id, event.Event.imageMode, alarm.id)"
+ on-tap="showImage(event.Event.recordingURL,event.Event.relativePath,alarm.fname, alarm.fid, event.Event.Id, event.Event.imageMode, alarm.id)"
image-spinner-loader="lines" />