From 2dcd736caf0cfd3fc4ff0a2841d486c795d6661d Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sun, 23 Sep 2018 14:17:04 -0400 Subject: wekwebview fixes --- www/js/MontageCtrl.js | 4 ++-- www/js/app.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'www') diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index fefe2ddc..f4c77a80 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -334,7 +334,7 @@ angular.module('zmApp.controllers') progressCalled = true; loadCount++; - console.log ("loaded "+loadCount+" of "+positions.length); + // console.log ("loaded "+loadCount+" of "+positions.length); // if (layouttype) $timeout (function(){layout(pckry);},100); }); @@ -1828,7 +1828,7 @@ angular.module('zmApp.controllers') // NVRDataModel.regenConnKeys(); $scope.monitors = NVRDataModel.getMonitorsNow(); - console.log ("MONITORS:"+JSON.stringify($scope.monitors)); + //console.log ("MONITORS:"+JSON.stringify($scope.monitors)); $scope.MontageMonitors = angular.copy($scope.monitors); diff --git a/www/js/app.js b/www/js/app.js index 6287e09b..6ca4c9d0 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -1967,9 +1967,9 @@ angular.module('zmApp', [ $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; - if (window.cordova && window.cordova.plugins.Keyboard) { - // console.log("no keyboard"); - // cordova.plugins.Keyboard.disableScroll(true); + if (window.cordova ) { + console.log("------------->Keyboard foonone"); + //window.cordova.plugins.Keyboard.disableScroll(true); } if (window.StatusBar) { // org.apache.cordova.statusbar required @@ -2255,7 +2255,7 @@ angular.module('zmApp', [ }]); // If you do this, Allow Origin can't be * - //$httpProvider.defaults.withCredentials = true; + $httpProvider.defaults.withCredentials = true; $httpProvider.interceptors.push('timeoutHttpIntercept'); $ionicConfigProvider.navBar.alignTitle('center'); //$ionicConfigProvider.backButton.text('').icon('ion-chevron-left'); -- cgit v1.2.3 From 447d4aeaf3714b8d97765f74452d3cd59614cf28 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 24 Sep 2018 15:32:12 -0400 Subject: #709 remove native-trans (don't need to) --- www/js/app.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'www') diff --git a/www/js/app.js b/www/js/app.js index 6ca4c9d0..97132a21 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -25,7 +25,7 @@ angular.module('zmApp', [ 'com.2fdevs.videogular', 'com.2fdevs.videogular.plugins.controls', 'com.2fdevs.videogular.plugins.overlayplay', - 'ionic-native-transitions', + //'ionic-native-transitions', 'mgo-angular-wizard', 'pascalprecht.translate', 'uk.ac.soton.ecs.videogular.plugins.cuepoints', @@ -1380,7 +1380,7 @@ angular.module('zmApp', [ // First run in ionic //==================================================================== - .run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate, $localstorage) { + .run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, /* $ionicNativeTransitions,*/ $translate, $localstorage) { $ionicPlatform.ready(function () { @@ -2000,13 +2000,14 @@ angular.module('zmApp', [ // console.log("file logger"); - if (NVRDataModel.getLogin().disableNative) { + /*if (NVRDataModel.getLogin().disableNative) { NVRDataModel.log("Disabling native transitions..."); $ionicNativeTransitions.enable(false); } else { NVRDataModel.log("Enabling native transitions..."); $ionicNativeTransitions.enable(true); - } + }*/ + // At this stage, DataModel.init is not called yet // but I do need to know the language @@ -2230,7 +2231,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) { //$logProvider.debugEnabled(false); //$compileProvider.debugInfoEnabled(false); @@ -2265,10 +2266,11 @@ angular.module('zmApp', [ // so it messes up scrolldelegate zoom and possibly others //$ionicConfigProvider.scrolling.jsScrolling(false); $compileProvider.debugInfoEnabled(false); + $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/); - $ionicNativeTransitionsProvider.setDefaultOptions({ + /*$ionicNativeTransitionsProvider.setDefaultOptions({ duration: 250, - }); + }); */ $translateProvider.useStaticFilesLoader({ prefix: 'lang/locale-', -- cgit v1.2.3 From 19c228b23507c5f8ec9a2f468fb6b221eb361da5 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 24 Sep 2018 15:32:36 -0400 Subject: #709 changes to how photos are saved --- www/js/DataModel.js | 7 +-- www/js/EventModalCtrl.js | 124 +++++++++++++++++++++++++++++++-------------- www/js/MonitorModalCtrl.js | 78 +++++++++++++++++++++------- 3 files changed, 150 insertions(+), 59 deletions(-) (limited to 'www') diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 575f369c..24aabd69 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -9,10 +9,10 @@ angular.module('zmApp.controllers') - .service('NVRDataModel', ['$ionicPlatform', '$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$ionicNativeTransitions', '$translate', '$cordovaSQLite', + .service('NVRDataModel', ['$ionicPlatform', '$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$translate', '$cordovaSQLite', function ($ionicPlatform, $http, $q, $ionicLoading, $ionicBackdrop, $fileLogger, zm, $rootScope, $ionicContentBanner, $timeout, $cordovaPinDialog, - $ionicPopup, $localstorage, $state, $ionicNativeTransitions, $translate) { + $ionicPopup, $localstorage, $state, $translate) { var currentServerMultiPortSupported = false; @@ -694,7 +694,8 @@ angular.module('zmApp.controllers') if ($rootScope.platformOS == 'desktop') $state.go(state, p1, p2); else - $ionicNativeTransitions.stateGo(state, p1, p2); + $state.go(state, p1, p2); + // $ionicNativeTransitions.stateGo(state, p1, p2); }, // used when an empty server profile is created diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index cf77aa3d..eb78573a 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -3,7 +3,7 @@ /* jslint browser: true*/ /* global saveAs, cordova,StatusBar,angular,console,ionic, moment, Chart */ -angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups) { +angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', '$cordovaFile',function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups, $cordovaFile) { var playerReady = false; @@ -520,7 +520,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro noBackdrop: true, duration: 2000 }); - NVRDataModel.log("Error saving image: " + e.message); + //NVRDataModel.log("Error saving image: " + e.message); //console.log("***ERROR"); } @@ -880,37 +880,80 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro noBackdrop: true, duration: zm.httpTimeout }); + + var url = $scope.selectEventUrl; - NVRDataModel.log("saveNow: File path to grab is " + url); - - var img = new Image(); - img.onload = function () { - // console.log("********* ONLOAD"); - canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - - if ($rootScope.platformOS != "desktop") { - try { - - cordova.exec( - SaveSuccess, - SaveError, - 'Canvas2ImagePlugin', - 'saveImageDataToLibrary', [imageData] - ); - // carouselUtils.setStop(curState); - } catch (e) { - - SaveError(e.message); - // carouselUtils.setStop(curState); + NVRDataModel.log(">>saveNow: File path to grab is " + url); + + if ($rootScope.platformOS != 'desktop') { + + var album = 'zmNinja'; + NVRDataModel.debug ("Trying to save image to album: "+album); + cordova.plugins.photoLibrary.requestAuthorization( + function () { + //url = "https://picsum.photos/200/300/?random"; + + var fileTransfer = new FileTransfer(); + var urle = encodeURI(url); + var fname = "zmninja.jpg"; + + fileTransfer.download(urle, cordova.file.dataDirectory + fname, + function(entry){ + NVRDataModel.debug("local download complete: " + entry.toURL()); + NVRDataModel.debug("Now trying to move it to album"); + cordova.plugins.photoLibrary.saveImage(entry.toURL(), album, + function (cameraRollAssetId) { + SaveSuccess(); + $cordovaFile.removeFile(cordova.file.dataDirectory, fname) + .then ( + function () { + NVRDataModel.debug ("file removed from data directory"); + }, + function (e) { + NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e)); + } + ); + + + }, function (err) { + NVRDataModel.debug ("Saving error:" + JSON.stringify(err)); + SaveError(); + + }); + + }, + function(err) { console.log ("error downloading:"+JSON.stringify(err));}, false, {}); + + + + + // User gave us permission to his library, retry reading it! + }, + function (err) { + // User denied the access + NVRDataModel.debug ("Permission not granted"); + SaveError(); + }, // if options not provided, defaults to {read: true}. + + { + read: true, + write: true } - } else { + ); + + } + else { + var img = new Image(); + img.onload = function () { + // console.log("********* ONLOAD"); + canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + context = canvas.getContext('2d'); + context.drawImage(img, 0, 0); + + imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); + imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); var fname = $scope.relativePath + $scope.slides[$scope.slideIndex].img + ".png"; fname = fname.replace(/\//, "-"); @@ -920,15 +963,18 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro saveAs(blob, fname); SaveSuccess(); }); + }; + + try { + img.src = url; + console.log ("DESKTOP SAVING IMAGE SOURCE"); + } catch (e) { + SaveError(e.message); } - }; - try { - img.src = url; - // console.log ("SAVING IMAGE SOURCE"); - } catch (e) { - SaveError(e.message); } - } + + } + } $scope.reloadView = function () { @@ -2144,4 +2190,4 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro return number; } -}]); +}]); \ No newline at end of file diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js index 3d765aed..55e15f3a 100644 --- a/www/js/MonitorModalCtrl.js +++ b/www/js/MonitorModalCtrl.js @@ -3,7 +3,7 @@ /* jslint browser: true*/ /* global saveAs, cordova,StatusBar,angular,console,ionic, moment, imagesLoaded, chrome */ -angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', 'SecuredPopups', '$translate', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, SecuredPopups, $translate) { +angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', 'SecuredPopups', '$translate', '$cordovaFile', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, SecuredPopups, $translate, $cordovaFile) { $scope.animationInProgress = false; $scope.imageFit = true; @@ -1183,6 +1183,64 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ NVRDataModel.log("SavetoPhone:Trying to save image from " + url); + if ($rootScope.platformOS != 'desktop') { + var album = 'zmNinja'; + NVRDataModel.debug ("Trying to save image to album: "+album); + cordova.plugins.photoLibrary.requestAuthorization( + function () { + //url = "https://picsum.photos/200/300/?random"; + + var fileTransfer = new FileTransfer(); + var urle = encodeURI(url); + var fname = "zmninja.jpg"; + + fileTransfer.download(urle, cordova.file.dataDirectory + fname, + function(entry){ + NVRDataModel.debug("local download complete: " + entry.toURL()); + NVRDataModel.debug("Now trying to move it to album"); + cordova.plugins.photoLibrary.saveImage(entry.toURL(), album, + function (cameraRollAssetId) { + SaveSuccess(); + $cordovaFile.removeFile(cordova.file.dataDirectory, fname) + .then ( + function () { + NVRDataModel.debug ("file removed from data directory"); + }, + function (e) { + NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e)); + } + ); + + + }, function (err) { + NVRDataModel.debug ("Saving error:" + JSON.stringify(err)); + SaveError(); + + }); + + }, + function(err) { console.log ("error downloading:"+JSON.stringify(err));}, false, {}); + + + + + // User gave us permission to his library, retry reading it! + }, + function (err) { + // User denied the access + NVRDataModel.debug ("Permission not granted"); + SaveError(); + }, // if options not provided, defaults to {read: true}. + + { + read: true, + write: true + } + ); + } + + else { + var img = new Image(); img.onload = function () { // console.log("********* ONLOAD"); @@ -1195,21 +1253,6 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - if ($rootScope.platformOS != "desktop") { - try { - - cordova.exec( - SaveSuccess, - SaveError, - 'Canvas2ImagePlugin', - 'saveImageDataToLibrary', [imageData] - ); - } catch (e) { - - SaveError(e.message); - } - } else { - var fname = $scope.monitorName + "-" + moment().format('MMM-DD-YY_HH-mm-ss') + ".png"; canvas.toBlob(function (blob) { @@ -1217,7 +1260,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ SaveSuccess(); }); - } + }; try { img.src = url; @@ -1227,6 +1270,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ } } + } $scope.constructSingleStream = function () { -- cgit v1.2.3 From e520aecb5b1e3c3da74383f0c91e2e2f81d003f0 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 24 Sep 2018 16:48:40 -0400 Subject: #710 allow native video downloads --- www/js/EventModalCtrl.js | 221 ++++++++++++++++++++++++++-------------- www/templates/events-modal.html | 4 +- 2 files changed, 148 insertions(+), 77 deletions(-) (limited to 'www') diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index eb78573a..217025d4 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -509,7 +509,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $ionicLoading.show({ template: $translate.instant('kDone'), noBackdrop: true, - duration: 1000 + duration: 2000 }); NVRDataModel.debug("ModalCtrl:Photo saved successfuly"); } @@ -518,7 +518,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $ionicLoading.show({ template: $translate.instant('kErrorSave'), noBackdrop: true, - duration: 2000 + duration: 3000 }); //NVRDataModel.log("Error saving image: " + e.message); //console.log("***ERROR"); @@ -562,8 +562,20 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro function processSaveEventImageToPhone(onlyAlarms) { + + if ($scope.isSnapShot()) { + + + $scope.selectEventUrl = $scope.constructStream(); + NVRDataModel.debug ("just saving current snapshot:"+$scope.selectEventUrl); + saveNow(); + return; + + } + if ($scope.loginData.useNphZmsForEvents) { NVRDataModel.log("Use ZMS stream to save to phone"); + saveEventImageToPhoneZms(onlyAlarms); } else { @@ -874,34 +886,70 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro ] }); - function saveNow() { - $ionicLoading.show({ - template: $translate.instant('kSavingSnapshot') + "...", - noBackdrop: true, - duration: zm.httpTimeout - }); + + } - var url = $scope.selectEventUrl; - NVRDataModel.log(">>saveNow: File path to grab is " + url); + function saveNow() { - if ($rootScope.platformOS != 'desktop') { - - var album = 'zmNinja'; - NVRDataModel.debug ("Trying to save image to album: "+album); - cordova.plugins.photoLibrary.requestAuthorization( - function () { - //url = "https://picsum.photos/200/300/?random"; - - var fileTransfer = new FileTransfer(); - var urle = encodeURI(url); - var fname = "zmninja.jpg"; - - fileTransfer.download(urle, cordova.file.dataDirectory + fname, - function(entry){ - NVRDataModel.debug("local download complete: " + entry.toURL()); - NVRDataModel.debug("Now trying to move it to album"); - cordova.plugins.photoLibrary.saveImage(entry.toURL(), album, + var fname = "zmninja.jpg"; + var fn = "cordova.plugins.photoLibrary.saveImage"; + + $ionicLoading.show({ + template: $translate.instant('kPleaseWait') + "...", + noBackdrop: true, + //duration: zm.httpTimeout + }); + + if ($scope.defaultVideo !== undefined && $scope.defaultVideo != '') { + $scope.selectEventUrl = $scope.video_url; + fname = "zmNinja.mp4"; + fn = "cordova.plugins.photoLibrary.saveVideo"; + + NVRDataModel.debug ("-->Going to try and download "+$scope.selectEventUrl); + } + + + var url = $scope.selectEventUrl; + + + NVRDataModel.log(">>saveNow: File path to grab is " + url); + + if ($rootScope.platformOS != 'desktop') { + + var album = 'zmNinja'; + NVRDataModel.debug ("Trying to save image to album: "+album); + cordova.plugins.photoLibrary.requestAuthorization( + function () { + //url = "https://picsum.photos/200/300/?random"; + + var fileTransfer = new FileTransfer(); + var urle = encodeURI(url); + + + fileTransfer.onprogress = function (progressEvent) { + if (progressEvent.lengthComputable) { + + $timeout (function() { + var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100); + $ionicLoading.show({ + template: $translate.instant('kPleaseWait') + "... ("+perc+"%)", + noBackdrop: true, + //duration: zm.httpTimeout + }); + }); + + + } + }; + + fileTransfer.download(urle, cordova.file.dataDirectory + fname, + function(entry){ + NVRDataModel.debug("local download complete: " + entry.toURL()); + NVRDataModel.debug("Now trying to move it to album"); + + if (fname == "zmNinja.mp4") { + cordova.plugins.photoLibrary.saveVideo(entry.toURL(), album, function (cameraRollAssetId) { SaveSuccess(); $cordovaFile.removeFile(cordova.file.dataDirectory, fname) @@ -920,62 +968,85 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro SaveError(); }); - - }, - function(err) { console.log ("error downloading:"+JSON.stringify(err));}, false, {}); - - - - - // User gave us permission to his library, retry reading it! - }, - function (err) { - // User denied the access - NVRDataModel.debug ("Permission not granted"); - SaveError(); - }, // if options not provided, defaults to {read: true}. - - { - read: true, - write: true - } - ); + } + else { - } - else { - var img = new Image(); - img.onload = function () { - // console.log("********* ONLOAD"); - canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); + cordova.plugins.photoLibrary.saveImage(entry.toURL(), album, + function (cameraRollAssetId) { + SaveSuccess(); + $cordovaFile.removeFile(cordova.file.dataDirectory, fname) + .then ( + function () { + NVRDataModel.debug ("file removed from data directory"); + }, + function (e) { + NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e)); + } + ); + - var fname = $scope.relativePath + $scope.slides[$scope.slideIndex].img + ".png"; - fname = fname.replace(/\//, "-"); - fname = fname.replace(/\.jpg/, ''); + }, function (err) { + NVRDataModel.debug ("Saving error:" + JSON.stringify(err)); + SaveError(); + + }); + + } + + + }, + function(err) { console.log ("error downloading:"+JSON.stringify(err));}, false, {}); - canvas.toBlob(function (blob) { - saveAs(blob, fname); - SaveSuccess(); - }); - }; - try { - img.src = url; - console.log ("DESKTOP SAVING IMAGE SOURCE"); - } catch (e) { - SaveError(e.message); + + + // User gave us permission to his library, retry reading it! + }, + function (err) { + // User denied the access + NVRDataModel.debug ("Permission not granted"); + SaveError(); + }, // if options not provided, defaults to {read: true}. + + { + read: true, + write: true } - } + ); + } + else { + var img = new Image(); + img.onload = function () { + // console.log("********* ONLOAD"); + canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + context = canvas.getContext('2d'); + context.drawImage(img, 0, 0); + + imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); + imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); + + var fname = $scope.relativePath + $scope.slides[$scope.slideIndex].img + ".png"; + fname = fname.replace(/\//, "-"); + fname = fname.replace(/\.jpg/, ''); + + canvas.toBlob(function (blob) { + saveAs(blob, fname); + SaveSuccess(); + }); + }; + + try { + img.src = url; + console.log ("DESKTOP SAVING IMAGE SOURCE"); + } catch (e) { + SaveError(e.message); } + } - } + } $scope.reloadView = function () { NVRDataModel.log("Reloading view for modal view, recomputing rand"); diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html index 598bde23..6342ab98 100644 --- a/www/templates/events-modal.html +++ b/www/templates/events-modal.html @@ -155,9 +155,9 @@ -{{loginData.gapless? ('kOn' | translate): ('kOff' | translate)}} -
  • +
  • - +
  • -- cgit v1.2.3 From bc06e31f5ce9c5df538aa4be3987f4b82892d9f9 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Tue, 25 Sep 2018 11:16:26 -0400 Subject: fixed event frame offset + simplified plugin invocation #709 #710 --- www/js/EventModalCtrl.js | 46 ++++++++++++++++------------------------------ 1 file changed, 16 insertions(+), 30 deletions(-) (limited to 'www') diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index 217025d4..961db0b0 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -568,7 +568,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $scope.selectEventUrl = $scope.constructStream(); NVRDataModel.debug ("just saving current snapshot:"+$scope.selectEventUrl); - saveNow(); + saveNow("image"); return; } @@ -722,6 +722,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro //console.log("Your index is " + $scope.mycarousel.index); //console.log("Associated image is " + $scope.slides[$scope.mycarousel.index].img); + + + NVRDataModel.debug("ModalCtrl: SaveEventImageToPhone called"); var canvas, context, imageDataUrl, imageData; var loginData = NVRDataModel.getLogin(); @@ -733,9 +736,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro 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)); + url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + - "&fid=" + $scope.slides[$scope.mycarousel.index].id; + "&fid=" + $scope.slides[$scope.mycarousel.index -1].id; } if ($rootScope.authSession != 'undefined') { @@ -879,7 +886,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro text: '', type: 'button-positive button-small ion-checkmark-round', onTap: function (e) { - saveNow(); + saveNow("image"); } } @@ -890,7 +897,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } - function saveNow() { + function saveNow(t) { var fname = "zmninja.jpg"; var fn = "cordova.plugins.photoLibrary.saveImage"; @@ -901,7 +908,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro //duration: zm.httpTimeout }); - if ($scope.defaultVideo !== undefined && $scope.defaultVideo != '') { + if ($scope.defaultVideo !== undefined && $scope.defaultVideo != '' && t != "image") { $scope.selectEventUrl = $scope.video_url; fname = "zmNinja.mp4"; fn = "cordova.plugins.photoLibrary.saveVideo"; @@ -947,9 +954,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro function(entry){ NVRDataModel.debug("local download complete: " + entry.toURL()); NVRDataModel.debug("Now trying to move it to album"); + var pluginName = (fname == "zmNinja.mp4"? "saveVideo": "saveImage"); - if (fname == "zmNinja.mp4") { - cordova.plugins.photoLibrary.saveVideo(entry.toURL(), album, + + cordova.plugins.photoLibrary[pluginName](entry.toURL(), album, function (cameraRollAssetId) { SaveSuccess(); $cordovaFile.removeFile(cordova.file.dataDirectory, fname) @@ -968,30 +976,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro SaveError(); }); - } - else { - - cordova.plugins.photoLibrary.saveImage(entry.toURL(), album, - function (cameraRollAssetId) { - SaveSuccess(); - $cordovaFile.removeFile(cordova.file.dataDirectory, fname) - .then ( - function () { - NVRDataModel.debug ("file removed from data directory"); - }, - function (e) { - NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e)); - } - ); - - - }, function (err) { - NVRDataModel.debug ("Saving error:" + JSON.stringify(err)); - SaveError(); - }); - - } + }, -- cgit v1.2.3 From 74a4d75566708e78eb0aedae466008fb7c4e187e Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Tue, 25 Sep 2018 15:44:57 -0400 Subject: #709 #710 clean up video/image code, switch to "a download" for desktop --- www/js/EventModalCtrl.js | 248 +++++++++++++++++++++------------------- www/js/MonitorModalCtrl.js | 38 ++---- www/lang/locale-en.json | 3 + www/templates/events-modal.html | 14 ++- www/templates/events.html | 5 + 5 files changed, 161 insertions(+), 147 deletions(-) (limited to 'www') diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index 961db0b0..1894b96f 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -3,7 +3,7 @@ /* jslint browser: true*/ /* global saveAs, cordova,StatusBar,angular,console,ionic, moment, Chart */ -angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', '$cordovaFile',function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups, $cordovaFile) { +angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', '$cordovaFile', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups, $cordovaFile) { var playerReady = false; @@ -86,13 +86,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro NVRDataModel.debug("Setting playback to " + $scope.streamMode); - if ($rootScope.platformOS == 'desktop') { + if ($rootScope.platformOS == 'desktop') { window.addEventListener('keydown', keyboardHandler, true); } - // Keyboard handler for desktop versions - function keyboardHandler(evt) { + // Keyboard handler for desktop versions + function keyboardHandler(evt) { var handled = false; var keyCodes = { @@ -103,36 +103,31 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro ESC: 27, FITFILL_F: 70, - PLAY_SELECT:13 - + PLAY_SELECT: 13 + }; - $timeout (function () { + $timeout(function () { var keyCode = evt.keyCode; - - console.log (keyCode + " PRESSED"); + + console.log(keyCode + " PRESSED"); if (keyCode == keyCodes.ESC) { $scope.closeModal(); - } - else if (keyCode == keyCodes.LEFT) { - - $scope.jumpToEvent($scope.prevId, -1); - } - else if (keyCode == keyCodes.RIGHT) { + } else if (keyCode == keyCodes.LEFT) { + + $scope.jumpToEvent($scope.prevId, -1); + } else if (keyCode == keyCodes.RIGHT) { $scope.jumpToEvent($scope.nextId, 1); - } - else if (keyCode == keyCodes.FITFILL_F) { + } else if (keyCode == keyCodes.FITFILL_F) { $scope.scaleImage(); - } - else if (keyCode == keyCodes.PLAY_SELECT) { + } else if (keyCode == keyCodes.PLAY_SELECT) { if ($scope.isSnapShot() && !$scope.liveFeedMid) { $scope.convertSnapShotToStream(); - } - else { - NVRDataModel.debug ("Not in snapshot mode, ignoring"); + } else { + NVRDataModel.debug("Not in snapshot mode, ignoring"); } } @@ -528,6 +523,36 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro // streamReq.send( streamParms+"&command="+CMD_SEEK+"&offset="+offset ); }; + + $scope.saveEventVideoToPhoneWithPerms = function () { + + if ($rootScope.platformOS != 'android') { + saveNow(); + return; + } + + NVRDataModel.debug("EventModalCtrl: Permission checking for write"); + var permissions = cordova.plugins.permissions; + permissions.hasPermission(permissions.WRITE_EXTERNAL_STORAGE, checkPermissionCallback, null); + + function checkPermissionCallback(status) { + if (!status.hasPermission) { + SaveError("No permission to write to external storage"); + } + permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE, succ, err); + } + + function succ(s) { + saveNow(); + } + + function err(e) { + SaveError("Error in requestPermission"); + } + + } + + //----------------------------------------------------------------------- // Saves a snapshot of the monitor image to phone storage //----------------------------------------------------------------------- @@ -563,11 +588,12 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro function processSaveEventImageToPhone(onlyAlarms) { + if ($scope.isSnapShot()) { - + $scope.selectEventUrl = $scope.constructStream(); - NVRDataModel.debug ("just saving current snapshot:"+$scope.selectEventUrl); + NVRDataModel.debug("just saving current snapshot:" + $scope.selectEventUrl); saveNow("image"); return; @@ -599,13 +625,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro sendCommand('1', $scope.connKey). then(function (resp) { - console.log ("PAUSE ANSWER IS " + JSON.stringify(resp)); + console.log("PAUSE ANSWER IS " + JSON.stringify(resp)); if (resp && resp.data && resp.data.status) $scope.currentProgress.progress = resp.data.status.progress; - else - $scope.currentProgress.progress = 100; - + else + $scope.currentProgress.progress = 100; + // console.log ("STEP 0 progress is " + $scope.currentProgress.progress); $scope.slides = []; @@ -718,11 +744,12 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro // console.log ("________________UNUSED?_______________________"); var curState = carouselUtils.getStop(); carouselUtils.setStop(true); + var url; //console.log("Your index is " + $scope.mycarousel.index); //console.log("Associated image is " + $scope.slides[$scope.mycarousel.index].img); - + NVRDataModel.debug("ModalCtrl: SaveEventImageToPhone called"); @@ -730,19 +757,20 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro var loginData = NVRDataModel.getLogin(); // for alarms only - if (onlyAlarms) $scope.mycarousel.index = 0; - var url; + if (onlyAlarms || ($scope.defaultVideo !== undefined && $scope.defaultVideo != '')) + $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)); + console.log("SLIDES " + JSON.stringify($scope.slides)); + console.log("CAROUSEL " + JSON.stringify($scope.mycarousel)); url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + - "&fid=" + $scope.slides[$scope.mycarousel.index -1].id; + "&fid=" + $scope.slides[$scope.mycarousel.index - 1].id; } if ($rootScope.authSession != 'undefined') { @@ -893,7 +921,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro ] }); - + } @@ -905,7 +933,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $ionicLoading.show({ template: $translate.instant('kPleaseWait') + "...", noBackdrop: true, - //duration: zm.httpTimeout + duration: zm.httpTimeout }); if ($scope.defaultVideo !== undefined && $scope.defaultVideo != '' && t != "image") { @@ -913,84 +941,87 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro fname = "zmNinja.mp4"; fn = "cordova.plugins.photoLibrary.saveVideo"; - NVRDataModel.debug ("-->Going to try and download "+$scope.selectEventUrl); - } + } + NVRDataModel.debug("-->Going to try and download " + $scope.selectEventUrl); var url = $scope.selectEventUrl; - + NVRDataModel.log(">>saveNow: File path to grab is " + url); if ($rootScope.platformOS != 'desktop') { - + var album = 'zmNinja'; - NVRDataModel.debug ("Trying to save image to album: "+album); + NVRDataModel.debug("Trying to save image to album: " + album); cordova.plugins.photoLibrary.requestAuthorization( function () { //url = "https://picsum.photos/200/300/?random"; var fileTransfer = new FileTransfer(); var urle = encodeURI(url); - - + + fileTransfer.onprogress = function (progressEvent) { if (progressEvent.lengthComputable) { - $timeout (function() { + $timeout(function () { var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100); $ionicLoading.show({ - template: $translate.instant('kPleaseWait') + "... ("+perc+"%)", + template: $translate.instant('kPleaseWait') + "... (" + perc + "%)", noBackdrop: true, //duration: zm.httpTimeout }); }); - + } }; - fileTransfer.download(urle, cordova.file.dataDirectory + fname, - function(entry){ + fileTransfer.download(urle, cordova.file.dataDirectory + fname, + function (entry) { NVRDataModel.debug("local download complete: " + entry.toURL()); NVRDataModel.debug("Now trying to move it to album"); - var pluginName = (fname == "zmNinja.mp4"? "saveVideo": "saveImage"); - - - cordova.plugins.photoLibrary[pluginName](entry.toURL(), album, - function (cameraRollAssetId) { - SaveSuccess(); - $cordovaFile.removeFile(cordova.file.dataDirectory, fname) - .then ( - function () { - NVRDataModel.debug ("file removed from data directory"); - }, - function (e) { - NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e)); - } - ); - - - }, function (err) { - NVRDataModel.debug ("Saving error:" + JSON.stringify(err)); - SaveError(); - - }); - - - - - }, - function(err) { console.log ("error downloading:"+JSON.stringify(err));}, false, {}); + var pluginName = (fname == "zmNinja.mp4" ? "saveVideo" : "saveImage"); + + + cordova.plugins.photoLibrary[pluginName](entry.toURL(), album, + function (cameraRollAssetId) { + SaveSuccess(); + $cordovaFile.removeFile(cordova.file.dataDirectory, fname) + .then( + function () { + NVRDataModel.debug("file removed from data directory"); + }, + function (e) { + NVRDataModel.debug("could not delete temp file: " + JSON.stringify(e)); + } + ); + + + }, + function (err) { + NVRDataModel.debug("Saving error:" + JSON.stringify(err)); + SaveError(); + + }); + + + + + }, + function (err) { + console.log("error downloading:" + JSON.stringify(err)); + }, false, {}); + + - - // User gave us permission to his library, retry reading it! }, function (err) { // User denied the access - NVRDataModel.debug ("Permission not granted"); + NVRDataModel.debug("Permission not granted"); SaveError(); }, // if options not provided, defaults to {read: true}. @@ -1000,40 +1031,24 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } ); - } - else { - var img = new Image(); - img.onload = function () { - // console.log("********* ONLOAD"); - canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - - var fname = $scope.relativePath + $scope.slides[$scope.slideIndex].img + ".png"; - fname = fname.replace(/\//, "-"); - fname = fname.replace(/\.jpg/, ''); - - canvas.toBlob(function (blob) { - saveAs(blob, fname); - SaveSuccess(); - }); - }; + } else { + //desktop + + $ionicLoading.hide(); + + $rootScope.zmPopup = SecuredPopups.show('alert', { + title: $translate.instant('kNote'), + template: $translate.instant('kDownloadVideoImage')+"

    "+" "+$translate.instant('kDownload')+"
    ", + cancelText: $translate.instant('kDismiss'), + cancelType:'button-stable' + }); + - try { - img.src = url; - console.log ("DESKTOP SAVING IMAGE SOURCE"); - } catch (e) { - SaveError(e.message); - } - } } + } + $scope.reloadView = function () { NVRDataModel.log("Reloading view for modal view, recomputing rand"); $rootScope.modalRand = Math.floor((Math.random() * 100000) + 1); @@ -1269,7 +1284,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $scope.videoTime = function (s, c) { - // console.log ("VIDEO TIME WITH "+s+ " and "+c); + // console.log ("VIDEO TIME WITH "+s+ " and "+c); var a, o; if (NVRDataModel.getLogin().useLocalTimeZone) { a = moment.tz(s, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()); @@ -1287,10 +1302,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $scope.$on('modal.removed', function (e, m) { - if ($rootScope.platformOS == 'desktop') { - NVRDataModel.debug ("Removing keyboard handler"); + if ($rootScope.platformOS == 'desktop') { + NVRDataModel.debug("Removing keyboard handler"); window.removeEventListener('keydown', keyboardHandler, true); - + } NVRDataModel.debug("Deregistering broadcast handles"); @@ -1913,8 +1928,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro // console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length); - if (ts != data.event.Frame[i].TimeStamp) - { + if (ts != data.event.Frame[i].TimeStamp) { tempAlarms.push({ id: data.event.Frame[i].Id, @@ -1922,7 +1936,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro }); ts = data.event.Frame[i].TimeStamp; } - + } @@ -2247,4 +2261,4 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro return number; } -}]); \ No newline at end of file +}]); diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js index 55e15f3a..fe8f822d 100644 --- a/www/js/MonitorModalCtrl.js +++ b/www/js/MonitorModalCtrl.js @@ -1241,35 +1241,17 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ else { - var img = new Image(); - img.onload = function () { - // console.log("********* ONLOAD"); - canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - - var fname = $scope.monitorName + "-" + - moment().format('MMM-DD-YY_HH-mm-ss') + ".png"; - canvas.toBlob(function (blob) { - saveAs(blob, fname); - SaveSuccess(); - - }); - - }; - try { - img.src = url; - // console.log ("SAVING IMAGE SOURCE"); - } catch (e) { - SaveError(e.message); - - } + $ionicLoading.hide(); + + $rootScope.zmPopup = SecuredPopups.show('alert', { + title: $translate.instant('kNote'), + template: $translate.instant('kDownloadVideoImage')+"

    "+" "+$translate.instant('kDownload')+"
    ", + okText: $translate.instant('kDismiss'), + okType:'button-stable' + }); + } + } diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json index fcdd8ecc..a716f76e 100644 --- a/www/lang/locale-en.json +++ b/www/lang/locale-en.json @@ -75,7 +75,10 @@ "kDiscoveringAPI" :"discovering api", "kDiscoveringCGI" :"discovering cgi", "kDiscoveringPortal" :"discovering portal", + "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", "kEmailNotConfigured" :"Email not configured", "kEnable24hr" :"enable 24hr time format", "kEnableDebug" :"Enable debug logs", diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html index 6342ab98..1f168b69 100644 --- a/www/templates/events-modal.html +++ b/www/templates/events-modal.html @@ -155,11 +155,21 @@ -{{loginData.gapless? ('kOn' | translate): ('kOff' | translate)}}
  • -
  • - +
  • + + + +
  • + + + +
  • +
  • + +
  • diff --git a/www/templates/events.html b/www/templates/events.html index c517966f..291762a4 100644 --- a/www/templates/events.html +++ b/www/templates/events.html @@ -78,12 +78,17 @@ {{humanize(event.Event.Length)}}
    + + +
  • - +
  • - +
  • -- cgit v1.2.3 From 50d51dbeb01f88fcd93675f5422a823bd3b27035 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sun, 30 Sep 2018 17:39:39 -0400 Subject: remove backdrop in loaders --- www/js/DataModel.js | 6 +++--- www/js/EventCtrl.js | 2 +- www/js/TimelineCtrl.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'www') diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 5b49aa88..05a77294 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -2044,7 +2044,7 @@ angular.module('zmApp.controllers') $ionicLoading.show({ template: $translate.instant('kLoadingMonitors'), animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, duration: zm.loadingTimeout, maxWidth: 200, showDelay: 0 @@ -2533,7 +2533,7 @@ angular.module('zmApp.controllers') $ionicLoading.show({ template: $translate.instant('kCalcEventSize') + '...', animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, duration: zm.loadingTimeout, maxWidth: 200, showDelay: 0 @@ -2585,7 +2585,7 @@ angular.module('zmApp.controllers') $ionicLoading.show({ template: loadingStr, animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, maxWidth: 200, showDelay: 0, duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 2b5ef82d..0d2ae4ab 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -2658,7 +2658,7 @@ angular.module('zmApp.controllers') $ionicLoading.show({ template: $translate.instant('kSearchCancelled'), animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, duration: 2000, maxWidth: 200, showDelay: 0 diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js index 250fda9e..b612468a 100644 --- a/www/js/TimelineCtrl.js +++ b/www/js/TimelineCtrl.js @@ -1026,7 +1026,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla $ionicLoading.show({ template: $translate.instant('kLoadingGraph') + "...", animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, maxWidth: 200, showDelay: 0, duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times @@ -1398,7 +1398,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla /*$ionicLoading.show({ template: "", animation: 'fade-in', - showBackdrop: true, + showBackdrop: false, maxWidth: 200, showDelay: 0, duration: 1500, -- cgit v1.2.3 From f3d3c53453b0274efd29fa8e7844d08aa2e2063a Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 1 Oct 2018 12:38:29 -0400 Subject: typo --- www/js/EventServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'www') diff --git a/www/js/EventServer.js b/www/js/EventServer.js index fae8b307..e142dc8d 100644 --- a/www/js/EventServer.js +++ b/www/js/EventServer.js @@ -150,7 +150,7 @@ angular.module('zmApp.controllers') if (timeElapsedSinceResume == -1) { // so we display error - timeElapsedSinceResume = moment().subtract('1', hour); + timeElapsedSinceResume = moment().subtract('1', 'hour'); } var duration = moment.duration(moment().diff(timeElapsedSinceResume)).asSeconds().toFixed(1); -- cgit v1.2.3 From 62c77d57097915a6051132b18cd767bb356323e5 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 8 Oct 2018 11:19:26 -0400 Subject: don't cycle if you only have one or less --- www/js/MonitorModalCtrl.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'www') diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js index 7c363b7a..cc110197 100644 --- a/www/js/MonitorModalCtrl.js +++ b/www/js/MonitorModalCtrl.js @@ -897,10 +897,20 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ function moveToMonitor(m, d) { - $scope.animationInProgress = true; + if ($scope.isZoneEdit) { NVRDataModel.log("Not cycling, as you are editing zones"); + return; + } + + if ($scope.monitors.length <= 1) { + NVRDataModel.log("Not cycling, as you only have at most 1 monitors"); + return; } + + + + $scope.animationInProgress = true; var curstate = $ionicHistory.currentStateName(); var found = 0; var mid; -- cgit v1.2.3 From ba440af714d5471a94e541c5af2853ff2427ee6f Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 8 Oct 2018 11:24:34 -0400 Subject: can't call getPathZms as API is not stored --- www/js/WizardCtrl.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'www') diff --git a/www/js/WizardCtrl.js b/www/js/WizardCtrl.js index e6cfed4c..bc5c3935 100644 --- a/www/js/WizardCtrl.js +++ b/www/js/WizardCtrl.js @@ -198,10 +198,13 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$ var urls = [a1, a2, a3, a4, a5]; - NVRDataModel.getPathZms() // what does ZM have stored in PATH_ZMS? + // can't use getPathZms as loginData is not inited yet + $http.get ($scope.wizard.apiURL+"/configs/viewByName/ZM_PATH_ZMS.json") + //NVRDataModel.getPathZms() // what does ZM have stored in PATH_ZMS? .then(function (data) { // remove zms or nph-zms - var path = data.trim(); + var str = data.data.config.Value; + var path = str.trim(); path = path.replace("/nph-zms", ""); path = path.replace("/zms", ""); urls.push(baseUri.trim() + path); -- cgit v1.2.3 From 022a9f5f5801f1c661499f19073f88209891f10d Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 8 Oct 2018 11:24:54 -0400 Subject: avoid idiotic wkwebview zoom on input --- www/css/style.css | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'www') diff --git a/www/css/style.css b/www/css/style.css index 175a8748..2d8650d7 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -1843,4 +1843,15 @@ body { .platform-ios.platform-cordova:not(.fullscreen) .has-subheader { top: 88px !important; -} \ No newline at end of file +} + + + + /* @media screen and (-webkit-min-device-pixel-ratio:0) { + select, + textarea, + input { + font-size: 16px; + } + }*/ + \ No newline at end of file -- cgit v1.2.3 From 881a3b160a1320f2318712c1063e40775236099f Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 8 Oct 2018 11:26:07 -0400 Subject: rework to use native browser websockets. angular-websocket doesn't seem to work with WK --- www/js/EventServer.js | 373 +++++++++++++++++++++----------------- www/js/EventServerSettingsCtrl.js | 10 +- 2 files changed, 211 insertions(+), 172 deletions(-) (limited to 'www') diff --git a/www/js/EventServer.js b/www/js/EventServer.js index e142dc8d..f252cca4 100644 --- a/www/js/EventServer.js +++ b/www/js/EventServer.js @@ -16,65 +16,174 @@ angular.module('zmApp.controllers') var localNotificationId = 0; var pushInited = false; var isTimerOn = false; + //-------------------------------------------------------------------------- // called when the websocket is opened //-------------------------------------------------------------------------- - function openHandshake() { - NVRDataModel.log("Inside openHandshake"); - var loginData = NVRDataModel.getLogin(); - if (loginData.isUseEventServer == false || loginData.eventServer == "") { - NVRDataModel.log("openHandShake: no event server"); - return; - } - - if (typeof ws == 'undefined') { - NVRDataModel.debug("websocket is undefined, need to create ws before I can sent auth"); - ws = $websocket(loginData.eventServer, { - reconnectIfNotNormalClose: false + function handleOpen(event) { + + NVRDataModel.debug ("WebSocket open called with:"+JSON.stringify(event.data)); + var loginData = NVRDataModel.getLogin(); + NVRDataModel.log("openHandshake: Websocket open, sending Auth"); + sendMessage("auth", + { + user: loginData.username, + password: loginData.password }); - // ws.onOpen(openHandshake); - // return; - } - NVRDataModel.log("openHandshake: Websocket open, sending Auth"); - ws.send({ - event: 'auth', - data: { - user: loginData.username, - password: loginData.password + + if ($rootScope.apnsToken != '') { + var plat = $ionicPlatform.is('ios') ? 'ios' : 'android'; + var ld = NVRDataModel.getLogin(); + var pushstate = "enabled"; + if (ld.disablePush == true) + pushstate = "disabled"; + + NVRDataModel.debug("openHandShake: state of push is " + pushstate); + // let's do this only if disabled. If enabled, I suppose registration + // will be called? + //if (ld.disablePush) + //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring); + + sendMessage ("push", { + type: 'token', + platform: plat, + token: $rootScope.apnsToken, + monlist: $rootScope.monstring, + intlist: $rootScope.intstring, + state: pushstate + + }); } + + } - }); + function handleClose(event) { - if ($rootScope.apnsToken != '') { - var plat = $ionicPlatform.is('ios') ? 'ios' : 'android'; - var ld = NVRDataModel.getLogin(); - var pushstate = "enabled"; - if (ld.disablePush == true) - pushstate = "disabled"; + + console.log ("*********** WEBSOCKET CLOSE CALLED WITH "+JSON.stringify(event.data)); - NVRDataModel.debug("openHandShake: state of push is " + pushstate); - // let's do this only if disabled. If enabled, I suppose registration - // will be called? - //if (ld.disablePush) - if (1) { - //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring); - ws.send({ - event: 'push', - data: { - type: 'token', - platform: plat, - token: $rootScope.apnsToken, - monlist: $rootScope.monstring, - intlist: $rootScope.intstring, - state: pushstate - } - }); - } + + if (!isTimerOn) { + NVRDataModel.log("Will try to reconnect in 10 sec.."); + $timeout(init, 10000); + isTimerOn = true; } + } + + function handleError(event) { + + console.log ("*********** WEBSOCKET CLOSE CALLED WITH "+JSON.stringify(event.data)); + //return; + if (!isTimerOn) { + NVRDataModel.log("Will try to reconnect in 10 sec.."); + $timeout(init, 10000); + isTimerOn = true; + } + } + + function handleMessage(smsg) { + //NVRDataModel.debug ("Websocket received message:"+smsg); + str = JSON.parse(smsg); + NVRDataModel.debug("Real-time event: " + JSON.stringify(str)); + + + + // Error messages + if (str.status != 'Success') { + NVRDataModel.log("Event Error: " + JSON.stringify(str)); + + if (str.reason == 'APNSDISABLED') { + console.log ("FORCE CLOSING"); + ws.close(); + NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000); + $rootScope.apnsToken = ""; + } + + } + + if (str.status == 'Success' && (str.event == 'auth')) { + if (str.version == undefined) + str.version = "0.1"; + if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) { + $rootScope.zmPopup = $ionicPopup.alert({ + title: $translate.instant('kEventServerVersionTitle'), + template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " + + zm.minEventServerVersion, + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), + }); + } + + } + + if (str.status == 'Success' && str.event == 'alarm') // new events + { + + var localNotText; + // ZMN specific hack for Event Server + if (str.supplementary != 'true') { + new Audio('sounds/blop.mp3').play(); + localNotText = ""; + $rootScope.isAlarm = 1; + + // Show upto a max of 99 when it comes to display + // so aesthetics are maintained + if ($rootScope.alarmCount == "99") { + $rootScope.alarmCount = "99+"; + } + if ($rootScope.alarmCount != "99+") { + $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString(); + } + + } else { + NVRDataModel.debug("received supplementary event information over websockets"); + } + var eventsToDisplay = []; + var listOfMonitors = []; + for (var iter = 0; iter < str.events.length; iter++) { + // lets stack the display so they don't overwrite + //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")"); + var txt = str.events[iter].EventId; + if (str.events[iter].Cause) { + txt = str.events[iter].Cause; + } + eventsToDisplay.push(str.events[iter].Name + ": " + txt); + localNotText = localNotText + str.events[iter].Name + ": " + txt + ","; + listOfMonitors.push(str.events[iter].MonitorId); + + } + localNotText = localNotText.substring(0, localNotText.length - 1); + + // if we are in background, do a local notification, else do an in app display + if (!NVRDataModel.isBackground()) { + + //emit alarm details - this is when received over websockets + $rootScope.$broadcast('alarm', { + message: listOfMonitors + }); + + if (str.supplementary != 'true') { + + NVRDataModel.debug("App is in foreground, displaying banner"); + if (eventsToDisplay.length > 0) { + + if (eventsToDisplay.length == 1) { + //console.log("Single Display: " + eventsToDisplay[0]); + NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000); + } else { + NVRDataModel.displayBanner('alarm', eventsToDisplay, + 5000, 5000 * eventsToDisplay.length); + } + + } + } + } + } + } @@ -83,130 +192,69 @@ angular.module('zmApp.controllers') //-------------------------------------------------------------------------- function init() { - - $rootScope.isAlarm = 0; $rootScope.alarmCount = "0"; - isTimerOn = false; - var d = $q.defer(); - var loginData = NVRDataModel.getLogin(); - //console.log ("INIT GOT " + JSON.stringify(loginData)); - if (loginData.isUseEventServer == false || !loginData.eventServer) { NVRDataModel.log("No Event Server present. Not initializing"); d.reject("false"); return d.promise; } - //if (!$rootScope.apnsToken) - if (!pushInited) pushInit(); - - // console.log ("WS TYPEOF="+ typeof ws); - // console.log ("WS="+JSON.stringify(ws)); - /*if (typeof ws !== 'undefined') - { - NVRDataModel.debug("websocket already initialized --Forcing close"); - ws.close(true); - ws=undefined; - - }*/ - NVRDataModel.log("Initializing Websocket with URL " + loginData.eventServer); - /* ws = $websocket.$new( - { - url: loginData.eventServer, - reconnect: true, - reconnectInterval: 60000, - lazy: true - });*/ - - ws = $websocket(loginData.eventServer, { - reconnectIfNotNormalClose: false - }); - ws.onOpen(openHandshake); + - initCalled = true; - // Transmit auth information to server - // ws.$on('$open', openHandshake); + + ws = new WebSocket(loginData.eventServer); - if (ws) { - ws.onErrorCallbacks = []; - NVRDataModel.debug("Removing error handlers for websocket"); - } - NVRDataModel.debug("Setting up websocket error handler"); - //ws.$on('$error', function(e) - ws.onError(function (e) { + ws.onopen = function (event) { + handleOpen(event); + if (!pushInited) { NVRDataModel.debug ("Initializing FCM push"); pushInit();} + d.resolve("true"); + return; + }; - NVRDataModel.debug("Websocket Errorhandler called"); + ws.onclose = function (event) { + handleClose(event); + d.reject ("error"); + return; + + }; - var timeElapsedSinceResume = NVRDataModel.getTimeSinceResumed(); + ws.onerror = function (event) { + handleError(event); + d.reject ("error"); + return; + - if (timeElapsedSinceResume == -1) { - // so we display error - timeElapsedSinceResume = moment().subtract('1', 'hour'); - } - - var duration = moment.duration(moment().diff(timeElapsedSinceResume)).asSeconds().toFixed(1); - - NVRDataModel.debug(">> time since resumed is " + duration + " seconds"); - if (duration > zm.waitTimeTillResume) { + + }; - $timeout(function () { - var eserr = $translate.instant('kEventServerConnErr'); - NVRDataModel.displayBanner('error', [eserr]); - }, 1000); // leave time for transitions - - } else { - NVRDataModel.debug("ES error happened " + timeElapsedSinceResume + " secs after resume, maybe fake, lets wait..."); - } + ws.onmessage = function (event) { + + var smsg = event.data; + handleMessage (smsg); - /*if (typeof ws !== 'undefined'){ - NVRDataModel.debug ("-->Forcing socket close"); - ws.close(true); + + }; - }*/ - ws = undefined; - NVRDataModel.log("Will try to reconnect in 10 sec.."); - if (!isTimerOn) { - $timeout(init, 10000); - isTimerOn = true; - } - - - //console.log ("VALUE TIME " + lastEventServerCheck); - //console.log ("NOW TIME " + Date.now()); - }); - - ws.onClose(function () - // ws.$on('$close', function() - { - NVRDataModel.log("Websocket closed"); - ws = undefined; - - var ld = NVRDataModel.getLogin(); + - /* if (ld.isUseEventServer && !isTimerOn) { - // this means remote error, because zmN still - // wants it on - $timeout ( init, 10000 ); - isTimerOn = true; - }*/ - }); + - // Handles responses back from ZM ES + /* ws.onMessage(function (str) // ws.$on('$message', function(str) @@ -309,7 +357,11 @@ angular.module('zmApp.controllers') } //end of success handler }); - d.resolve("true"); + + + */ + + return (d.promise); } @@ -323,9 +375,11 @@ angular.module('zmApp.controllers') NVRDataModel.log("Clearing error/close cbk, disconnecting and deleting Event Server socket..."); // ws.$close(); - ws.onErrorCallbacks = []; - ws.onCloseCallbacks = []; - ws.close(true); // force close + + + ws.onmessage = null; + + ws.close(); // ws.$un('open'); // ws.$un('close'); // ws.$un('message'); @@ -354,38 +408,17 @@ angular.module('zmApp.controllers') } // console.log (">>>>>>>>>>>>>>>>>EVENT SERVER SENDING: type="+type+" DATA="+JSON.stringify(obj)); - ws.send({ + + var msg = { 'event': type, 'data': obj - }); + }; - /*if (ws.$status() == ws.$CLOSED) - { - NVRDataModel.log("Websocket was closed, trying to re-open"); - ws.$un('$open'); - //ws.$on ('$open', openHandshake); - ws.$open(); - - ws.$on('$open', openHandshake, function() - { - - //console.log(" sending " + type + " " + - // JSON.stringify(obj)); - //console.log("sending " + type + " " + JSON.stringify(obj)); - ws.$emit(type, obj); - - ws.$un('$open'); - ws.$on('$open', openHandshake); - - }); - - } - else* - { - ws.send(type, obj); - // console.log("sending " + type + " " + JSON.stringify(obj)); - }*/ + var jmsg = JSON.stringify(msg); + NVRDataModel.debug ("~~~~ sendMessage: Sending->"+jmsg); + ws.send(jmsg); + } //-------------------------------------------------------------------------- diff --git a/www/js/EventServerSettingsCtrl.js b/www/js/EventServerSettingsCtrl.js index 24928007..a4ce03b0 100644 --- a/www/js/EventServerSettingsCtrl.js +++ b/www/js/EventServerSettingsCtrl.js @@ -212,7 +212,8 @@ EventServer.sendMessage("control", { type: 'filter', monlist: monstring, - intlist: intervalstring + intlist: intervalstring, + token: $rootScope.apnsToken, }, 1); if ($rootScope.apnsToken != "") @@ -231,7 +232,12 @@ } - }); + }, + function (err) { + NVRDataModel.debug("Event Server init failed"); + } + + ); } // no event server configured/enabled else { -- cgit v1.2.3 From bace2be553e3175ba7a47024c8352e43d285b620 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Mon, 8 Oct 2018 12:14:32 -0400 Subject: log cleanup, wait for eventserver init before sending messages --- www/index.html | 3 ++- www/js/DataModel.js | 10 +++++++--- www/js/FirstUseCtrl.js | 7 +++++-- www/js/LoginCtrl.js | 43 +++++++++++++++++++++++++------------------ www/js/MenuController.js | 27 +++++++++++++-------------- www/js/app.js | 4 ++-- 6 files changed, 54 insertions(+), 40 deletions(-) (limited to 'www') diff --git a/www/index.html b/www/index.html index 4d8d2332..7aa77593 100644 --- a/www/index.html +++ b/www/index.html @@ -5,7 +5,7 @@ - + @@ -13,6 +13,7 @@ + diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 05a77294..a87f7765 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -1142,13 +1142,13 @@ angular.module('zmApp.controllers') } - console.log("INIT SIMUL=" + loginData.disableSimulStreaming); - console.log("INIT PLATFORM IS=" + $rootScope.platformOS); + //console.log("INIT SIMUL=" + loginData.disableSimulStreaming); + //console.log("INIT PLATFORM IS=" + $rootScope.platformOS); if (typeof loginData.disableSimulStreaming == 'undefined') { loginData.disableSimulStreaming = ($rootScope.platformOS == 'ios') ? true : false; - console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming); + //console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming); } @@ -1870,12 +1870,16 @@ angular.module('zmApp.controllers') //-------------------------------------------------------------------------- getPathZms: function () { var d = $q.defer(); + + var apiurl = loginData.apiurl; var myurl = apiurl + '/configs/viewByName/ZM_PATH_ZMS.json'; debug("Config URL for ZMS PATH is:" + myurl); $http.get(myurl) .then(function (data) { + data = data.data; + //console.log (">>>> GOT: "+JSON.stringify(data)); configParams.ZM_PATH_ZMS = data.config.Value; d.resolve(configParams.ZM_PATH_ZMS); return (d.promise); diff --git a/www/js/FirstUseCtrl.js b/www/js/FirstUseCtrl.js index 89f45e96..1ad42e9c 100644 --- a/www/js/FirstUseCtrl.js +++ b/www/js/FirstUseCtrl.js @@ -18,8 +18,11 @@ angular.module('zmApp.controllers').controller('zmApp.FirstUseCtrl', ['$scope', // if (window.cordova) { - cordova.plugins.certificates.trustUnsecureCerts(true); - NVRDataModel.log(">>>>>Accepting all certificates, since its first use"); + cordova.plugin.http.setSSLCertMode('nocheck', function() { + NVRDataModel.debug('--> First use -> SSL is permissive, will allow any certs for now. You can change it later.'); + }, function() { + console.log('-->First Use -> Error setting SSL permissive'); + }); } diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js index fc63ff06..d2dfe899 100644 --- a/www/js/LoginCtrl.js +++ b/www/js/LoginCtrl.js @@ -583,23 +583,23 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r if ($rootScope.platformOS != 'desktop') { if ($scope.loginData.isUseBasicAuth) { - debug ("Cordova HTTP: configuring basic auth"); + NVRDataModel.debug ("Cordova HTTP: configuring basic auth"); cordova.plugin.http.useBasicAuth($scope.loginData.basicAuthUser, $scope.loginData.basicAuthPassword); } if (!$scope.loginData.enableStrictSSL) { //alert("Enabling insecure SSL"); - log(">>>> Disabling strict SSL checking (turn off in Dev Options if you can't connect)"); + NVRDataModel.log(">>>> Disabling strict SSL checking (turn off in Dev Options if you can't connect)"); cordova.plugin.http.setSSLCertMode('nocheck', function() { - debug('--> SSL is permissive, will allow any certs. Use at your own risk.'); + NVRDataModel.debug('--> SSL is permissive, will allow any certs. Use at your own risk.'); }, function() { console.log('-->Error setting SSL permissive'); }); } else { - log(">>>> Enabling strict SSL checking (turn off in Dev Options if you can't connect)"); + NVRDataModel.log(">>>> Enabling strict SSL checking (turn off in Dev Options if you can't connect)"); } @@ -649,21 +649,28 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r oldName = $scope.loginData.serverName; if ($scope.loginData.isUseEventServer) { - EventServer.init(); - if ($rootScope.apnsToken && $scope.loginData.disablePush != true) { - NVRDataModel.log("Making sure we get push notifications"); - EventServer.sendMessage('push', { - type: 'token', - platform: $rootScope.platformOS, - token: $rootScope.apnsToken, - state: "enabled" - }, 1); - } - EventServer.sendMessage("control", { - type: 'filter', - monlist: $scope.loginData.eventServerMonitors, - intlist: $scope.loginData.eventServerInterval + EventServer.init() + .then (function (succ) { + if ($rootScope.apnsToken && $scope.loginData.disablePush != true) { + NVRDataModel.log("Making sure we get push notifications"); + EventServer.sendMessage('push', { + type: 'token', + platform: $rootScope.platformOS, + token: $rootScope.apnsToken, + state: "enabled" + }, 1); + } + EventServer.sendMessage("control", { + type: 'filter', + monlist: $scope.loginData.eventServerMonitors, + intlist: $scope.loginData.eventServerInterval, + token: $rootScope.apnsToken + }); + }, + function (err) { + NVRDataModel.log ("Event server init failed"); }); + } diff --git a/www/js/MenuController.js b/www/js/MenuController.js index 52ab51ac..d9d4d114 100644 --- a/www/js/MenuController.js +++ b/www/js/MenuController.js @@ -111,21 +111,20 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io if (loginData.isUseEventServer) { - EventServer.init(); - if ($rootScope.apnsToken && loginData.disablePush != true) { - NVRDataModel.log("Making sure we get push notifications"); - EventServer.sendMessage('push', { - type: 'token', - platform: $rootScope.platformOS, - token: $rootScope.apnsToken, - state: "enabled" - }, 1); - } - EventServer.sendMessage("control", { - type: 'filter', - monlist: loginData.eventServerMonitors, - intlist: loginData.eventServerInterval + EventServer.init() + .then (function (succ) { + EventServer.sendMessage("control", { + type: 'filter', + monlist: loginData.eventServerMonitors, + intlist: loginData.eventServerInterval, + token: $rootScope.apnsToken + }); + }, + function (err) { + NVRDataModel.debug ("EventServer init failed"); }); + + } diff --git a/www/js/app.js b/www/js/app.js index bcfe67c0..b3553664 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -2302,7 +2302,7 @@ angular.module('zmApp', [ method = arguments[0].method; var isOutgoingRequest = /^(http|https):\/\//.test(url); if (window.cordova && isOutgoingRequest) { - // console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)); + //console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)); var d = $q.defer(); var options = { method: method, @@ -2328,7 +2328,7 @@ angular.module('zmApp', [ } catch (e) { - // console.log ("*** Native HTTP response: JSON parsing failed for "+url+", returning text"); + //console.log ("*** Native HTTP response: JSON parsing failed for "+url+", returning text"); d.resolve({"data":succ.data}); return d.promise; } -- cgit v1.2.3 From adb3927065bc2908f3dc1e88922db5ec37762684 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Tue, 9 Oct 2018 11:32:06 -0400 Subject: updated eventId only if present in response --- www/js/EventModalCtrl.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'www') diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js index 68d378dc..0e6d6be7 100644 --- a/www/js/EventModalCtrl.js +++ b/www/js/EventModalCtrl.js @@ -403,13 +403,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } }) .then(function (resp) { - // NVRDataModel.debug ("processEvent success:"+JSON.stringify(resp)); + //NVRDataModel.debug ("processEvent success:"+JSON.stringify(resp)); resp = resp.data; if (resp.result == "Ok") { if (resp.status) $scope.currentProgress.progress = resp.status.progress; - if (resp.status) $scope.eventId = resp.status.event; + if (resp.status && resp.status.event) $scope.eventId = resp.status.event; $scope.d_eventId = $scope.eventId; if (resp.status) $scope.currentRate = resp.status.rate; @@ -1067,8 +1067,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro $scope.constructStream = function (monitor) { + //console.log ("STREAMSTATE ="+currentStreamState); if ($scope.animationInProgress) return ""; - var stream = ""; // eventId gets populated when prepareModal completes if (currentStreamState == streamState.STOPPED || !$scope.eventId) { @@ -1092,7 +1092,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro } //console.log ($scope.connKey ); - // console.log ("STREAM="+stream); + //console.log ("STREAM="+stream); //console.log ("EID="+$scope.eventId); if ($rootScope.basicAuthToken && stream) stream += "&basicauth=" + $rootScope.basicAuthToken; return stream; -- cgit v1.2.3 From 5f89cfff2904b65d8adacb05b7edc8e9e2f356ff Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 10 Oct 2018 09:10:15 -0400 Subject: bump min ES to 2 --- www/js/app.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'www') diff --git a/www/js/app.js b/www/js/app.js index b3553664..fe42b264 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -44,7 +44,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: '1.0', + minEventServerVersion: '2.0', castAppId: 'BA30FB4C', alarmFlashTimer: 20000, // time to flash alarm gcmSenderId: '710936220256', @@ -2302,7 +2302,8 @@ angular.module('zmApp', [ method = arguments[0].method; var isOutgoingRequest = /^(http|https):\/\//.test(url); if (window.cordova && isOutgoingRequest) { - //console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)); + + var d = $q.defer(); var options = { method: method, @@ -2311,7 +2312,7 @@ angular.module('zmApp', [ timeout: arguments[0].timeout, responseType: arguments[0].responseType }; - + 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 @@ -2336,7 +2337,7 @@ angular.module('zmApp', [ } }, function (err) { - //console.log ("*** Inside native HTTP error: "+JSON.stringify(err)); + console.log ("*** Inside native HTTP error: "+JSON.stringify(err)); d.reject(err); return d.promise; -- cgit v1.2.3 From 8d4670c168a136e2745765ac9a354fb4b54d9d70 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 10 Oct 2018 09:10:34 -0400 Subject: zm needs restart after auth_hash --- www/lang/locale-en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'www') diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json index a0749bc1..2950c0dd 100644 --- a/www/lang/locale-en.json +++ b/www/lang/locale-en.json @@ -15,7 +15,7 @@ "kApplyingChanges" :"Applying changes. Please wait", "kArrangingImages" :"arranging images", "kAt" :"at", - "kAuthHashDisabled" :"zmNinja needs AUTH_HASH_LOGINS to be enabled to be able to display image frames", + "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", -- cgit v1.2.3 From 0c99777beff4abf2035c7a571a758e57a89daf60 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 12 Oct 2018 09:53:10 -0400 Subject: fix events page image download --- www/js/EventCtrl.js | 145 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 43 deletions(-) (limited to 'www') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 0d2ae4ab..82f04bd2 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -522,6 +522,11 @@ angular.module('zmApp.controllers') function saveNow(imgsrc, r, f) { + var fname = "zmninja.jpg"; + var fn = "cordova.plugins.photoLibrary.saveImage"; + var loginData = NVRDataModel.getLogin(); + + $ionicLoading.show({ template: $translate.instant('kSavingSnapshot') + "...", noBackdrop: true, @@ -530,52 +535,106 @@ angular.module('zmApp.controllers') var url = imgsrc; NVRDataModel.log("saveNow: File path to grab is " + url); - var img = new Image(); - img.onload = function () { - // console.log("********* ONLOAD"); - var canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - var context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - var imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - var imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - - if ($rootScope.platformOS != "desktop") { - try { - - cordova.exec( - SaveSuccess, - SaveError, - 'Canvas2ImagePlugin', - 'saveImageDataToLibrary', [imageData] - ); - // carouselUtils.setStop(curState); - } catch (e) { - - SaveError(e.message); - // carouselUtils.setStop(curState); + if ($rootScope.platformOS != 'desktop') { + + var album = 'zmNinja'; + NVRDataModel.debug("Trying to save image to album: " + album); + cordova.plugins.photoLibrary.requestAuthorization( + function () { + //url = "https://picsum.photos/200/300/?random"; + + var fileTransfer = new FileTransfer(); + var urle = encodeURI(url); + + + fileTransfer.onprogress = function (progressEvent) { + if (progressEvent.lengthComputable) { + + $timeout(function () { + var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100); + $ionicLoading.show({ + template: $translate.instant('kPleaseWait') + "... (" + perc + "%)", + noBackdrop: true, + //duration: zm.httpTimeout + }); + }); + + + } + }; + + fileTransfer.download(urle, cordova.file.dataDirectory + fname, + function (entry) { + NVRDataModel.debug("local download complete: " + entry.toURL()); + NVRDataModel.debug("Now trying to move it to album"); + var pluginName = (fname == "zmNinja.mp4" ? "saveVideo" : "saveImage"); + + + cordova.plugins.photoLibrary[pluginName](entry.toURL(), album, + function (cameraRollAssetId) { + SaveSuccess(); + $cordovaFile.removeFile(cordova.file.dataDirectory, fname) + .then( + function () { + NVRDataModel.debug("file removed from data directory"); + }, + function (e) { + NVRDataModel.debug("could not delete temp file: " + JSON.stringify(e)); + } + ); + + + }, + function (err) { + NVRDataModel.debug("Saving error:" + JSON.stringify(err)); + SaveError(); + + }); + + + + + }, + function (err) { + NVRDataModel.log("error downloading:" + JSON.stringify(err)); + SaveError(); + }, !loginData.enableStrictSSL, {}); + + + + + // User gave us permission to his library, retry reading it! + }, + function (err) { + // User denied the access + NVRDataModel.debug("Permission not granted"); + SaveError(); + }, // if options not provided, defaults to {read: true}. + + { + read: true, + write: true } - } else { - - var fname = r + f + ".png"; - fname = fname.replace(/\//, "-"); - fname = fname.replace(/\.jpg/, ''); - - canvas.toBlob(function (blob) { - saveAs(blob, fname); - SaveSuccess(); - }); - } - }; - try { - img.src = url; - // console.log ("SAVING IMAGE SOURCE"); - } catch (e) { - SaveError(e.message); + ); + + } else { + //desktop + + $ionicLoading.hide(); + + $rootScope.zmPopup = SecuredPopups.show('alert', { + title: $translate.instant('kNote'), + template: $translate.instant('kDownloadVideoImage')+"

    "+" "+$translate.instant('kDownload')+"
    ", + okText: $translate.instant('kDismiss'), + okType:'button-stable' + }); + + + } + + } -- cgit v1.2.3 From 2453cf21be3a283f2ee8ff4640762733c4b7b6b2 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 12 Oct 2018 09:54:00 -0400 Subject: meh don't think we need these --- www/js/EventServerSettingsCtrl.js | 2 +- www/js/WizardCtrl.js | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'www') diff --git a/www/js/EventServerSettingsCtrl.js b/www/js/EventServerSettingsCtrl.js index a4ce03b0..c5857369 100644 --- a/www/js/EventServerSettingsCtrl.js +++ b/www/js/EventServerSettingsCtrl.js @@ -213,7 +213,7 @@ type: 'filter', monlist: monstring, intlist: intervalstring, - token: $rootScope.apnsToken, + token: $rootScope.apnsToken }, 1); if ($rootScope.apnsToken != "") diff --git a/www/js/WizardCtrl.js b/www/js/WizardCtrl.js index bc5c3935..a152f537 100644 --- a/www/js/WizardCtrl.js +++ b/www/js/WizardCtrl.js @@ -13,12 +13,8 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$ function login(u, zmu, zmp) { var d = $q.defer(); - - - - $http({ - method: 'POST', + method: 'post', //withCredentials: true, url: u, headers: { @@ -31,6 +27,7 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$ str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); var params = str.join("&"); + //console.log ("PARAMS in login:"+params); return params; }, @@ -61,7 +58,7 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$ } }, function (error) { - //console.log("************ERROR"); + // console.log("************ERROR:"+ JSON.stringify(error)); $scope.wizard.portalValidText = $translate.instant('kPortalDetectionFailed'); $scope.wizard.portalColor = "#e74c3c"; d.reject(false); -- cgit v1.2.3 From e47839bb9264d36f61189f6dc5be9656f92604cc Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 13 Oct 2018 17:41:00 -0400 Subject: speed up event fetching --- www/js/DataModel.js | 38 +++++++++++++++++++------------------- www/js/EventCtrl.js | 49 ++++++++++++++++++++++++++++++------------------- www/js/TimelineCtrl.js | 25 ++++++++++++++++--------- 3 files changed, 65 insertions(+), 47 deletions(-) (limited to 'www') diff --git a/www/js/DataModel.js b/www/js/DataModel.js index a87f7765..3b465400 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -28,7 +28,7 @@ angular.module('zmApp.controllers') var monitors = []; var multiservers = []; - var oldevents = []; + var migrationComplete = false; var tz = ""; @@ -2519,6 +2519,11 @@ angular.module('zmApp.controllers') getEventsPages: function (monitorId, startTime, endTime) { //console.log("********** INSIDE EVENTS PAGES "); + + var d = $q.defer(); + + + var apiurl = loginData.apiurl; var myurl = apiurl + "/events/index"; @@ -2544,7 +2549,7 @@ angular.module('zmApp.controllers') }); //var myurl = (monitorId == 0) ? apiurl + "/events.json?page=1" : apiurl + "/events/index/MonitorId:" + monitorId + ".json?page=1"; - var d = $q.defer(); + $http.get(myurl) .then(function (data) { data = data.data; @@ -2575,9 +2580,13 @@ angular.module('zmApp.controllers') //----------------------------------------------------------------------------- // new reminder - // https://zm/api/events.json?&sort=StartTime&direction=desc + // + //https:///zm/api/events.json?&sort=StartTime&direction=desc&page=1 getEvents: function (monitorId, pageId, loadingStr, startTime, endTime) { + + + if (!pageId) pageId = 1; //console.log("ZMData getEvents called with ID=" + monitorId + "and Page=" + pageId); if (!loadingStr) { @@ -2609,14 +2618,11 @@ angular.module('zmApp.controllers') myurl = myurl + "/EndTime <=:" + endTime; myurl = myurl + "/AlarmFrames >=:" + (loginData.enableAlarmCount ? loginData.minAlarmCount : 0); - myurl = myurl + ".json"; - if (pageId) { - myurl = myurl + "?page=" + pageId; - } else { - //console.log("**** PAGE WAS " + pageId); - } + myurl = myurl + ".json?&sort=StartTime&direction=desc&page="+pageId; + + debug ("getEvents:"+myurl); // Simulated data // myurl = "https://api.myjson.com/bins/4jx44.json"; @@ -2628,12 +2634,9 @@ angular.module('zmApp.controllers') data = data.data; if (loadingStr != 'none') $ionicLoading.hide(); //myevents = data.events; - myevents = data.events.reverse(); - if (monitorId == 0) { - oldevents = myevents; - } - //console.log (JSON.stringify(data)); - // console.log("DataModel Returning " + myevents.length + "events for page" + pageId); + myevents = data; + + d.resolve(myevents); return d.promise; @@ -2650,10 +2653,7 @@ angular.module('zmApp.controllers') d.reject(myevents); - // FIXME: Check what pagination does to this logic - if (monitorId == 0) { - oldevents = []; - } + return d.promise; }); return d.promise; diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 82f04bd2..32367682 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -45,7 +45,8 @@ angular.module('zmApp.controllers') var oldEvent; var scrollbynumber; var eventImageDigits = 5; // failsafe - var eventsPage; + var currEventsPage = 1; + var maxEventsPage = 1; var moreEvents; var pageLoaded; var enableLoadMore; @@ -236,7 +237,7 @@ angular.module('zmApp.controllers') }); $scope.showSearch = false; - eventsPage = 1; + moreEvents = true; $scope.viewTitle = { title: "" @@ -342,6 +343,8 @@ angular.module('zmApp.controllers') $scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; } else*/ $scope.monitors = message; + currEventsPage = 1; + maxEventsPage = 1; if ($scope.monitors.length == 0) { var pTitle = $translate.instant('kNoMonitors'); @@ -374,14 +377,8 @@ angular.module('zmApp.controllers') nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); //NVRDataModel.debug ("GETTING EVENTS USING "+$scope.id+" "+nolangFrom+" "+ nolangTo); - NVRDataModel.getEventsPages($scope.id, nolangFrom, nolangTo) - .then(function (data) { - // console.log ("WE GOT PAGES="+JSON.stringify(data)); - eventsPage = data.pageCount || 1; - NVRDataModel.debug("EventCtrl: found " + eventsPage + " pages of events"); - pageLoaded = true; - $scope.viewTitle.title = data.count; + NVRDataModel.debug("EventCtrl: grabbing events for: id=" + $scope.id + " Date/Time:" + $rootScope.fromString + "-" + $rootScope.toString); nolangFrom = ""; @@ -391,11 +388,20 @@ angular.module('zmApp.controllers') if ($rootScope.toString) nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); - NVRDataModel.getEvents($scope.id, eventsPage, "", nolangFrom, nolangTo) + NVRDataModel.getEvents($scope.id, currEventsPage, "", nolangFrom, nolangTo) .then(function (data) { + pageLoaded = true; + //$scope.viewTitle.title = data.pagination.count; + + console.log (JSON.stringify(data.pagination)); + if (data.pagination && data.pagination.pageCount) + maxEventsPage = data.pagination.pageCount; + + NVRDataModel.debug ("We have a total of "+maxEventsPage+" and are at page="+currEventsPage); + // console.log ("WE GOT EVENTS="+JSON.stringify(data)); - var myevents = data; + var myevents = data.events; NVRDataModel.debug("EventCtrl: success, got " + myevents.length + " events"); var loginData = NVRDataModel.getLogin(); @@ -493,7 +499,6 @@ angular.module('zmApp.controllers') } }); - }); } //------------------------------------------------------- @@ -2733,14 +2738,17 @@ angular.module('zmApp.controllers') // the events API does not return an error for anything // except greater page limits than reported - // console.log("***** LOADING MORE INFINITE SCROLL ****"); - eventsPage--; - if ((eventsPage <= 0) && (pageLoaded)) { + console.log("***** LOADING MORE INFINITE SCROLL ****"); + + if ((currEventsPage >= maxEventsPage) && (pageLoaded)) { moreEvents = false; - //console.log("*** At Page " + eventsPage + ", not proceeding"); + NVRDataModel.debug ("No more - We have a total of "+maxEventsPage+" and are at page="+currEventsPage); + + console.log("*** At Page " + currEventsPage + " of "+maxEventsPage+", not proceeding"); return; } + currEventsPage++; if (!enableLoadMore) { moreEvents = false; // Don't ion-scroll till enableLoadMore is true; $scope.$broadcast('scroll.infiniteScrollComplete'); @@ -2751,7 +2759,7 @@ angular.module('zmApp.controllers') var loadingStr = ""; if ($scope.search.text != "") { - var toastStr = $translate.instant('kToastSearchingPage') + eventsPage; + var toastStr = $translate.instant('kToastSearchingPage') + currEventsPage; $ionicLoading.show({ maxwidth: 100, scope: $scope, @@ -2768,11 +2776,12 @@ angular.module('zmApp.controllers') if ($rootScope.toString) nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); - NVRDataModel.getEvents($scope.id, eventsPage, loadingStr, nolangFrom, nolangTo) + NVRDataModel.getEvents($scope.id, currEventsPage, loadingStr, nolangFrom, nolangTo) .then(function (data) { var loginData = NVRDataModel.getLogin(); // console.log("Got new page of events with Page=" + eventsPage); - var myevents = data; + var myevents = data.events; + for (var i = 0; i < myevents.length; i++) { @@ -3064,6 +3073,8 @@ angular.module('zmApp.controllers') // console.log("***Pull to Refresh"); NVRDataModel.debug("Reloading monitors"); + maxEventsPage = 1; + currEventsPage = 1; var refresh = NVRDataModel.getMonitors(1); refresh.then(function (data) { $scope.monitors = data; diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js index b612468a..a5c7f818 100644 --- a/www/js/TimelineCtrl.js +++ b/www/js/TimelineCtrl.js @@ -1103,9 +1103,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla //console.log ("**NOLANG" + fromDateNoLang + " " + toDateNoLang); NVRDataModel.getEventsPages(0, fromDateNoLang, toDateNoLang) - .then(function (data) { - var pages = data.pageCount || 1; - var itemsPerPage = parseInt(data.limit); + .then(function (epData) { + var pages = 1; + var itemsPerPage = parseInt(epData.limit); var iterCount; // So iterCount is the # of HTTP calls I need to make @@ -1117,17 +1117,18 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla // for dynamic binding which was easier, but due to performance reasons // I am waiting for the full data to load before I draw var promises = []; - while ((pages > 0) && (iterCount > 0)) { + while ((pages <= epData.pageCount) && (iterCount > 0)) { var promise = NVRDataModel.getEvents(0, pages, "none", fromDateNoLang, toDateNoLang); promises.push(promise); - pages--; + + pages++; iterCount--; } $q.all(promises) .then(function (data) { - NVRDataModel.debug("TimelineCtrl/drawgraph: all pages of graph data received"); + NVRDataModel.debug("TimelineCtrl/drawgraph: all pages of graph data received " ); graphIndex = 0; NVRDataModel.log("Creating " + $scope.monitors.length + " groups for the graph"); // create groups @@ -1143,8 +1144,10 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla } for (var j = 0; j < data.length; j++) { - var myevents = data[j]; + var myevents = data[j].events; + // console.log ("****************DATA ="+JSON.stringify(data[j])); + // console.log ("**********************************"); if (graphIndex > count) { NVRDataModel.log("Exiting page count graph - reached limit of " + count); break; @@ -1203,10 +1206,12 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla } //console.log ("ADDED "+tzs+" " +tze); + + if (!graphData.get(myevents[i].Event.Id)) { graphData.add({ //id: graphIndex, id: myevents[i].Event.Id, - content: "" + "( " + myevents[i].Event.AlarmFrames + ") " + "(" + myevents[j].Event.Id + ") " + myevents[i].Event.Notes + "", + content: "" + "( " + myevents[i].Event.AlarmFrames + ") " + "(" + myevents[i].Event.Id + ") " + myevents[i].Event.Notes + "", start: tzs, //start: myevents[i].Event.StartTime, @@ -1224,7 +1229,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla myevent: myevents[i] }); + //console.log ("IED="+myevents[i].Event.Id); graphIndex++; + } } else { //console.log ("SKIPPED GRAPH ID " + graphIndex); } @@ -1375,7 +1382,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla var _item; for (var x = 0; x < visible.length; x++) { _item = timeline.itemSet.items[x]; - if (_item.data.group == prop.group) { + if (_item && _item.data && _item.data.group == prop.group) { if (Math.abs(_item.left - prop.x) < minDist) { closestItem = _item; minDist = Math.abs(_item.left - prop.x); -- cgit v1.2.3 From f6be92a7c14d600fa1345a55de76bda706b84380 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sun, 14 Oct 2018 14:39:37 -0400 Subject: migrate websockets to native --- www/js/EventServer.js | 499 +++++++++++++++++++++++--------------------------- www/js/app.js | 2 +- 2 files changed, 231 insertions(+), 270 deletions(-) (limited to 'www') diff --git a/www/js/EventServer.js b/www/js/EventServer.js index f252cca4..a460795c 100644 --- a/www/js/EventServer.js +++ b/www/js/EventServer.js @@ -16,173 +16,174 @@ angular.module('zmApp.controllers') var localNotificationId = 0; var pushInited = false; var isTimerOn = false; - + var nativeWebSocketId = -1; + //-------------------------------------------------------------------------- // called when the websocket is opened //-------------------------------------------------------------------------- - function handleOpen(event) { - - NVRDataModel.debug ("WebSocket open called with:"+JSON.stringify(event.data)); - var loginData = NVRDataModel.getLogin(); - NVRDataModel.log("openHandshake: Websocket open, sending Auth"); - sendMessage("auth", - { - user: loginData.username, - password: loginData.password - }); + function handleOpen(data) { + NVRDataModel.debug("WebSocket open called with:" + JSON.stringify(data)); + var loginData = NVRDataModel.getLogin(); + NVRDataModel.log("openHandshake: Websocket open, sending Auth"); + sendMessage("auth", { + user: loginData.username, + password: loginData.password + }); - if ($rootScope.apnsToken != '') { - var plat = $ionicPlatform.is('ios') ? 'ios' : 'android'; - var ld = NVRDataModel.getLogin(); - var pushstate = "enabled"; - if (ld.disablePush == true) - pushstate = "disabled"; - - NVRDataModel.debug("openHandShake: state of push is " + pushstate); - // let's do this only if disabled. If enabled, I suppose registration - // will be called? - //if (ld.disablePush) - //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring); - sendMessage ("push", { - type: 'token', - platform: plat, - token: $rootScope.apnsToken, - monlist: $rootScope.monstring, - intlist: $rootScope.intstring, - state: pushstate + if ($rootScope.apnsToken != '') { + var plat = $ionicPlatform.is('ios') ? 'ios' : 'android'; + var ld = NVRDataModel.getLogin(); + var pushstate = "enabled"; + if (ld.disablePush == true) + pushstate = "disabled"; + + NVRDataModel.debug("openHandShake: state of push is " + pushstate); + // let's do this only if disabled. If enabled, I suppose registration + // will be called? + //if (ld.disablePush) + //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring); + + sendMessage("push", { + type: 'token', + platform: plat, + token: $rootScope.apnsToken, + monlist: $rootScope.monstring, + intlist: $rootScope.intstring, + state: pushstate + + }); + } - }); - } - } function handleClose(event) { - - console.log ("*********** WEBSOCKET CLOSE CALLED WITH "+JSON.stringify(event.data)); + console.log("*********** WEBSOCKET CLOSE CALLED"); + + if (!NVRDataModel.getLogin().isUseEventServer) return; - if (!isTimerOn) { - NVRDataModel.log("Will try to reconnect in 10 sec.."); - $timeout(init, 10000); - isTimerOn = true; + NVRDataModel.log("Will try to reconnect in 10 sec.."); + $timeout(init, 10000); + isTimerOn = true; } } function handleError(event) { - console.log ("*********** WEBSOCKET CLOSE CALLED WITH "+JSON.stringify(event.data)); - //return; - if (!isTimerOn) { - NVRDataModel.log("Will try to reconnect in 10 sec.."); - $timeout(init, 10000); - isTimerOn = true; - } + console.log("*********** WEBSOCKET ERROR CALLED"); + if (!NVRDataModel.getLogin().isUseEventServer) return; + + if (!isTimerOn) { + NVRDataModel.log("Will try to reconnect in 10 sec.."); + $timeout(init, 10000); + isTimerOn = true; + } } function handleMessage(smsg) { //NVRDataModel.debug ("Websocket received message:"+smsg); - str = JSON.parse(smsg); - NVRDataModel.debug("Real-time event: " + JSON.stringify(str)); - - - - // Error messages - if (str.status != 'Success') { - NVRDataModel.log("Event Error: " + JSON.stringify(str)); - - if (str.reason == 'APNSDISABLED') { - console.log ("FORCE CLOSING"); - ws.close(); - NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000); - $rootScope.apnsToken = ""; - } + str = JSON.parse(smsg); + NVRDataModel.debug("Real-time event: " + JSON.stringify(str)); - } - if (str.status == 'Success' && (str.event == 'auth')) { - if (str.version == undefined) - str.version = "0.1"; - if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) { - $rootScope.zmPopup = $ionicPopup.alert({ - title: $translate.instant('kEventServerVersionTitle'), - template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " + - zm.minEventServerVersion, - okText: $translate.instant('kButtonOk'), - cancelText: $translate.instant('kButtonCancel'), - }); - } - } + // Error messages + if (str.status != 'Success') { + NVRDataModel.log("Event Error: " + JSON.stringify(str)); - if (str.status == 'Success' && str.event == 'alarm') // new events - { + if (str.reason == 'APNSDISABLED') { + console.log("FORCE CLOSING"); + ws.close(); + NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000); + $rootScope.apnsToken = ""; + } - var localNotText; - // ZMN specific hack for Event Server - if (str.supplementary != 'true') { - new Audio('sounds/blop.mp3').play(); - localNotText = ""; - $rootScope.isAlarm = 1; - - // Show upto a max of 99 when it comes to display - // so aesthetics are maintained - if ($rootScope.alarmCount == "99") { - $rootScope.alarmCount = "99+"; - } - if ($rootScope.alarmCount != "99+") { - $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString(); - } + } - } else { - NVRDataModel.debug("received supplementary event information over websockets"); - } - var eventsToDisplay = []; - var listOfMonitors = []; - for (var iter = 0; iter < str.events.length; iter++) { - // lets stack the display so they don't overwrite - //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")"); - var txt = str.events[iter].EventId; - if (str.events[iter].Cause) { - txt = str.events[iter].Cause; - } - eventsToDisplay.push(str.events[iter].Name + ": " + txt); - localNotText = localNotText + str.events[iter].Name + ": " + txt + ","; - listOfMonitors.push(str.events[iter].MonitorId); + if (str.status == 'Success' && (str.event == 'auth')) { + if (str.version == undefined) + str.version = "0.1"; + if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) { + $rootScope.zmPopup = $ionicPopup.alert({ + title: $translate.instant('kEventServerVersionTitle'), + template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " + + zm.minEventServerVersion, + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), + }); + } - } - localNotText = localNotText.substring(0, localNotText.length - 1); + } - // if we are in background, do a local notification, else do an in app display - if (!NVRDataModel.isBackground()) { + if (str.status == 'Success' && str.event == 'alarm') // new events + { - //emit alarm details - this is when received over websockets - $rootScope.$broadcast('alarm', { - message: listOfMonitors - }); + var localNotText; + // ZMN specific hack for Event Server + if (str.supplementary != 'true') { + new Audio('sounds/blop.mp3').play(); + localNotText = ""; + $rootScope.isAlarm = 1; + + // Show upto a max of 99 when it comes to display + // so aesthetics are maintained + if ($rootScope.alarmCount == "99") { + $rootScope.alarmCount = "99+"; + } + if ($rootScope.alarmCount != "99+") { + $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString(); + } - if (str.supplementary != 'true') { + } else { + NVRDataModel.debug("received supplementary event information over websockets"); + } + var eventsToDisplay = []; + var listOfMonitors = []; + for (var iter = 0; iter < str.events.length; iter++) { + // lets stack the display so they don't overwrite + //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")"); + var txt = str.events[iter].EventId; + if (str.events[iter].Cause) { + txt = str.events[iter].Cause; + } + eventsToDisplay.push(str.events[iter].Name + ": " + txt); + localNotText = localNotText + str.events[iter].Name + ": " + txt + ","; + listOfMonitors.push(str.events[iter].MonitorId); + + } + localNotText = localNotText.substring(0, localNotText.length - 1); - NVRDataModel.debug("App is in foreground, displaying banner"); - if (eventsToDisplay.length > 0) { + // if we are in background, do a local notification, else do an in app display + if (!NVRDataModel.isBackground()) { - if (eventsToDisplay.length == 1) { - //console.log("Single Display: " + eventsToDisplay[0]); - NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000); - } else { - NVRDataModel.displayBanner('alarm', eventsToDisplay, - 5000, 5000 * eventsToDisplay.length); - } + //emit alarm details - this is when received over websockets + $rootScope.$broadcast('alarm', { + message: listOfMonitors + }); - } + if (str.supplementary != 'true') { + + NVRDataModel.debug("App is in foreground, displaying banner"); + if (eventsToDisplay.length > 0) { + + if (eventsToDisplay.length == 1) { + //console.log("Single Display: " + eventsToDisplay[0]); + NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000); + } else { + NVRDataModel.displayBanner('alarm', eventsToDisplay, + 5000, 5000 * eventsToDisplay.length); } + } } + } + } } @@ -207,183 +208,134 @@ angular.module('zmApp.controllers') NVRDataModel.log("Initializing Websocket with URL " + loginData.eventServer); - - - - ws = new WebSocket(loginData.eventServer); - - ws.onopen = function (event) { - handleOpen(event); - if (!pushInited) { NVRDataModel.debug ("Initializing FCM push"); pushInit();} - d.resolve("true"); - return; - }; + if ($rootScope.platforOS == 'desktop') { + NVRDataModel.debug("Using browser websockets..."); + return setupDesktopSocket(); + } else { + NVRDataModel.debug("Using native websockets..."); + return setupMobileSocket(); - ws.onclose = function (event) { - handleClose(event); - d.reject ("error"); - return; - - }; - - ws.onerror = function (event) { - handleError(event); - d.reject ("error"); - return; - + } - - }; + } - ws.onmessage = function (event) { - + function setupMobileSocket() { - var smsg = event.data; - handleMessage (smsg); + var loginData = NVRDataModel.getLogin(); + var d = $q.defer(); - + var wsOptions = { + url: loginData.eventServer, + acceptAllCerts: !loginData.enableStrictSSL }; + CordovaWebsocketPlugin.wsConnect(wsOptions, + function (recvEvent) { + console.log("Received callback from WebSocket: " + recvEvent.callbackMethod); + if (recvEvent.callbackMethod == 'onMessage') { + handleMessage(recvEvent.message); + } else if (recvEvent.callbackMethod == 'onClose') { + handleClose(); + } else if (recvEvent.callbackMethod == 'onFail') { + handleError(); + } - - - - - - - /* - - ws.onMessage(function (str) - // ws.$on('$message', function(str) - - { - str = JSON.parse(str.data); - //console.log ("FULL MESSAGE="+JSON.stringify(str.data)); - NVRDataModel.debug("Real-time event: " + JSON.stringify(str)); - - // Error messages - if (str.status != 'Success') { - NVRDataModel.log("Event Error: " + JSON.stringify(str)); - - if (str.reason == 'APNSDISABLED') { - ws.close(); - NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000); - $rootScope.apnsToken = ""; - } - + }, + function (success) { + console.log("Connected to WebSocket with id: " + success.webSocketId); + nativeWebSocketId = success.webSocketId; + handleOpen(success); + if (!pushInited) { + NVRDataModel.debug("Initializing FCM push"); + pushInit(); } + d.resolve(true); + return d.promise; + }, + function (error) { + console.log("Failed to connect to WebSocket: " + + "code: " + error.code + + ", reason: " + error.reason + + ", exception: " + error.exception); + d.resolve(false); + return d.promise; + } + ); + return d.promise; + } - if (str.status == 'Success' && (str.event == 'auth')) { - if (str.version == undefined) - str.version = "0.1"; - if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) { - $rootScope.zmPopup = $ionicPopup.alert({ - title: $translate.instant('kEventServerVersionTitle'), - template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " + - zm.minEventServerVersion, - okText: $translate.instant('kButtonOk'), - cancelText: $translate.instant('kButtonCancel'), - }); - } + function setupDesktopSocket() { - } + var d = $q.defer(); + ws = new WebSocket(loginData.eventServer); - if (str.status == 'Success' && str.event == 'alarm') // new events - { + ws.onopen = function (event) { + handleOpen(event.data); + if (!pushInited) { + NVRDataModel.debug("Initializing FCM push"); + pushInit(); + } + d.resolve("true"); + return d.promise; + }; - var localNotText; - // ZMN specific hack for Event Server - if (str.supplementary != 'true') { - new Audio('sounds/blop.mp3').play(); - localNotText = ""; - $rootScope.isAlarm = 1; - - // Show upto a max of 99 when it comes to display - // so aesthetics are maintained - if ($rootScope.alarmCount == "99") { - $rootScope.alarmCount = "99+"; - } - if ($rootScope.alarmCount != "99+") { - $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString(); - } - } else { - NVRDataModel.debug("received supplementary event information over websockets"); - } - var eventsToDisplay = []; - var listOfMonitors = []; - for (var iter = 0; iter < str.events.length; iter++) { - // lets stack the display so they don't overwrite - //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")"); - var txt = str.events[iter].EventId; - if (str.events[iter].Cause) { - txt = str.events[iter].Cause; - } - eventsToDisplay.push(str.events[iter].Name + ": " + txt); - localNotText = localNotText + str.events[iter].Name + ": " + txt + ","; - listOfMonitors.push(str.events[iter].MonitorId); + ws.onclose = function (event) { + handleClose(event); + d.reject("error"); + return d.promise; - } - localNotText = localNotText.substring(0, localNotText.length - 1); + }; - // if we are in background, do a local notification, else do an in app display - if (!NVRDataModel.isBackground()) { + ws.onerror = function (event) { + handleError(event); + d.reject("error"); + return d.promise; - //emit alarm details - this is when received over websockets - $rootScope.$broadcast('alarm', { - message: listOfMonitors - }); + }; - if (str.supplementary != 'true') { - NVRDataModel.debug("App is in foreground, displaying banner"); - if (eventsToDisplay.length > 0) { + ws.onmessage = function (event) { - if (eventsToDisplay.length == 1) { - //console.log("Single Display: " + eventsToDisplay[0]); - NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000); - } else { - NVRDataModel.displayBanner('alarm', eventsToDisplay, - 5000, 5000 * eventsToDisplay.length); - } + var smsg = event.data; + handleMessage(smsg); - } - } - } - } //end of success handler + }; - }); + return d.promise; + } - */ - - return (d.promise); - } function disconnect() { - if (typeof ws === 'undefined') { - NVRDataModel.log("Event server socket is empty, nothing to disconnect"); - return; - } NVRDataModel.log("Clearing error/close cbk, disconnecting and deleting Event Server socket..."); - // ws.$close(); - - ws.onmessage = null; + if ($rootScope.platforOS == 'desktop'){ + if (typeof ws === 'undefined') { + NVRDataModel.log("Event server socket is empty, nothing to disconnect"); + return; + } + + + ws.onmessage = null; + ws.close(); + ws = undefined; + } + else { + if (nativeWebSocketId != -1) //native; + CordovaWebsocketPlugin.wsClose(nativeWebSocketId, 1000, "Connection closed"); + nativeWebSocketId = -1; - ws.close(); - // ws.$un('open'); - // ws.$un('close'); - // ws.$un('message'); - ws = undefined; + } + } @@ -402,7 +354,7 @@ angular.module('zmApp.controllers') return; } - if (typeof ws === 'undefined') { + if (typeof ws === 'undefined' && nativeWebSocketId == -1) { NVRDataModel.debug("Event server not initalized, not sending message"); return; } @@ -415,10 +367,19 @@ angular.module('zmApp.controllers') }; var jmsg = JSON.stringify(msg); - NVRDataModel.debug ("~~~~ sendMessage: Sending->"+jmsg); + NVRDataModel.debug("~~~~ sendMessage: Sending->" + jmsg); + + if ($rootScope.platformOS == 'desktop') { ws.send(jmsg); + } + else { + if (nativeWebSocketId != -1) + CordovaWebsocketPlugin.wsSend(nativeWebSocketId, jmsg); + else + NVRDataModel.debug ("ERROR:native websocket not initialized, can't send "+jmsg); + } + - } //-------------------------------------------------------------------------- diff --git a/www/js/app.js b/www/js/app.js index fe42b264..5935ee0d 100755 --- a/www/js/app.js +++ b/www/js/app.js @@ -2312,7 +2312,7 @@ angular.module('zmApp', [ timeout: arguments[0].timeout, responseType: arguments[0].responseType }; - console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)+" payload:"+JSON.stringify(options)); + // 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 -- cgit v1.2.3