From 31ca68739126f5740681238539a8c6a1b66e0000 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 18 Nov 2016 09:28:08 -0500 Subject: mass formatting and normalization - tweaked JSBeautify options --- www/js/EventCtrl.js | 925 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 532 insertions(+), 393 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index c076ea4d..7f1c0af0 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -9,21 +9,24 @@ angular.module('zmApp.controllers') // alarm frames filter -.filter('selectFrames', function ($filter, $translate) { +.filter('selectFrames', function($filter, $translate) +{ // Create the return function and set the required parameter name to **input** - return function (input, typeOfFrames) { - + return function(input, typeOfFrames) + { var out = []; - angular.forEach(input, function (item) { - + angular.forEach(input, function(item) + { - if (typeOfFrames == $translate.instant('kShowTimeDiffFrames')) { + if (typeOfFrames == $translate.instant('kShowTimeDiffFrames')) + { if (item.type == $translate.instant('kShowTimeDiffFrames')) out.push(item); - } else + } + else out.push(item); }); @@ -33,7 +36,8 @@ angular.module('zmApp.controllers') }) -.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', function ($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate) { +.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', function($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate) +{ // events in last 5 minutes // TODO https://server/zm/api/events/consoleEvents/5%20minute.json @@ -56,32 +60,34 @@ angular.module('zmApp.controllers') var mycarouselWatcher; var nolangFrom; var nolangTo; - + $scope.typeOfFrames = $translate.instant('kShowTimeDiffFrames'); var eventsListScrubHeight = eventsListScrubHeight; var eventsListDetailsHeight = eventsListDetailsHeight; - //--------------------------------------------------- // initial code //--------------------------------------------------- //we come here is TZ is updated after the view loads - $rootScope.$on('tz-updated', function() { + $rootScope.$on('tz-updated', function() + { $scope.tzAbbr = NVRDataModel.getTimeZoneNow(); - NVRDataModel.debug ("Timezone API updated timezone to " + NVRDataModel.getTimeZoneNow()); + NVRDataModel.debug("Timezone API updated timezone to " + NVRDataModel.getTimeZoneNow()); }); - - $rootScope.$on("language-changed", function () { + + $rootScope.$on("language-changed", function() + { NVRDataModel.log(">>>>>>>>>>>>>>> language changed"); doRefresh(); }); - $scope.$on('$ionicView.afterEnter', function () { + $scope.$on('$ionicView.afterEnter', function() + { //console.log ("********* AFTER ENTER"); - + // see if we come from monitors, if so, don't filter events - if ($ionicHistory.backTitle() =='Monitors') + if ($ionicHistory.backTitle() == 'Monitors') { showHiddenMonitors = true; } @@ -89,8 +95,8 @@ angular.module('zmApp.controllers') { showHiddenMonitors = false; } - // console.log (">>>>>>>>>>>>>>>>>SHOWHIDDEN IS " + showHiddenMonitors); - + // console.log (">>>>>>>>>>>>>>>>>SHOWHIDDEN IS " + showHiddenMonitors); + // lets get the abbreviated version of TZ to display if (NVRDataModel.getLogin().useLocalTimeZone) { @@ -100,41 +106,38 @@ angular.module('zmApp.controllers') { $scope.tzAbbr = moment().tz(NVRDataModel.getTimeZoneNow()).zoneAbbr(); } - + $scope.events = []; getInitialEvents(); setupWatchers(); footerExpand(); }); - - - $scope.$on('$ionicView.beforeEnter', function () { + $scope.$on('$ionicView.beforeEnter', function() + { - //console.log ("********* BEFORE ENTER"); document.addEventListener("pause", onPause, false); //console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id, 10); $scope.showEvent = $stateParams.playEvent || false; - - console.log (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - - - NVRDataModel.log ("EventCtrl called with: EID=" + $scope.id + " playEvent = "+$scope.showEvent); - + + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + + NVRDataModel.log("EventCtrl called with: EID=" + $scope.id + " playEvent = " + $scope.showEvent); + // This is the only view that hardcodes row size due to // collection repeat, so lets re-get the text size if it has changed // note that there may be a delay as its a callback - so might involve // a UI jiggle - + if (window.cordova) MobileAccessibility.getTextZoom(getTextZoomCallback); - + eventsListDetailsHeight = parseInt(zm.eventsListDetailsHeight * $rootScope.textScaleFactor); eventsListScrubHeight = parseInt(zm.eventsListScrubHeight * $rootScope.textScaleFactor); - - NVRDataModel.debug (">>>height of list/scrub set to " + eventsListDetailsHeight + " and " + eventsListScrubHeight); + + NVRDataModel.debug(">>>height of list/scrub set to " + eventsListDetailsHeight + " and " + eventsListScrubHeight); pageLoaded = false; enableLoadMore = true; @@ -153,7 +156,6 @@ angular.module('zmApp.controllers') $scope.weeks = []; $scope.months = []; - $scope.eventList = { showDelete: false }; @@ -167,13 +169,13 @@ angular.module('zmApp.controllers') $scope.FrameArray = []; // will hold frame info from detailed Events API loginData = NVRDataModel.getLogin(); NVRDataModel.getKeyConfigParams(0) - .then(function (data) { + .then(function(data) + { //console.log ("***GETKEY: " + JSON.stringify(data)); eventImageDigits = parseInt(data); NVRDataModel.log("Image padding digits reported as " + eventImageDigits); }); - $scope.showSearch = false; eventsPage = 1; moreEvents = true; @@ -191,18 +193,14 @@ angular.module('zmApp.controllers') }); - - function getEventObject(eid) { - - var apiurl = NVRDataModel.getLogin().apiurl + '/events/'+eid+'.json'; - - $http.get (apiurl) - .success (function (data) { - }) - .error (function (err) { - }); + + var apiurl = NVRDataModel.getLogin().apiurl + '/events/' + eid + '.json'; + + $http.get(apiurl) + .success(function(data) {}) + .error(function(err) {}); /* myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime); myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId); @@ -220,35 +218,38 @@ angular.module('zmApp.controllers') myevents[i].Event.relativePath = computeRelativePath(myevents[i]); */ } - function getTextZoomCallback(tz) { - $rootScope.textScaleFactor = parseFloat(tz+"%") / 100.0; - NVRDataModel.debug ("text zoom factor is " + $rootScope.textScaleFactor); + $rootScope.textScaleFactor = parseFloat(tz + "%") / 100.0; + NVRDataModel.debug("text zoom factor is " + $rootScope.textScaleFactor); } - - - // -------------------------------------------------------- // Handling of back button in case modal is open should // close the modal // -------------------------------------------------------- - $ionicPlatform.registerBackButtonAction(function (e) { + $ionicPlatform.registerBackButtonAction(function(e) + { e.preventDefault(); - if ($scope.modal != undefined && $scope.modal.isShown()) { + if ($scope.modal != undefined && $scope.modal.isShown()) + { // switch off awake, as liveview is finished NVRDataModel.debug("Modal is open, closing it"); NVRDataModel.setAwake(false); $scope.modal.remove(); - } else { + } + else + { NVRDataModel.debug("Modal is closed, so toggling or exiting"); - if (!$ionicSideMenuDelegate.isOpenLeft()) { + if (!$ionicSideMenuDelegate.isOpenLeft()) + { $ionicSideMenuDelegate.toggleLeft(); - } else { + } + else + { navigator.app.exitApp(); } @@ -256,30 +257,30 @@ angular.module('zmApp.controllers') }, 1000); - //-------------------------------------- // monitor the slider for carousels //-------------------------------------- - function setupWatchers() { + function setupWatchers() + { NVRDataModel.debug("Setting up carousel watchers"); - ionRangeWatcher = $scope.$watch('ionRange.index', function () { + ionRangeWatcher = $scope.$watch('ionRange.index', function() + { // console.log ("Watching index"); $scope.mycarousel.index = parseInt($scope.ionRange.index) - 1; if (carouselUtils.getStop() == true) return; - //console.log ("***ION RANGE CHANGED TO " + $scope.mycarousel.index); }); + mycarouselWatcher = $scope.$watch('mycarousel.index', function() + { - - mycarouselWatcher = $scope.$watch('mycarousel.index', function () { - - - if ($scope.event && $scope.ionRange.index == parseInt($scope.event.Event.Frames) - 1) { - if (!$scope.modal || $scope.modal.isShown() == false) { + if ($scope.event && $scope.ionRange.index == parseInt($scope.event.Event.Frames) - 1) + { + if (!$scope.modal || $scope.modal.isShown() == false) + { // console.log("quick scrub playback over"); carouselUtils.setStop(true); $scope.ionRange.index = 0; @@ -292,10 +293,8 @@ angular.module('zmApp.controllers') $scope.ionRange.index = ($scope.mycarousel.index + 1).toString(); // console.log ("***IONRANGE RANGE CHANGED TO " + $scope.ionRange.index); - }); - } // -------------------------------------------------------- @@ -303,30 +302,32 @@ angular.module('zmApp.controllers') // close the modal // -------------------------------------------------------- - function getInitialEvents() { + function getInitialEvents() + { NVRDataModel.debug("getInitialEvents called"); var lData = NVRDataModel.getLogin(); - - // If you came from Monitors, disregard hidden monitors in montage - /* if (lData.persistMontageOrder && stackState != "Monitors") { - var tempMon = message; - $scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; - } else*/ - $scope.monitors = message; - + /* if (lData.persistMontageOrder && stackState != "Monitors") { + var tempMon = message; + $scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; + } else*/ + $scope.monitors = message; - if ($scope.monitors.length == 0) { + if ($scope.monitors.length == 0) + { var pTitle = $translate.instant('kNoMonitors'); - $ionicPopup.alert({ + $ionicPopup.alert( + { title: pTitle, template: "{{'kCheckCredentials' | translate }}" }); - $ionicHistory.nextViewOptions({ + $ionicHistory.nextViewOptions( + { disableBack: true }); - $state.go("login", { + $state.go("login", + { "wizard": false }); return; @@ -345,7 +346,8 @@ angular.module('zmApp.controllers') if ($rootScope.toString) nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); NVRDataModel.getEventsPages($scope.id, nolangFrom, nolangTo) - .then(function (data) { + .then(function(data) + { eventsPage = data.pageCount || 1; NVRDataModel.debug("EventCtrl: found " + eventsPage + " pages of events"); @@ -361,18 +363,23 @@ angular.module('zmApp.controllers') nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); NVRDataModel.getEvents($scope.id, eventsPage, "", nolangFrom, nolangTo) - .then(function (data) { + .then(function(data) + { var myevents = data; NVRDataModel.debug("EventCtrl: success, got " + myevents.length + " events"); var loginData = NVRDataModel.getLogin(); - for (var i = 0; i < myevents.length; i++) { + for (var i = 0; i < myevents.length; i++) + { var idfound = true; - if (loginData.persistMontageOrder) { + if (loginData.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId && (NVRDataModel.isNotHidden(myevents[i].Event.MonitorId) || showHiddenMonitors)) { + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId && (NVRDataModel.isNotHidden(myevents[i].Event.MonitorId) || showHiddenMonitors)) + { idfound = true; break; @@ -380,7 +387,6 @@ angular.module('zmApp.controllers') } } - myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime); myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId); myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId); @@ -397,26 +403,28 @@ angular.module('zmApp.controllers') myevents[i].Event.BasePath = computeBasePath(myevents[i]); myevents[i].Event.relativePath = computeRelativePath(myevents[i]); - // in multiserver BasePath is login url for frames // http://login.url/index.php?view=frame&eid=19696772&fid=21 // console.log ("COMPARING "+NVRDataModel.getLogin().url+ " TO " +myevents[i].Event.baseURL); - if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) { + if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) + { //NVRDataModel.debug ("Multi server, changing base"); myevents[i].Event.baseURL = NVRDataModel.getLogin().url; } - if (idfound) { + if (idfound) + { $scope.events.push(myevents[i]); - } else { + } + else + { //console.log ("Skipping Event MID = " + myevents[i].Event.MonitorId); } } //for - //$scope.events = myevents; // we only need to stop the template from loading when the list is empty // so this can be false once we have _some_ content @@ -425,7 +433,8 @@ angular.module('zmApp.controllers') // to avoid only few events being displayed // if last page has less events //console.log("**Loading Next Page ***"); - if (myevents.length < 50) { + if (myevents.length < 50) + { NVRDataModel.debug("EventCtrl:loading one more page just in case we don't have enough to display"); loadMore(); } @@ -434,14 +443,14 @@ angular.module('zmApp.controllers') }); } - - //------------------------------------------------------- // Tapping on a frame shows this image //------------------------------------------------------ - function SaveSuccess() { - $ionicLoading.show({ + function SaveSuccess() + { + $ionicLoading.show( + { template: $translate.instant('kDone'), noBackdrop: true, duration: 1000 @@ -449,8 +458,10 @@ angular.module('zmApp.controllers') NVRDataModel.debug("ModalCtrl:Photo saved successfuly"); } - function SaveError(e) { - $ionicLoading.show({ + function SaveError(e) + { + $ionicLoading.show( + { template: $translate.instant('kErrorSave'), noBackdrop: true, duration: 2000 @@ -459,10 +470,11 @@ angular.module('zmApp.controllers') //console.log("***ERROR"); } + function saveNow(imgsrc, r, f) + { - function saveNow(imgsrc, r, f) { - - $ionicLoading.show({ + $ionicLoading.show( + { template: $translate.instant('kSavingSnapshot') + "...", noBackdrop: true, duration: zm.httpTimeout @@ -471,7 +483,8 @@ angular.module('zmApp.controllers') NVRDataModel.log("saveNow: File path to grab is " + url); var img = new Image(); - img.onload = function () { + img.onload = function() + { // console.log("********* ONLOAD"); var canvas = document.createElement('canvas'); canvas.width = img.width; @@ -482,8 +495,10 @@ angular.module('zmApp.controllers') var imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); var imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - if ($rootScope.platformOS != "desktop") { - try { + if ($rootScope.platformOS != "desktop") + { + try + { cordova.exec( SaveSuccess, @@ -492,37 +507,44 @@ angular.module('zmApp.controllers') 'saveImageDataToLibrary', [imageData] ); // carouselUtils.setStop(curState); - } catch (e) { + } + catch (e) + { SaveError(e.message); // carouselUtils.setStop(curState); } - } else { - + } + else + { var fname = r + f + ".png"; fname = fname.replace(/\//, "-"); fname = fname.replace(/\.jpg/, ''); - canvas.toBlob(function (blob) { + canvas.toBlob(function(blob) + { saveAs(blob, fname); SaveSuccess(); }); } }; - try { + try + { img.src = url; // console.log ("SAVING IMAGE SOURCE"); - } catch (e) { + } + catch (e) + { SaveError(e.message); } } - $scope.showImage = function (p, r, f, fid, e, imode, id, parray, ndx) { + $scope.showImage = function(p, r, f, fid, e, imode, id, parray, ndx) + { var img; - //console.log ("HERE"); $scope.kFrame = $translate.instant('kFrame'); $scope.kEvent = $translate.instant('kEvent'); @@ -534,42 +556,41 @@ angular.module('zmApp.controllers') // at unique frames; // NVRDataModel.debug("Hello"); - if ($scope.typeOfFrames == $translate.instant('kShowTimeDiffFrames')) { + if ($scope.typeOfFrames == $translate.instant('kShowTimeDiffFrames')) + { var ic; - for (ic = 0; ic < $scope.parray.length; ic++) { + for (ic = 0; ic < $scope.parray.length; ic++) + { if ($scope.parray[ic].frameid == fid) break; } - NVRDataModel.debug("Readjusting selected frame ID from:" + $scope.ndx + " to actual frame ID of:" + ic); $scope.ndx = ic; - } else { + } + else + { NVRDataModel.debug("No index adjustment necessary as we are using all frames"); } - - - // console.log ("Image Mode " + imode); // console.log ("parray : " + JSON.stringify(parray)); // console.log ("index: " + ndx); if ($scope.imode == 'path') $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname; - else { + else + { $scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id; } - - - //$rootScope.zmPopup = $ionicPopup.alert({title: kFrame+':'+fid+'/'+kEvent+':'+e,template:img, cssClass:'popup80'}); - $rootScope.zmPopup = $ionicPopup.show({ + $rootScope.zmPopup = $ionicPopup.show( + { template: '
' + $translate.instant('kFrame') + ':{{parray[ndx].frameid}}@{{prettifyTimeSec(parray[ndx].time)}}

', title: $translate.instant('kImages') + " (" + $translate.instant($scope.typeOfFrames) + ")", subTitle: 'use left and right arrows to change', @@ -580,7 +601,8 @@ angular.module('zmApp.controllers') { text: '', type: 'button-assertive button-small ion-camera', - onTap: function (e) { + onTap: function(e) + { e.preventDefault(); saveNow($scope.imgsrc, r, parray[$scope.ndx].fname); @@ -591,15 +613,18 @@ angular.module('zmApp.controllers') // left 1 text: '', type: 'button-small button-energized ion-chevron-left', - onTap: function (e) { + onTap: function(e) + { // look for next frame that matches the type of frame // we are showing (all or diff timestamps); // console.log ("TYPE OF FRAMES: " + $scope.typeOfFrames); var nndx = null; var alltype = $translate.instant('kShowAllFrames'); - for (var i = $scope.ndx - 1; i >= 0; i--) { - if ($scope.parray[i].type == $scope.typeOfFrames || $scope.typeOfFrames == alltype) { + for (var i = $scope.ndx - 1; i >= 0; i--) + { + if ($scope.parray[i].type == $scope.typeOfFrames || $scope.typeOfFrames == alltype) + { nndx = i; break; } @@ -607,25 +632,26 @@ angular.module('zmApp.controllers') if (nndx == null) nndx = $scope.ndx; $scope.ndx = nndx; - if ($scope.imode == 'path') { + if ($scope.imode == 'path') + { $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname; - } else { + } + else + { $scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id; } - - e.preventDefault(); - } }, { // right 1 text: '', type: 'button-small button-energized ion-chevron-right', - onTap: function (e) { + onTap: function(e) + { // look for next frame that matches the type of frame // we are showing (all or diff timestamps); @@ -633,9 +659,11 @@ angular.module('zmApp.controllers') // console.log ("TYPE OF FRAMES: " + $scope.typeOfFrames); var nndx = null; var alltype = $translate.instant('kShowAllFrames'); - for (var i = $scope.ndx + 1; i < $scope.parray.length; i++) { + for (var i = $scope.ndx + 1; i < $scope.parray.length; i++) + { //console.log ("Comparing: " +$scope.parray[i].type +" to " + $scope.typeOfFrames); - if ($scope.parray[i].type == $scope.typeOfFrames || $scope.typeOfFrames == alltype) { + if ($scope.parray[i].type == $scope.typeOfFrames || $scope.typeOfFrames == alltype) + { nndx = i; break; } @@ -643,67 +671,63 @@ angular.module('zmApp.controllers') if (nndx == null) nndx = $scope.ndx; $scope.ndx = nndx; - if ($scope.imode == 'path') { + if ($scope.imode == 'path') + { $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname; - } else { + } + else + { $scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id; } e.preventDefault(); - } }, - - { text: '', type: 'button-positive button-small ion-checkmark-round', - onTap: function (e) { - + onTap: function(e) { } - }] + } + ] }); - - - }; - - - - - - $scope.toggleTypeOfAlarms = function () { + $scope.toggleTypeOfAlarms = function() + { // "kShowAllFrames" : "all", // "kShowTimeDiffFrames" : "different timestamps" - if ($scope.typeOfFrames == $translate.instant('kShowAllFrames')) { + if ($scope.typeOfFrames == $translate.instant('kShowAllFrames')) + { $scope.typeOfFrames = $translate.instant('kShowTimeDiffFrames'); - } else { + } + else + { $scope.typeOfFrames = $translate.instant('kShowAllFrames'); } }; - // not explictly handling error --> I have a default "No events found" message // displayed in the template if events list is null //-------------------------------------------------------------------------- // This is what the pullup bar calls depending on what range is specified //-------------------------------------------------------------------------- - $scope.showEvents = function (val, unit, monitorId) { + $scope.showEvents = function(val, unit, monitorId) + { NVRDataModel.debug("ShowEvents called with val:" + val + " unit:" + unit + " for Monitor:" + monitorId); - $ionicHistory.nextViewOptions({ + $ionicHistory.nextViewOptions( + { disableBack: true }); - // we have to convert from and to, to server time var mToDate = moment().tz(NVRDataModel.getTimeZoneNow()); var mFromDate = moment().subtract(parseInt(val), unit).tz(NVRDataModel.getTimeZoneNow()); @@ -728,16 +752,17 @@ angular.module('zmApp.controllers') .format("YYYY-MM-DD") + " " + mToDate .format("HH:mm:ss"); - // console.log("**************From String: " + $rootScope.fromString); // console.log("**************To String: " + $rootScope.toString); // reloading - may solve https://github.com/pliablepixels/zmNinja/issues/36 // if you are in the same mid event page $state.go won't work - $state.go("events", { + $state.go("events", + { "id": monitorId, - "playEvent":false - }, { + "playEvent": false + }, + { reload: true }); }; @@ -745,17 +770,22 @@ angular.module('zmApp.controllers') //---------------------------------------------------------------- // Alarm notification handling //---------------------------------------------------------------- - $scope.handleAlarms = function () { + $scope.handleAlarms = function() + { $rootScope.isAlarm = !$rootScope.isAlarm; - if (!$rootScope.isAlarm) { + if (!$rootScope.isAlarm) + { $rootScope.alarmCount = "0"; - $ionicHistory.nextViewOptions({ + $ionicHistory.nextViewOptions( + { disableBack: true }); - $state.go("events", { + $state.go("events", + { "id": 0, - "playEvent":false - }, { + "playEvent": false + }, + { reload: true }); return; @@ -765,7 +795,8 @@ angular.module('zmApp.controllers') //-------------------------------------------------------------------------- // Takes care of deleting individual events //-------------------------------------------------------------------------- - $scope.deleteEvent = function (id, itemid) { + $scope.deleteEvent = function(id, itemid) + { //$scope.eventList.showDelete = false; //curl -XDELETE http://server/zm/api/events/1.json var loginData = NVRDataModel.getLogin(); @@ -773,14 +804,16 @@ angular.module('zmApp.controllers') NVRDataModel.debug("DeleteEvent: ID=" + id + " item=" + itemid); NVRDataModel.log("Delete event " + apiDelete); - $ionicLoading.show({ + $ionicLoading.show( + { template: "{{'kDeletingEvent' | translate}}...", noBackdrop: true, duration: zm.httpTimeout }); $http.delete(apiDelete) - .success(function (data) { + .success(function(data) + { $ionicLoading.hide(); NVRDataModel.debug("delete success: " + JSON.stringify(data)); NVRDataModel.displayBanner('info', [$translate.instant('kDeleteEventSuccess')], 2000, 2000); @@ -789,30 +822,34 @@ angular.module('zmApp.controllers') //doRefresh(); }) - .error(function (data) { + .error(function(data) + { $ionicLoading.hide(); NVRDataModel.debug("delete error: " + JSON.stringify(data)); NVRDataModel.displayBanner('error', [$translate.instant('kDeleteEventError1'), $translate.instant('kDeleteEventError2')]); }); - }; //------------------------------------------------ // Tapping on the filter sign lets you reset it //------------------------------------------------- - $scope.filterTapped = function () { + $scope.filterTapped = function() + { //console.log("FILTER TAPPED"); var myFrom = moment($rootScope.fromString).format("MMM/DD/YYYY " + NVRDataModel.getTimeFormat()).toString(); var toString = moment($rootScope.toString).format("MMM/DD/YYYY " + NVRDataModel.getTimeFormat()).toString(); - $rootScope.zmPopup = $ionicPopup.confirm({ + $rootScope.zmPopup = $ionicPopup.confirm( + { title: $translate.instant('kFilterSettings'), template: $translate.instant('kFilterEventsBetween1') + ':
' + myFrom + " " + $translate.instant('kTo') + " " + toString + '
' + $translate.instant('kFilterEventsBetween2') }); - $rootScope.zmPopup.then(function (res) { - if (res) { + $rootScope.zmPopup.then(function(res) + { + if (res) + { NVRDataModel.log("Filter reset requested in popup"); $rootScope.isEventFilterOn = false; $rootScope.fromDate = ""; @@ -821,15 +858,19 @@ angular.module('zmApp.controllers') $rootScope.toTime = ""; $rootScope.fromString = ""; $rootScope.toString = ""; - $ionicHistory.nextViewOptions({ + $ionicHistory.nextViewOptions( + { disableBack: true }); - $state.go("events", { + $state.go("events", + { "id": 0, - "playEvent":false + "playEvent": false }); return; - } else { + } + else + { NVRDataModel.log("Filter reset cancelled in popup"); } }); @@ -841,40 +882,44 @@ angular.module('zmApp.controllers') // data for events ranges summaries using the consolveEvents facility of ZM //-------------------------------------------------------------------------- - $scope.footerExpand = function () { - footerExpand(); + $scope.footerExpand = function() + { + footerExpand(); }; function footerExpand() { - //https://server/zm/api/events/consoleEvents/5%20minute.json + //https://server/zm/api/events/consoleEvents/5%20minute.json var ld = NVRDataModel.getLogin(); - var af = "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0); + var af = "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0); var apiurl = ld.apiurl + "/events/consoleEvents/1%20hour" + af + ".json"; NVRDataModel.debug("consoleEvents API:" + apiurl); - $http.get(apiurl) - .success(function (data) { + .success(function(data) + { NVRDataModel.debug(JSON.stringify(data)); $scope.hours = []; var p = data.results; - for (var key in data.results) { - - + for (var key in data.results) + { - if (p.hasOwnProperty(key)) { + if (p.hasOwnProperty(key)) + { var idfound = true; //console.log ("PERSIST IS " + ld.persistMontageOrder); - if (ld.persistMontageOrder) { + if (ld.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors) ) { - // console.log ("Authorizing "+$scope.monitors[ii].Monitor.Name); + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors)) + { + // console.log ("Authorizing "+$scope.monitors[ii].Monitor.Name); idfound = true; break; } @@ -882,7 +927,8 @@ angular.module('zmApp.controllers') } //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); if (idfound) - $scope.hours.push({ + $scope.hours.push( + { monitor: NVRDataModel.getMonitorName(key), events: p[key], mid: key @@ -892,21 +938,26 @@ angular.module('zmApp.controllers') } }); - apiurl = ld.apiurl + "/events/consoleEvents/1%20day" + af + ".json"; NVRDataModel.debug("consoleEvents API:" + apiurl); $http.get(apiurl) - .success(function (data) { + .success(function(data) + { NVRDataModel.debug(JSON.stringify(data)); $scope.days = []; var p = data.results; - for (var key in data.results) { - if (p.hasOwnProperty(key)) { + for (var key in data.results) + { + if (p.hasOwnProperty(key)) + { var idfound = true; - if (ld.persistMontageOrder) { + if (ld.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors)) { + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors)) + { idfound = true; break; } @@ -915,7 +966,8 @@ angular.module('zmApp.controllers') //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); if (idfound) //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); - $scope.days.push({ + $scope.days.push( + { monitor: NVRDataModel.getMonitorName(key), events: p[key], mid: key @@ -925,23 +977,27 @@ angular.module('zmApp.controllers') } }); - - apiurl = ld.apiurl + "/events/consoleEvents/1%20week" + af + ".json"; NVRDataModel.debug("consoleEvents API:" + apiurl); $http.get(apiurl) - .success(function (data) { + .success(function(data) + { NVRDataModel.debug(JSON.stringify(data)); $scope.weeks = []; var p = data.results; - for (var key in data.results) { - if (p.hasOwnProperty(key)) { + for (var key in data.results) + { + if (p.hasOwnProperty(key)) + { var idfound = true; - if (ld.persistMontageOrder) { + if (ld.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key)|| showHiddenMonitors)) { + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors)) + { idfound = true; break; } @@ -950,7 +1006,8 @@ angular.module('zmApp.controllers') //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); if (idfound) //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); - $scope.weeks.push({ + $scope.weeks.push( + { monitor: NVRDataModel.getMonitorName(key), events: p[key], mid: key @@ -960,23 +1017,28 @@ angular.module('zmApp.controllers') } }); - apiurl = ld.apiurl + "/events/consoleEvents/1%20month" + af + ".json"; NVRDataModel.debug("consoleEvents API:" + apiurl); $http.get(apiurl) - .success(function (data) { + .success(function(data) + { NVRDataModel.debug(JSON.stringify(data)); $scope.months = []; var p = data.results; - for (var key in data.results) { - if (p.hasOwnProperty(key)) { + for (var key in data.results) + { + if (p.hasOwnProperty(key)) + { var idfound = true; var ld = NVRDataModel.getLogin(); - if (ld.persistMontageOrder) { + if (ld.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key)|| showHiddenMonitors)) { + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == key && (NVRDataModel.isNotHidden(key) || showHiddenMonitors)) + { idfound = true; break; } @@ -985,7 +1047,8 @@ angular.module('zmApp.controllers') //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); if (idfound) //console.log(NVRDataModel.getMonitorName(key) + " -> " + p[key]); - $scope.months.push({ + $scope.months.push( + { monitor: NVRDataModel.getMonitorName(key), events: p[key], mid: key @@ -997,16 +1060,21 @@ angular.module('zmApp.controllers') } - $scope.openMenu = function () { + $scope.openMenu = function() + { $ionicSideMenuDelegate.toggleLeft(); }; - $scope.scrollPosition = function () { + $scope.scrollPosition = function() + { var scrl = parseFloat($ionicScrollDelegate.$getByHandle("mainScroll").getScrollPosition().top); - var item = Math.round(scrl / eventsListDetailsHeight ); - if ($scope.events == undefined || !$scope.events.length || $scope.events[item] == undefined) { + var item = Math.round(scrl / eventsListDetailsHeight); + if ($scope.events == undefined || !$scope.events.length || $scope.events[item] == undefined) + { return ""; - } else { + } + else + { //return prettifyDate($scope.events[item].Event.StartTime); return ($scope.events[item].Event.humanizeTime); } @@ -1016,7 +1084,8 @@ angular.module('zmApp.controllers') //------------------------------------------------------------------------- // called when user switches to background //------------------------------------------------------------------------- - function onPause() { + function onPause() + { NVRDataModel.debug("EventCtrl:onpause called"); if ($scope.popover) $scope.popover.remove(); @@ -1024,66 +1093,70 @@ angular.module('zmApp.controllers') //------------------------------------------------------------------------- // Pads the filename with leading 0s, depending on ZM_IMAGE_DIGITS //------------------------------------------------------------------------- - function padToN(number, digits) { + function padToN(number, digits) + { var i; var stringMax = ""; var stringLeading = ""; - for (i = 1; i <= digits; i++) { + for (i = 1; i <= digits; i++) + { stringMax = stringMax + "9"; if (i != digits) stringLeading = stringLeading + "0"; } var numMax = parseInt(stringMax); - if (number <= numMax) { + if (number <= numMax) + { number = (stringLeading + number).slice(-digits); } //console.log ("PADTON: returning " + number); return number; } - //------------------------------------------------------------------------- // FIXME: Are we using this? //------------------------------------------------------------------------- - $scope.disableSlide = function () { + $scope.disableSlide = function() + { NVRDataModel.debug("EventCtrl:DisableSlide called"); $ionicSlideBoxDelegate.$getByHandle("eventSlideBox").enableSlide(false); }; - - - //------------------------------------------------------------------------- // This function is called when a user enables or disables // scrub view for an event. //------------------------------------------------------------------------- - $scope.toggleGroupScrub = function (event, ndx, frames) { + $scope.toggleGroupScrub = function(event, ndx, frames) + { $scope.groupType = "scrub"; toggleGroup(event, ndx, frames, $scope.groupType); }; - $scope.toggleGroupAlarms = function (event, ndx, frames) { + $scope.toggleGroupAlarms = function(event, ndx, frames) + { $scope.groupType = "alarms"; toggleGroup(event, ndx, frames, $scope.groupType); }; - function toggleGroup(event, ndx, frames, groupType) { - + function toggleGroup(event, ndx, frames, groupType) + { // If we are here and there is a record of a previous scroll // then we need to scroll back to hide that view - if (scrollbynumber) { + if (scrollbynumber) + { $ionicScrollDelegate.$getByHandle("mainScroll").scrollBy(0, -1 * scrollbynumber, true); scrollbynumber = 0; } - if (oldEvent && event != oldEvent) { + if (oldEvent && event != oldEvent) + { NVRDataModel.debug("EventCtrl:Old event scrub will hide now"); oldEvent.Event.ShowScrub = false; - oldEvent.Event.height = eventsListDetailsHeight ; + oldEvent.Event.height = eventsListDetailsHeight; oldEvent = ""; } @@ -1095,14 +1168,16 @@ angular.module('zmApp.controllers') if (event.Event.ShowScrub == true) // turn on display now { - if (groupType == 'alarms') { + if (groupType == 'alarms') + { $scope.alarm_images = []; event.Event.height = (eventsListDetailsHeight + eventsListScrubHeight); $ionicScrollDelegate.resize(); var myurl = loginData.apiurl + '/events/' + event.Event.Id + ".json"; NVRDataModel.log("API for event details" + myurl); $http.get(myurl) - .success(function (data) { + .success(function(data) + { $scope.FrameArray = data.event.Frame; // $scope.slider_options.scale=[]; @@ -1110,18 +1185,24 @@ angular.module('zmApp.controllers') var i; var timestamp = null; - for (i = 0; i < data.event.Frame.length; i++) { - if (data.event.Frame[i].Type == "Alarm") { + for (i = 0; i < data.event.Frame.length; i++) + { + if (data.event.Frame[i].Type == "Alarm") + { //console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length); var atype; - if (timestamp != data.event.Frame[i].TimeStamp) { + if (timestamp != data.event.Frame[i].TimeStamp) + { atype = $translate.instant('kShowTimeDiffFrames'); - } else { + } + else + { atype = $translate.instant('kShowAllFrames'); } - $scope.alarm_images.push({ + $scope.alarm_images.push( + { type: atype, id: data.event.Frame[i].Id, frameid: data.event.Frame[i].FrameId, @@ -1137,7 +1218,8 @@ angular.module('zmApp.controllers') //console.log (JSON.stringify(data)); }) - .error(function (err) { + .error(function(err) + { NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err)); NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']); }); @@ -1157,31 +1239,38 @@ angular.module('zmApp.controllers') realtime: true, step: 1, className: "mySliderClass", - callback: function (value, released) { + callback: function(value, released) + { //console.log("CALLBACK"+value+released); $ionicScrollDelegate.freezeScroll(!released); //NVRDataModel.debug("EventCtrl: freezeScroll called with " + !released); - }, //modelLabels:function(val) {return "";}, - css: { - background: { + css: + { + background: + { "background-color": "silver" }, - before: { + before: + { "background-color": "purple" }, - default: { + default: + { "background-color": "white" }, // default value: 1px - after: { + after: + { "background-color": "green" }, // zone after default value - pointer: { + pointer: + { "background-color": "red" }, // circle pointer - range: { + range: + { "background-color": "red" } // use it if double value }, @@ -1197,58 +1286,58 @@ angular.module('zmApp.controllers') $scope.slides = []; var i; - if (event.Event.imageMode == 'path') { + if (event.Event.imageMode == 'path') + { NVRDataModel.debug("EventCtrl: found " + frames + " frames to scrub"); - - - for (i = 1; i <= frames; i++) { + for (i = 1; i <= frames; i++) + { var fname = padToN(i, eventImageDigits) + "-capture.jpg"; - - - $scope.slides.push({ + $scope.slides.push( + { id: i, img: fname }); } - } else // we need fids + } + else // we need fids { var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json"; NVRDataModel.log("API for event details" + myurl_frames); $http.get(myurl_frames) - .success(function (data) { + .success(function(data) + { $scope.FrameArray = data.event.Frame; // $scope.slider_options.scale=[]; //$scope.slider_options.scale = []; var i; - for (i = 0; i < data.event.Frame.length; i++) { - + for (i = 0; i < data.event.Frame.length; i++) + { //console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length); - $scope.slides.push({ + $scope.slides.push( + { id: data.event.Frame[i].Id, frameid: data.event.Frame[i].FrameId, }); - } //console.log (JSON.stringify(data)); }) - .error(function (err) { + .error(function(err) + { NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err)); NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]); }); } - - // now get event details to show alarm frames loginData = NVRDataModel.getLogin(); @@ -1270,7 +1359,7 @@ angular.module('zmApp.controllers') { src: $sce.trustAsResourceUrl(videoURL), type: "video/mp4" - } + } ], @@ -1278,25 +1367,30 @@ angular.module('zmApp.controllers') }; - var myurl2 = loginData.apiurl + '/events/' + event.Event.Id + ".json"; NVRDataModel.log("API for event details" + myurl2); $http.get(myurl2) - .success(function (data) { + .success(function(data) + { $scope.FrameArray = data.event.Frame; // $scope.slider_options.scale=[]; $scope.slider_options.scale = []; var i; - for (i = 0; i < data.event.Frame.length; i++) { - if (data.event.Frame[i].Type == "Alarm") { + for (i = 0; i < data.event.Frame.length; i++) + { + if (data.event.Frame[i].Type == "Alarm") + { //console.log ("**ALARM AT " + i + "of " + data.event.Frame.length); - $scope.slider_options.scale.push({ + $scope.slider_options.scale.push( + { val: data.event.Frame[i].FrameId, label: ' ' }); - } else { + } + else + { //$scope.slider_options.scale.push(' '); } @@ -1304,12 +1398,12 @@ angular.module('zmApp.controllers') //console.log (JSON.stringify(data)); }) - .error(function (err) { + .error(function(err) + { NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err)); NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]); }); - oldEvent = event; $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111; var elem = angular.element(document.getElementById("item-" + ndx)); @@ -1331,13 +1425,15 @@ angular.module('zmApp.controllers') } // end of groupType == scrub } // end of ShowScrub == true - else { + else + { // $ionicScrollDelegate.freezeScroll(false); $ionicSideMenuDelegate.canDragContent(true); event.Event.height = eventsListDetailsHeight; $ionicScrollDelegate.resize(); - if (scrollbynumber) { + if (scrollbynumber) + { $ionicScrollDelegate.$getByHandle("mainScroll").scrollBy(0, -1 * scrollbynumber, true); scrollbynumber = 0; } @@ -1346,15 +1442,18 @@ angular.module('zmApp.controllers') } - $scope.closeIfOpen = function (event) { - if (event != undefined) { + $scope.closeIfOpen = function(event) + { + if (event != undefined) + { if (event.Event.ShowScrub) toggleGroup(event); } }; - $scope.isGroupShown = function (event) { + $scope.isGroupShown = function(event) + { // console.log ("IS SHOW INDEX is " + ndx); //console.log ("SHOW GROUP IS " + showGroup); @@ -1365,7 +1464,8 @@ angular.module('zmApp.controllers') //--------------------------------------------------- // reload view //--------------------------------------------------- - $scope.reloadView = function () { + $scope.reloadView = function() + { // All we really need to do here is change the random token // in the image src and it will refresh. No need to reload the view // and if you did reload the view, it would go back to events list @@ -1373,7 +1473,8 @@ angular.module('zmApp.controllers') //console.log("*** Refreshing Modal view ***"); //$state.go($state.current, {}, {reload: true}); $rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111; - $ionicLoading.show({ + $ionicLoading.show( + { template: $translate.instant('kRefreshedView'), noBackdrop: true, duration: 3000 @@ -1384,17 +1485,20 @@ angular.module('zmApp.controllers') //--------------------------------------------------- // when you tap a list entry - to break search loop //--------------------------------------------------- - $scope.tapped = function () { + $scope.tapped = function() + { // console.log("*** TAPPED ****"); // if he tapped, the we are not infinite loading on ion-infinite - if (enableLoadMore == false) { + if (enableLoadMore == false) + { moreEvents = true; enableLoadMore = true; // console.log("REMOVING ARTIFICAL LOAD MORE BLOCK"); } }; - $scope.$on('$ionicView.loaded', function () { + $scope.$on('$ionicView.loaded', function() + { // console.log("**VIEW ** Events Ctrl Loaded"); }); @@ -1405,28 +1509,33 @@ angular.module('zmApp.controllers') // reset power state on exit as if it is called after we enter another // state, that effectively overwrites current view power management needs //------------------------------------------------------------------------ - $scope.$on('$ionicView.enter', function () { + $scope.$on('$ionicView.enter', function() + { // console.log("**VIEW ** Events Ctrl Entered"); NVRDataModel.setAwake(false); - EventServer.sendMessage('push', { + EventServer.sendMessage('push', + { type: 'badge', badge: 0, }); - $ionicPopover.fromTemplateUrl('templates/events-popover.html', { + $ionicPopover.fromTemplateUrl('templates/events-popover.html', + { scope: $scope, - }).then(function (popover) { + }).then(function(popover) + { $scope.popover = popover; }); - - //reset badge count - if (window.cordova && window.cordova.plugins.notification) { - $cordovaBadge.set(0).then(function () { + if (window.cordova && window.cordova.plugins.notification) + { + $cordovaBadge.set(0).then(function() + { // You have permission, badge set. - }, function (err) { + }, function(err) + { NVRDataModel.debug("app does not have badge permissions. Please check your phone notification settings"); // You do not have permission. }); @@ -1436,14 +1545,17 @@ angular.module('zmApp.controllers') }); - $scope.$on('$ionicView.leave', function () { + $scope.$on('$ionicView.leave', function() + { //console.log("**VIEW ** Events Ctrl Left"); }); - $scope.$on('$ionicView.unloaded', function () { + $scope.$on('$ionicView.unloaded', function() + { //console.log("**VIEW ** Events Ctrl Unloaded"); //console.log("*** MODAL ** Destroying modal too"); - if ($scope.modal !== undefined) { + if ($scope.modal !== undefined) + { $scope.modal.remove(); } @@ -1452,7 +1564,8 @@ angular.module('zmApp.controllers') //--------------------------------------------------- // used to hide loading image toast //--------------------------------------------------- - $scope.finishedLoadingImage = function (ndx) { + $scope.finishedLoadingImage = function(ndx) + { // console.log("*** Events image FINISHED loading index: "+ndx+"***"); $ionicLoading.hide(); }; @@ -1460,33 +1573,36 @@ angular.module('zmApp.controllers') //--------------------------------------------------- // //--------------------------------------------------- - $scope.clearSearch = function () { + $scope.clearSearch = function() + { $scope.search.text = ""; }; //--------------------------------------------------- // Called when user toggles search //--------------------------------------------------- - $scope.searchClicked = function () { + $scope.searchClicked = function() + { $scope.showSearch = !$scope.showSearch; // this helps greatly in repeat scroll gets if ($scope.showSearch == false) $scope.search.text = ""; //console.log("**** Setting search view to " + $scope.showSearch + " ****"); - if (enableLoadMore == false && $scope.showSearch == false) { + if (enableLoadMore == false && $scope.showSearch == false) + { moreEvents = true; enableLoadMore = true; //console.log("REMOVING ARTIFICAL LOAD MORE BLOCK"); } }; - //-------------------------------------------------------- // utility function //-------------------------------------------------------- - function computeRelativePath(event) { + function computeRelativePath(event) + { var relativePath = ""; var loginData = NVRDataModel.getLogin(); var str = event.Event.StartTime; @@ -1511,7 +1627,8 @@ angular.module('zmApp.controllers') // utility function //-------------------------------------------------------- - function computeBasePath(event) { + function computeBasePath(event) + { var basePath = ""; var loginData = NVRDataModel.getLogin(); var str = event.Event.StartTime; @@ -1533,43 +1650,44 @@ angular.module('zmApp.controllers') return basePath; } - $scope.modalGraph = function () { - $ionicModal.fromTemplateUrl('templates/events-modalgraph.html', { + $scope.modalGraph = function() + { + $ionicModal.fromTemplateUrl('templates/events-modalgraph.html', + { scope: $scope, // give ModalCtrl access to this scope animation: 'slide-in-up', id: 'modalgraph', }) - .then(function (modal) { + .then(function(modal) + { $scope.modal = modal; - - - $scope.modal.show(); }); }; - $scope.analyzeEvent = function (ev) { + $scope.analyzeEvent = function(ev) + { $scope.event = ev; - $ionicModal.fromTemplateUrl('templates/timeline-modal.html', { + $ionicModal.fromTemplateUrl('templates/timeline-modal.html', + { scope: $scope, // give ModalCtrl access to this scope animation: 'slide-in-up', id: 'analyze', }) - .then(function (modal) { + .then(function(modal) + { $scope.modal = modal; - - - $scope.modal.show(); }); }; - $scope.$on('modal.removed', function (e, m) { + $scope.$on('modal.removed', function(e, m) + { if (m.id != 'footage') return; @@ -1588,7 +1706,8 @@ angular.module('zmApp.controllers') //earlier won't work //-------------------------------------------------------- - $scope.openModal = function (event) { + $scope.openModal = function(event) + { NVRDataModel.debug("unbinding eventCtrl watchers as modal has its own"); ionRangeWatcher(); @@ -1602,17 +1721,18 @@ angular.module('zmApp.controllers') $scope.currentEvent = event; $scope.followSameMonitor = ($stateParams.id == "0") ? "0" : "1"; - - - $ionicModal.fromTemplateUrl('templates/events-modal.html', { + $ionicModal.fromTemplateUrl('templates/events-modal.html', + { scope: $scope, animation: 'slide-in-up', id: 'footage', }) - .then(function (modal) { + .then(function(modal) + { $scope.modal = modal; - $ionicLoading.show({ + $ionicLoading.show( + { template: $translate.instant('kPleaseWait') + "...", noBackdrop: true, duration: 10000 @@ -1622,8 +1742,6 @@ angular.module('zmApp.controllers') var ld = NVRDataModel.getLogin(); - - }); }; @@ -1632,10 +1750,12 @@ angular.module('zmApp.controllers') //We need to destroy because we are instantiating // it on open //-------------------------------------------------------- - $scope.closeModal = function () { + $scope.closeModal = function() + { NVRDataModel.debug(">>>EventCtrl:Close & Destroy Modal"); NVRDataModel.setAwake(false); - if ($scope.modal !== undefined) { + if ($scope.modal !== undefined) + { $scope.modal.remove(); } @@ -1645,9 +1765,11 @@ angular.module('zmApp.controllers') //Cleanup the modal when we're done with it // I Don't think it ever comes here //-------------------------------------------------------- - $scope.$on('$destroy', function () { + $scope.$on('$destroy', function() + { //console.log("Destroy Modal"); - if ($scope.modal !== undefined) { + if ($scope.modal !== undefined) + { $scope.modal.remove(); } if ($scope.popover !== undefined) @@ -1658,18 +1780,21 @@ angular.module('zmApp.controllers') // used by infinite scrolling to see if we can get more //-------------------------------------------------------- - $scope.moreDataCanBeLoaded = function () { + $scope.moreDataCanBeLoaded = function() + { return moreEvents; }; //-------------------------------------------------------- // stop searching for more data //-------------------------------------------------------- - $scope.cancelSearch = function () { + $scope.cancelSearch = function() + { $ionicLoading.hide(); //Or whatever action you want to preform enableLoadMore = false; //console.log("**** CANCELLED ****"); - $ionicLoading.show({ + $ionicLoading.show( + { template: $translate.instant('kSearchCancelled'), animation: 'fade-in', showBackdrop: true, @@ -1678,27 +1803,28 @@ angular.module('zmApp.controllers') showDelay: 0 }); - }; //-------------------------------------------------------- // loads next page of events //-------------------------------------------------------- - - function loadMore() { + function loadMore() + { // 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)) { + if ((eventsPage <= 0) && (pageLoaded)) + { moreEvents = false; //console.log("*** At Page " + eventsPage + ", not proceeding"); return; } - if (!enableLoadMore) { + if (!enableLoadMore) + { moreEvents = false; // Don't ion-scroll till enableLoadMore is true; $scope.$broadcast('scroll.infiniteScrollComplete'); @@ -1707,9 +1833,11 @@ angular.module('zmApp.controllers') } var loadingStr = ""; - if ($scope.search.text != "") { + if ($scope.search.text != "") + { var toastStr = $translate.instant('kToastSearchingPage') + eventsPage; - $ionicLoading.show({ + $ionicLoading.show( + { maxwidth: 100, scope: $scope, template: '' @@ -1726,20 +1854,25 @@ angular.module('zmApp.controllers') nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss"); NVRDataModel.getEvents($scope.id, eventsPage, loadingStr, nolangFrom, nolangTo) - .then(function (data) { + .then(function(data) + { var loginData = NVRDataModel.getLogin(); // console.log("Got new page of events with Page=" + eventsPage); var myevents = data; - for (var i = 0; i < myevents.length; i++) { + for (var i = 0; i < myevents.length; i++) + { var idfound = true; var ld = NVRDataModel.getLogin(); - if (ld.persistMontageOrder) { + if (ld.persistMontageOrder) + { idfound = false; - for (var ii = 0; ii < $scope.monitors.length; ii++) { - if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId && (NVRDataModel.isNotHidden(myevents[i].Event.MonitorId)|| showHiddenMonitors)) { + for (var ii = 0; ii < $scope.monitors.length; ii++) + { + if ($scope.monitors[ii].Monitor.Id == myevents[i].Event.MonitorId && (NVRDataModel.isNotHidden(myevents[i].Event.MonitorId) || showHiddenMonitors)) + { //console.log ( $scope.monitors[ii].Monitor.Id + " MATCHES " + myevents[i].Event.MonitorId); idfound = true; @@ -1749,7 +1882,6 @@ angular.module('zmApp.controllers') } } - myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime); myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId); // now construct base path @@ -1773,7 +1905,8 @@ angular.module('zmApp.controllers') $scope.$broadcast('scroll.infiniteScrollComplete'); }, - function (error) { + function(error) + { // console.log("*** No More Events to Load, Stop Infinite Scroll ****"); moreEvents = false; $scope.$broadcast('scroll.infiniteScrollComplete'); @@ -1781,13 +1914,14 @@ angular.module('zmApp.controllers') }); } - $scope.loadMore = function () { + $scope.loadMore = function() + { loadMore(); }; - $scope.toggleMinAlarmFrameCount = function () { - + $scope.toggleMinAlarmFrameCount = function() + { var ld = NVRDataModel.getLogin(); @@ -1798,54 +1932,57 @@ angular.module('zmApp.controllers') doRefresh(); }; - //-------------------------------------- // formats events dates in a nice way //--------------------------------------- - - function humanizeTime(str) { + function humanizeTime(str) + { //console.log ("Time:"+str+" TO LOCAL " + moment(str).local().toString()); //if (NVRDataModel.getLogin().useLocalTimeZone) - return moment.tz(str, NVRDataModel.getTimeZoneNow()).fromNow(); - // else - // return moment(str).fromNow(); - + return moment.tz(str, NVRDataModel.getTimeZoneNow()).fromNow(); + // else + // return moment(str).fromNow(); + } - $scope.prettifyDate = function (str) { + $scope.prettifyDate = function(str) + { if (NVRDataModel.getLogin().useLocalTimeZone) return moment.tz(str, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()).format('MMM Do'); else - return moment(str).format('MMM Do'); + return moment(str).format('MMM Do'); }; - function prettifyDate(str) { + function prettifyDate(str) + { if (NVRDataModel.getLogin().useLocalTimeZone) return moment.tz(str, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()).format('MMM Do'); else return moment(str).format('MMM Do'); } - $scope.prettifyTime = function (str) { + $scope.prettifyTime = function(str) + { if (NVRDataModel.getLogin().useLocalTimeZone) return moment.tz(str, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()).format(NVRDataModel.getTimeFormat()); - else + else return moment(str).format(NVRDataModel.getTimeFormat()); }; - $scope.prettifyTimeSec = function (str) { + $scope.prettifyTimeSec = function(str) + { if (NVRDataModel.getLogin().useLocalTimeZone) return moment.tz(str, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()).format(NVRDataModel.getTimeFormatSec()); else return moment(str).format(NVRDataModel.getTimeFormatSec()); }; - - $scope.prettify = function (str) { + $scope.prettify = function(str) + { if (NVRDataModel.getLogin().useLocalTimeZone) return moment.tz(str, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess()).format(NVRDataModel.getTimeFormat() + ', MMMM Do YYYY'); - else + else return moment(str).format(NVRDataModel.getTimeFormat() + ', MMMM Do YYYY'); }; //-------------------------------------------------------- @@ -1856,31 +1993,33 @@ angular.module('zmApp.controllers') // a large list //-------------------------------------------------------- - $scope.dummyDoRefresh = function () { + $scope.dummyDoRefresh = function() + { $scope.$broadcast('scroll.refreshComplete'); }; - - $scope.doRefresh = function () { + $scope.doRefresh = function() + { doRefresh(); }; //dorefresh - function doRefresh() { + function doRefresh() + { // console.log("***Pull to Refresh"); NVRDataModel.debug("Reloading monitors"); var refresh = NVRDataModel.getMonitors(1); - refresh.then(function (data) { + refresh.then(function(data) + { $scope.monitors = data; - - /* var ld = NVRDataModel.getLogin(); - if (ld.persistMontageOrder) { - var tempMon = data; - $scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; - } else { - $scope.monitors = data; - }*/ + /* var ld = NVRDataModel.getLogin(); + if (ld.persistMontageOrder) { + var tempMon = data; + $scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0]; + } else { + $scope.monitors = data; + }*/ getInitialEvents(); moreEvents = true; @@ -1888,4 +2027,4 @@ angular.module('zmApp.controllers') }); } -}]); \ No newline at end of file +}]); -- cgit v1.2.3 From 9dc36815cdf21287a597842d6653b3f652f5d85c Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 18 Nov 2016 16:33:07 -0500 Subject: Experimental and initial version - still has work to go - #379 --- www/js/EventCtrl.js | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 1 deletion(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 7f1c0af0..40c59ab7 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,6 +1,6 @@ /* jshint -W041 */ /* jslint browser: true*/ -/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility */ +/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot */ // This is the controller for Event view. StateParams is if I recall the monitor ID. // This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it @@ -117,6 +117,8 @@ angular.module('zmApp.controllers') { //console.log ("********* BEFORE ENTER"); + // + $scope.gifshotSupported =gifshot.isSupported(); document.addEventListener("pause", onPause, false); //console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id, 10); @@ -792,9 +794,178 @@ angular.module('zmApp.controllers') } }; + // credit:http://stackoverflow.com/a/20151856/1361529 + function base64toBlob(base64Data, contentType) + { + contentType = contentType || ''; + var sliceSize = 1024; + var byteCharacters = atob(base64Data); + var bytesLength = byteCharacters.length; + var slicesCount = Math.ceil(bytesLength / sliceSize); + var byteArrays = new Array(slicesCount); + + for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) + { + var begin = sliceIndex * sliceSize; + var end = Math.min(begin + sliceSize, bytesLength); + + var bytes = new Array(end - begin); + for (var offset = begin, i = 0; offset < end; ++i, ++offset) + { + bytes[i] = byteCharacters[offset].charCodeAt(0); + } + byteArrays[sliceIndex] = new Uint8Array(bytes); + } + return new Blob(byteArrays, + { + type: contentType + }); + } + + //---------------------------------------------------------- + // create an array of images + // too keep memory manageable, we are only going to pick up alarmed frames + // and that too, max 2fps + // -------------------------------------------------------------- + function prepareImages(e) + { + var d = $q.defer(); + var imglist = []; + var myurl = loginData.apiurl + '/events/' + e.Event.Id + ".json"; + $http.get(myurl) + .then(function(succ) + { + var data = succ.data; + var fps = 0; + var lastTime = ""; + + for (var i = 0; i < data.event.Frame.length; i++) + { + if (data.event.Frame[i].Type == "Alarm") + { + var fname; + if (e.Event.imageMode == 'path') + { + var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg"; + fname = e.Event.baseURL + "/index.php?view=image&path=" + e.Event.relativePath + rfp; + } + else + { + fname = e.Event.baseURL + "/index.php?view=image&fid=" + data.event.Frame[i].Id; + } + + if (data.event.Frame[i].TimeStamp != lastTime || fps < 2) + { + imglist.push(fname); + fps = data.event.Frame[i].TimeStamp != lastTime ? 0 : fps++; + lastTime = data.event.Frame[i].TimeStamp; + } + + } + + } + d.resolve(imglist); + return d.promise; + }, + function(err) + { + d.reject(err); + return d.promise; + }); + return d.promise; + } + + // force image to be 800px. TBD: rotated foo + function adjustAspect(e) + { + var w = 800; + var h = parseInt(e.Event.Height / e.Event.Width * 800.0); + return { + w: w, + h: h + }; + + } + + $scope.downloadAsGif = function(e) + { + $ionicLoading.show( + { + template: $translate.instant('kPleaseWait') + "...", + noBackdrop: true, + //duration: 10000 + }); + + prepareImages(e) + .then(function(imgs) + { + + console.log(JSON.stringify(imgs)); + + var ad = adjustAspect(e); + console.log("SAVING W=" + ad.w + " H=" + ad.h); + + gifshot.createGIF( + { + //'images': ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'] + 'gifWidth': ad.w, + 'gifHeight': ad.h, + 'images': imgs, + 'text': 'zmNinja', + }, function(obj) + { + if (!obj.error) + { + //console.log(obj.image); + + var blob; + + + + + + if ($rootScope.platformOS == 'desktop') + { + + obj.image = obj.image.replace(/data:image\/gif;base64,/, ''); + blob = base64toBlob(obj.image, "image/gif"); + var f = NVRDataModel.getMonitorName(e.Event.MonitorId); + f = f+"-"+e.Event.Id+".gif"; + saveAs(blob, f); + $ionicLoading.hide(); + } + + else + { + NVRDataModel.debug("Saving blob to gallery..."); + var album = "zmNinja"; + cordova.plugins.photoLibrary.saveImage(obj.image, album, + function () {$ionicLoading.hide(); NVRDataModel.debug ("Event saved");}, + function (err) {$ionicLoading.hide(); NVRDataModel.debug("Saving ERROR="+err);}); + + } + + } + else + { + $ionicLoading.hide(); + console.log("Error creating GIF"); + } + }); + }, + function(err) + { + $ionicLoading.hide(); + console.log("Error getting frames"); + } + + ); + }; + //-------------------------------------------------------------------------- // Takes care of deleting individual events //-------------------------------------------------------------------------- + $scope.deleteEvent = function(id, itemid) { //$scope.eventList.showDelete = false; -- cgit v1.2.3 From 662af8fdebb58e9129c437e17471ab3df5c3fddf Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 18 Nov 2016 20:10:25 -0500 Subject: made it work for iOS, also added percentage progress indication #379 --- www/js/EventCtrl.js | 82 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 16 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 40c59ab7..9fa5fed9 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -118,7 +118,7 @@ angular.module('zmApp.controllers') //console.log ("********* BEFORE ENTER"); // - $scope.gifshotSupported =gifshot.isSupported(); + $scope.gifshotSupported = gifshot.isExistingImagesGIFSupported(); document.addEventListener("pause", onPause, false); //console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id, 10); @@ -844,7 +844,9 @@ angular.module('zmApp.controllers') if (data.event.Frame[i].Type == "Alarm") { var fname; - if (e.Event.imageMode == 'path') + console.log ("PATH="+e.Event.imageMode); + //if (e.Event.imageMode == 'path') + if (1) { var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg"; fname = e.Event.baseURL + "/index.php?view=image&path=" + e.Event.relativePath + rfp; @@ -878,8 +880,10 @@ angular.module('zmApp.controllers') // force image to be 800px. TBD: rotated foo function adjustAspect(e) { + + var w = 800; - var h = parseInt(e.Event.Height / e.Event.Width * 800.0); + var h = Math.round(e.Event.Height / e.Event.Width * 800.0); return { w: w, h: h @@ -887,7 +891,44 @@ angular.module('zmApp.controllers') } - $scope.downloadAsGif = function(e) + $scope.permissionsDownload = function(e) + { + if ($rootScope.platformOS == 'desktop') + { + downloadAsGif(e); + } + else + { + + console.log ("in perms"); + cordova.plugins.photoLibrary.getLibrary( + function (library) { downloadAsGif(e);}, + function (err) { + if (err.startsWith('Permission')) { + // call requestAuthorization, and retry + cordova.plugins.photoLibrary.requestAuthorization( + function () { + // User gave us permission to his library, retry reading it! + downloadAsGif(e); + }, + function (err) { + NVRDataModel.log ("ERROR with saving permissions "+err); + // User denied the access + }, // if options not provided, defaults to {read: true}. + { + read: true, + write: true + } + ); + } + // Handle error - it's not permission-related + } + ); + + } + }; + + function downloadAsGif(e) { $ionicLoading.show( { @@ -907,11 +948,16 @@ angular.module('zmApp.controllers') gifshot.createGIF( { - //'images': ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'] + //'images': ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'], 'gifWidth': ad.w, 'gifHeight': ad.h, 'images': imgs, 'text': 'zmNinja', + 'crossOrigin': 'use-credentials', + 'progressCallback': function (cp) + { + var p = Math.round(cp * 100); + $ionicLoading.show({template: $translate.instant('kPleaseWait') + "...("+p+"%)",noBackdrop: true});} }, function(obj) { if (!obj.error) @@ -919,18 +965,14 @@ angular.module('zmApp.controllers') //console.log(obj.image); var blob; - - - - if ($rootScope.platformOS == 'desktop') { - + obj.image = obj.image.replace(/data:image\/gif;base64,/, ''); blob = base64toBlob(obj.image, "image/gif"); var f = NVRDataModel.getMonitorName(e.Event.MonitorId); - f = f+"-"+e.Event.Id+".gif"; + f = f + "-" + e.Event.Id + ".gif"; saveAs(blob, f); $ionicLoading.hide(); } @@ -939,10 +981,18 @@ angular.module('zmApp.controllers') { NVRDataModel.debug("Saving blob to gallery..."); var album = "zmNinja"; - cordova.plugins.photoLibrary.saveImage(obj.image, album, - function () {$ionicLoading.hide(); NVRDataModel.debug ("Event saved");}, - function (err) {$ionicLoading.hide(); NVRDataModel.debug("Saving ERROR="+err);}); - + cordova.plugins.photoLibrary.saveImage(obj.image, album, + function() + { + $ionicLoading.hide(); + NVRDataModel.debug("Event saved"); + }, + function(err) + { + $ionicLoading.hide(); + NVRDataModel.debug("Saving ERROR=" + err); + }); + } } @@ -960,7 +1010,7 @@ angular.module('zmApp.controllers') } ); - }; + } //-------------------------------------------------------------------------- // Takes care of deleting individual events -- cgit v1.2.3 From 53dba9853bd78dac6d1df70baef43f181ca810f4 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 19 Nov 2016 10:26:47 -0500 Subject: restricted gif size to max 50 images. If larger, it will keep deleting subsequent frames till <=50 is reached. Otherwise memory consumption can go nuts. #379 --- www/js/EventCtrl.js | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 9fa5fed9..999f0766 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -825,7 +825,7 @@ angular.module('zmApp.controllers') //---------------------------------------------------------- // create an array of images // too keep memory manageable, we are only going to pick up alarmed frames - // and that too, max 2fps + // and that too, max 1ps // -------------------------------------------------------------- function prepareImages(e) { @@ -842,30 +842,45 @@ angular.module('zmApp.controllers') for (var i = 0; i < data.event.Frame.length; i++) { if (data.event.Frame[i].Type == "Alarm") + //if (1) { var fname; - console.log ("PATH="+e.Event.imageMode); - //if (e.Event.imageMode == 'path') - if (1) + //console.log ("PATH="+e.Event.imageMode); + if (e.Event.imageMode == 'path') + //if (1) { var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg"; - fname = e.Event.baseURL + "/index.php?view=image&path=" + e.Event.relativePath + rfp; + fname = e.Event.baseURL + "/index.php?view=image&width=800&path=" + e.Event.relativePath + rfp; } else { - fname = e.Event.baseURL + "/index.php?view=image&fid=" + data.event.Frame[i].Id; + fname = e.Event.baseURL + "/index.php?view=image&width=800&fid=" + data.event.Frame[i].Id; } - if (data.event.Frame[i].TimeStamp != lastTime || fps < 2) + if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/) { imglist.push(fname); - fps = data.event.Frame[i].TimeStamp != lastTime ? 0 : fps++; + //fps = data.event.Frame[i].TimeStamp != lastTime ? 0 : fps+1; lastTime = data.event.Frame[i].TimeStamp; } } } + + // next up make sure we are not processing more than 100 images + + while (imglist.length > zm.maxGifCount) + { + NVRDataModel.debug ("Too many images: " +imglist.length+", deleting alternate frames to keep it <="+zm.maxGifCount); + + for(var l = 0; l < imglist.length; l++) { + imglist.splice(l+1,2); + if (imglist.length <=zm.maxGifCount) break; + } + + } + d.resolve(imglist); return d.promise; }, @@ -881,7 +896,6 @@ angular.module('zmApp.controllers') function adjustAspect(e) { - var w = 800; var h = Math.round(e.Event.Height / e.Event.Width * 800.0); return { @@ -941,6 +955,7 @@ angular.module('zmApp.controllers') .then(function(imgs) { + console.log ("TOTAL IMAGES TO GIF="+imgs.length); console.log(JSON.stringify(imgs)); var ad = adjustAspect(e); @@ -952,6 +967,8 @@ angular.module('zmApp.controllers') 'gifWidth': ad.w, 'gifHeight': ad.h, 'images': imgs, + 'interval':1, + //'frameDur':5, // 1/2 a sec 'text': 'zmNinja', 'crossOrigin': 'use-credentials', 'progressCallback': function (cp) -- cgit v1.2.3 From 5d69f02c6b8b40047daa5670a812f5965e8a3121 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 19 Nov 2016 13:17:49 -0500 Subject: tweaked sampling quality, changed frames from 50-70 --- www/js/EventCtrl.js | 1 + 1 file changed, 1 insertion(+) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 999f0766..60987392 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -968,6 +968,7 @@ angular.module('zmApp.controllers') 'gifHeight': ad.h, 'images': imgs, 'interval':1, + 'sampleInterval':20, //'frameDur':5, // 1/2 a sec 'text': 'zmNinja', 'crossOrigin': 'use-credentials', -- cgit v1.2.3 From 76b17d856fe7ce6ccaa377e31a53a733920548df Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 19 Nov 2016 17:02:36 -0500 Subject: added playback rate control 1,1.5,2x. #382 --- www/js/EventCtrl.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 60987392..98557f7a 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,6 +1,6 @@ /* jshint -W041 */ /* jslint browser: true*/ -/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot */ +/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, AnimatedGIF */ // This is the controller for Event view. StateParams is if I recall the monitor ID. // This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it @@ -961,6 +961,7 @@ angular.module('zmApp.controllers') var ad = adjustAspect(e); console.log("SAVING W=" + ad.w + " H=" + ad.h); + //AnimatedGIF.setRepeat(null); gifshot.createGIF( { //'images': ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'], @@ -968,6 +969,7 @@ angular.module('zmApp.controllers') 'gifHeight': ad.h, 'images': imgs, 'interval':1, + //'loop':null, 'sampleInterval':20, //'frameDur':5, // 1/2 a sec 'text': 'zmNinja', -- cgit v1.2.3 From 5eac484a44243b7d1a41036f4d25c4f23dcc6e76 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Tue, 22 Nov 2016 18:20:39 -0400 Subject: other video related updates --- www/js/EventCtrl.js | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 98557f7a..dc52846e 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -95,9 +95,7 @@ angular.module('zmApp.controllers') { showHiddenMonitors = false; } - // console.log (">>>>>>>>>>>>>>>>>SHOWHIDDEN IS " + showHiddenMonitors); - - // lets get the abbreviated version of TZ to display + if (NVRDataModel.getLogin().useLocalTimeZone) { $scope.tzAbbr = moment().tz(moment.tz.guess()).zoneAbbr(); @@ -203,22 +201,7 @@ angular.module('zmApp.controllers') $http.get(apiurl) .success(function(data) {}) .error(function(err) {}); - /* - myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime); - myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId); - // now construct base path - - myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId); - myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId); - myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId); - // console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL); - - // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL); - - myevents[i].Event.ShowScrub = false; - myevents[i].Event.BasePath = computeBasePath(myevents[i]); - myevents[i].Event.relativePath = computeRelativePath(myevents[i]); - */ + } function getTextZoomCallback(tz) @@ -948,7 +931,7 @@ angular.module('zmApp.controllers') { template: $translate.instant('kPleaseWait') + "...", noBackdrop: true, - //duration: 10000 + duration: 20000 }); prepareImages(e) @@ -961,10 +944,10 @@ angular.module('zmApp.controllers') var ad = adjustAspect(e); console.log("SAVING W=" + ad.w + " H=" + ad.h); - //AnimatedGIF.setRepeat(null); + gifshot.createGIF( { - //'images': ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'], + 'gifWidth': ad.w, 'gifHeight': ad.h, 'images': imgs, @@ -977,7 +960,7 @@ angular.module('zmApp.controllers') 'progressCallback': function (cp) { var p = Math.round(cp * 100); - $ionicLoading.show({template: $translate.instant('kPleaseWait') + "...("+p+"%)",noBackdrop: true});} + $ionicLoading.show({template: $translate.instant('kPleaseWait') + "...("+p+"%)",noBackdrop: true });} }, function(obj) { if (!obj.error) -- cgit v1.2.3 From d90a9534c04299c7eedefaf4388801722562ad09 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 23 Nov 2016 16:24:56 -0400 Subject: updates for #379 and #383 - you will now see both an MP4 and a GIF icon. MP4 will show only if you are on desktop and using 264 branch --- www/js/EventCtrl.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index dc52846e..830cc8d9 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -399,6 +399,13 @@ angular.module('zmApp.controllers') } + if (myevents[i].Event.imageMode == 'path') + //if (1) + myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo; + else + myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id; + + if (idfound) { $scope.events.push(myevents[i]); @@ -526,6 +533,16 @@ angular.module('zmApp.controllers') } + $scope.mp4warning = function() + { + $ionicPopup.alert( + { + title: $translate.instant('kNote'), + template: "{{'kVideoMp4Warning' | translate }}" + }); + }; + + $scope.showImage = function(p, r, f, fid, e, imode, id, parray, ndx) { var img; @@ -2121,6 +2138,15 @@ angular.module('zmApp.controllers') myevents[i].Event.BasePath = computeBasePath(myevents[i]); myevents[i].Event.relativePath = computeRelativePath(myevents[i]); myevents[i].Event.height = eventsListDetailsHeight; + + + if (myevents[i].Event.imageMode == 'path') + //if (1) + myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo; + else + myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id; + + if (idfound) $scope.events.push(myevents[i]); } -- cgit v1.2.3 From c44d3a53535373087f082a48fcd2eef1f34fb572 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 23 Nov 2016 21:24:01 -0400 Subject: removed device download for now -- need to experiment --- www/js/EventCtrl.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 830cc8d9..ecd3d96e 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,6 +1,6 @@ /* jshint -W041 */ /* jslint browser: true*/ -/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, AnimatedGIF */ +/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, AnimatedGIF , LibraryHelper*/ // This is the controller for Event view. StateParams is if I recall the monitor ID. // This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it @@ -36,7 +36,7 @@ angular.module('zmApp.controllers') }) -.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', function($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate) +.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', function($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer) { // events in last 5 minutes @@ -533,6 +533,26 @@ angular.module('zmApp.controllers') } + + $scope.downloadFileToDevice = function(path) { + // var url = "http://your_ip_address/images/my.jpg"; + LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, "zmNinja"); + //cordova.plugins.PhotoLibrary.videofromUrl(path, onSuccess, onError); + + function onSuccess(results) + { + console.log("Duration: " + results.duration); + console.log("Thumbnail path on disk: " + results.thumbnail); + } + + function onError(error) + { + console.log("Error: " + error); + + } + + }; + $scope.mp4warning = function() { $ionicPopup.alert( @@ -1588,7 +1608,8 @@ angular.module('zmApp.controllers') event.Event.video = {}; var videoURL; - if (event.Event.imageMode == 'path') + //if (event.Event.imageMode == 'path') + if (1) videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo; else videoURL = event.Event.baseURL + "/index.php?view=view_video&eid=" + event.Event.Id; -- cgit v1.2.3 From 1009cd07dd8beae0eee2a7b7f677da7c03b88b43 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 26 Nov 2016 03:32:43 -0500 Subject: added support for video download on devices - need to test more. On devices you can actually track progress. #383 --- www/js/EventCtrl.js | 181 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 61 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index ecd3d96e..ad1c1da0 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -36,7 +36,7 @@ angular.module('zmApp.controllers') }) -.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', function($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer) +.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', function($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile) { // events in last 5 minutes @@ -95,7 +95,7 @@ angular.module('zmApp.controllers') { showHiddenMonitors = false; } - + if (NVRDataModel.getLogin().useLocalTimeZone) { $scope.tzAbbr = moment().tz(moment.tz.guess()).zoneAbbr(); @@ -201,7 +201,7 @@ angular.module('zmApp.controllers') $http.get(apiurl) .success(function(data) {}) .error(function(err) {}); - + } function getTextZoomCallback(tz) @@ -405,7 +405,6 @@ angular.module('zmApp.controllers') else myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id; - if (idfound) { $scope.events.push(myevents[i]); @@ -533,35 +532,84 @@ angular.module('zmApp.controllers') } + $scope.downloadFileToDevice = function(path, eid) + { + + NVRDataModel.setAwake(true); + var tp = cordova.file.documentsDirectory + "temp-video.mp4"; + var th = true; + var opt = {}; + //path = "http://techslides.com/demos/sample-videos/small.mp4"; + + NVRDataModel.debug ("Saving temporary video to: "+tp); + $cordovaFileTransfer.download(path, tp, opt, th) + .then(function(result) + { + NVRDataModel.debug ("Moving to gallery..."); + var ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; + + $ionicLoading.hide(); + moveToGallery(ntp); + NVRDataModel.setAwake(false); + // Success! + }, function(err) + { + NVRDataModel.setAwake(false); + NVRDataModel.log ("Error="+JSON.stringify(err)); + $ionicLoading.hide(); + $ionicLoading.show( + { + + template: $translate.instant('kError'), + noBackdrop: true, + duration:3000 + }); + // Error + }, function(progress) + { + var p = Math.round((progress.loaded / progress.total) * 100); + $ionicLoading.show( + { - $scope.downloadFileToDevice = function(path) { - // var url = "http://your_ip_address/images/my.jpg"; - LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, "zmNinja"); - //cordova.plugins.PhotoLibrary.videofromUrl(path, onSuccess, onError); + template: $translate.instant('kPleaseWait') + "...(" + p + "%)", + noBackdrop: true + }); + + + }); - function onSuccess(results) + function moveToGallery(path) { - console.log("Duration: " + results.duration); - console.log("Thumbnail path on disk: " + results.thumbnail); - } - function onError(error) - { - console.log("Error: " + error); + NVRDataModel.debug ("moveToGallery called with "+path); + LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, "zmNinja"); + + function onSuccess(results) + { + NVRDataModel.debug ("Removing temp file"); + $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-video.mp4"); + + + } + + function onError(error) + { + console.log("Error: " + error); + + } } - }; + }; $scope.mp4warning = function() { - $ionicPopup.alert( - { - title: $translate.instant('kNote'), - template: "{{'kVideoMp4Warning' | translate }}" - }); + $ionicPopup.alert( + { + title: $translate.instant('kNote'), + template: "{{'kVideoMp4Warning' | translate }}" + }); }; - $scope.showImage = function(p, r, f, fid, e, imode, id, parray, ndx) { @@ -877,7 +925,7 @@ angular.module('zmApp.controllers') fname = e.Event.baseURL + "/index.php?view=image&width=800&fid=" + data.event.Frame[i].Id; } - if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/) + if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/ ) { imglist.push(fname); //fps = data.event.Frame[i].TimeStamp != lastTime ? 0 : fps+1; @@ -889,14 +937,15 @@ angular.module('zmApp.controllers') } // next up make sure we are not processing more than 100 images - + while (imglist.length > zm.maxGifCount) { - NVRDataModel.debug ("Too many images: " +imglist.length+", deleting alternate frames to keep it <="+zm.maxGifCount); + NVRDataModel.debug("Too many images: " + imglist.length + ", deleting alternate frames to keep it <=" + zm.maxGifCount); - for(var l = 0; l < imglist.length; l++) { - imglist.splice(l+1,2); - if (imglist.length <=zm.maxGifCount) break; + for (var l = 0; l < imglist.length; l++) + { + imglist.splice(l + 1, 2); + if (imglist.length <= zm.maxGifCount) break; } } @@ -934,29 +983,36 @@ angular.module('zmApp.controllers') else { - console.log ("in perms"); + console.log("in perms"); cordova.plugins.photoLibrary.getLibrary( - function (library) { downloadAsGif(e);}, - function (err) { - if (err.startsWith('Permission')) { - // call requestAuthorization, and retry - cordova.plugins.photoLibrary.requestAuthorization( - function () { - // User gave us permission to his library, retry reading it! - downloadAsGif(e); - }, - function (err) { - NVRDataModel.log ("ERROR with saving permissions "+err); - // User denied the access - }, // if options not provided, defaults to {read: true}. + function(library) + { + downloadAsGif(e); + }, + function(err) + { + if (err.startsWith('Permission')) { - read: true, - write: true + // call requestAuthorization, and retry + cordova.plugins.photoLibrary.requestAuthorization( + function() + { + // User gave us permission to his library, retry reading it! + downloadAsGif(e); + }, + function(err) + { + NVRDataModel.log("ERROR with saving permissions " + err); + // User denied the access + }, // if options not provided, defaults to {read: true}. + { + read: true, + write: true + } + ); } - ); + // Handle error - it's not permission-related } - // Handle error - it's not permission-related - } ); } @@ -975,31 +1031,36 @@ angular.module('zmApp.controllers') .then(function(imgs) { - console.log ("TOTAL IMAGES TO GIF="+imgs.length); - console.log(JSON.stringify(imgs)); + console.log("TOTAL IMAGES TO GIF=" + imgs.length); + //console.log(JSON.stringify(imgs)); var ad = adjustAspect(e); - console.log("SAVING W=" + ad.w + " H=" + ad.h); - - + //console.log("SAVING W=" + ad.w + " H=" + ad.h); + NVRDataModel.setAwake(true); gifshot.createGIF( { - + 'gifWidth': ad.w, 'gifHeight': ad.h, 'images': imgs, - 'interval':1, + 'interval': 1, //'loop':null, - 'sampleInterval':20, + 'sampleInterval': 20, //'frameDur':5, // 1/2 a sec 'text': 'zmNinja', 'crossOrigin': 'use-credentials', - 'progressCallback': function (cp) + 'progressCallback': function(cp) { var p = Math.round(cp * 100); - $ionicLoading.show({template: $translate.instant('kPleaseWait') + "...("+p+"%)",noBackdrop: true });} + $ionicLoading.show( + { + template: $translate.instant('kPleaseWait') + "...(" + p + "%)", + noBackdrop: true + }); + } }, function(obj) { + NVRDataModel.setAwake(false); if (!obj.error) { //console.log(obj.image); @@ -1039,14 +1100,14 @@ angular.module('zmApp.controllers') else { $ionicLoading.hide(); - console.log("Error creating GIF"); + NVRDataModel.log("Error creating GIF"); } }); }, function(err) { $ionicLoading.hide(); - console.log("Error getting frames"); + NVRDataModel.log("Error getting frames"); } ); @@ -2160,14 +2221,12 @@ angular.module('zmApp.controllers') myevents[i].Event.relativePath = computeRelativePath(myevents[i]); myevents[i].Event.height = eventsListDetailsHeight; - if (myevents[i].Event.imageMode == 'path') //if (1) myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo; else myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id; - if (idfound) $scope.events.push(myevents[i]); } -- cgit v1.2.3 From e3bbbf419adae4f391c786d94db4acd7b88a0355 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 26 Nov 2016 14:39:41 -0500 Subject: various updates to video downloads, including device compatibility (android) #383 --- www/js/EventCtrl.js | 71 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 24 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index ad1c1da0..22076b54 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -536,59 +536,72 @@ angular.module('zmApp.controllers') { NVRDataModel.setAwake(true); - var tp = cordova.file.documentsDirectory + "temp-video.mp4"; + var tp; + if ($rootScope.platformOS == 'ios') + tp = cordova.file.documentsDirectory + "temp-video.mp4"; + else + tp = cordova.file.dataDirectory + "temp-video.mp4"; + var th = true; var opt = {}; - //path = "http://techslides.com/demos/sample-videos/small.mp4"; + //path = "http://techslides.com/demos/sample-videos/small.mp4"; NVRDataModel.debug ("Saving temporary video to: "+tp); $cordovaFileTransfer.download(path, tp, opt, th) .then(function(result) { NVRDataModel.debug ("Moving to gallery..."); - var ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; + var ntp; + ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; - $ionicLoading.hide(); - moveToGallery(ntp); + $timeout (function(){$ionicLoading.hide();}); + moveToGallery(ntp,eid+"-video"); NVRDataModel.setAwake(false); // Success! }, function(err) { NVRDataModel.setAwake(false); NVRDataModel.log ("Error="+JSON.stringify(err)); - $ionicLoading.hide(); - $ionicLoading.show( - { + + $timeout (function() { + $ionicLoading.show( + { - template: $translate.instant('kError'), - noBackdrop: true, - duration:3000 - }); + template: $translate.instant('kError'), + noBackdrop: true, + duration:3000 + }); + }); // Error }, function(progress) { var p = Math.round((progress.loaded / progress.total) * 100); - $ionicLoading.show( - { + + $ionicLoading.show( + { - template: $translate.instant('kPleaseWait') + "...(" + p + "%)", - noBackdrop: true - }); - + template: $translate.instant('kPleaseWait') + "...(" + p + "%)", + noBackdrop: true + }); + }); - function moveToGallery(path) + function moveToGallery(path,fname) { NVRDataModel.debug ("moveToGallery called with "+path); - LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, "zmNinja"); + LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, fname); function onSuccess(results) { NVRDataModel.debug ("Removing temp file"); - $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-video.mp4"); + + if ($rootScope.platformOS == 'ios') + $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-video.mp4"); + else + $cordovaFile.removeFile(cordova.file.dataDirectory, "temp-video.mp4"); } @@ -978,7 +991,7 @@ angular.module('zmApp.controllers') { if ($rootScope.platformOS == 'desktop') { - downloadAsGif(e); + gifAlert(e); } else { @@ -987,7 +1000,7 @@ angular.module('zmApp.controllers') cordova.plugins.photoLibrary.getLibrary( function(library) { - downloadAsGif(e); + gifAlert(e); }, function(err) { @@ -998,7 +1011,7 @@ angular.module('zmApp.controllers') function() { // User gave us permission to his library, retry reading it! - downloadAsGif(e); + gifAlert(e); }, function(err) { @@ -1018,6 +1031,16 @@ angular.module('zmApp.controllers') } }; + function gifAlert(e) + { + $ionicPopup.alert( + { + title: $translate.instant('kNote'), + template: "{{'kGifWarning' | translate }}" + }).then(function(){downloadAsGif(e);}); + + } + function downloadAsGif(e) { $ionicLoading.show( -- cgit v1.2.3 From eb4dcce4167444cc856ed904c23d4417365dd0e8 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 30 Nov 2016 15:40:32 -0500 Subject: major rewrite of GIF creation - memory handling much better #398 - moved to Stream based support --- www/js/EventCtrl.js | 318 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 279 insertions(+), 39 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 22076b54..816b4461 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,6 +1,7 @@ /* jshint -W041 */ +/*jshint bitwise: false*/ /* jslint browser: true*/ -/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, AnimatedGIF , LibraryHelper*/ +/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, ReadableStream , LibraryHelper, GifWriter, NeuQuant*/ // This is the controller for Event view. StateParams is if I recall the monitor ID. // This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it @@ -116,7 +117,7 @@ angular.module('zmApp.controllers') //console.log ("********* BEFORE ENTER"); // - $scope.gifshotSupported = gifshot.isExistingImagesGIFSupported(); + $scope.gifshotSupported = true; document.addEventListener("pause", onPause, false); //console.log("I got STATE PARAM " + $stateParams.id); $scope.id = parseInt($stateParams.id, 10); @@ -534,75 +535,76 @@ angular.module('zmApp.controllers') $scope.downloadFileToDevice = function(path, eid) { - + NVRDataModel.setAwake(true); var tp; if ($rootScope.platformOS == 'ios') - tp = cordova.file.documentsDirectory + "temp-video.mp4"; + tp = cordova.file.documentsDirectory + "temp-video.mp4"; else tp = cordova.file.dataDirectory + "temp-video.mp4"; var th = true; var opt = {}; - //path = "http://techslides.com/demos/sample-videos/small.mp4"; + //path = "http://techslides.com/demos/sample-videos/small.mp4"; - NVRDataModel.debug ("Saving temporary video to: "+tp); + NVRDataModel.debug("Saving temporary video to: " + tp); $cordovaFileTransfer.download(path, tp, opt, th) .then(function(result) { - NVRDataModel.debug ("Moving to gallery..."); - var ntp; + NVRDataModel.debug("Moving to gallery..."); + var ntp; ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; - $timeout (function(){$ionicLoading.hide();}); - moveToGallery(ntp,eid+"-video"); + $timeout(function() + { + $ionicLoading.hide(); + }); + moveToGallery(ntp, eid + "-video"); NVRDataModel.setAwake(false); // Success! }, function(err) { NVRDataModel.setAwake(false); - NVRDataModel.log ("Error="+JSON.stringify(err)); - - $timeout (function() { + NVRDataModel.log("Error=" + JSON.stringify(err)); + + $timeout(function() + { $ionicLoading.show( { template: $translate.instant('kError'), noBackdrop: true, - duration:3000 + duration: 3000 }); - }); + }); // Error }, function(progress) { var p = Math.round((progress.loaded / progress.total) * 100); - - $ionicLoading.show( - { - template: $translate.instant('kPleaseWait') + "...(" + p + "%)", - noBackdrop: true - }); - - + $ionicLoading.show( + { + + template: $translate.instant('kPleaseWait') + "...(" + p + "%)", + noBackdrop: true + }); + }); - function moveToGallery(path,fname) + function moveToGallery(path, fname) { - NVRDataModel.debug ("moveToGallery called with "+path); + NVRDataModel.debug("moveToGallery called with " + path); LibraryHelper.saveVideoToLibrary(onSuccess, onError, path, fname); - function onSuccess(results) { - NVRDataModel.debug ("Removing temp file"); + NVRDataModel.debug("Removing temp file"); if ($rootScope.platformOS == 'ios') $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-video.mp4"); else - $cordovaFile.removeFile(cordova.file.dataDirectory, "temp-video.mp4"); - + $cordovaFile.removeFile(cordova.file.dataDirectory, "temp-video.mp4"); } @@ -931,14 +933,15 @@ angular.module('zmApp.controllers') //if (1) { var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg"; - fname = e.Event.baseURL + "/index.php?view=image&width=800&path=" + e.Event.relativePath + rfp; + fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&path=" + e.Event.relativePath + rfp; } else { - fname = e.Event.baseURL + "/index.php?view=image&width=800&fid=" + data.event.Frame[i].Id; + fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&fid=" + data.event.Frame[i].Id; } if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/ ) + { imglist.push(fname); //fps = data.event.Frame[i].TimeStamp != lastTime ? 0 : fps+1; @@ -951,17 +954,18 @@ angular.module('zmApp.controllers') // next up make sure we are not processing more than 100 images - while (imglist.length > zm.maxGifCount) + while (imglist.length > zm.maxGifCount2) { - NVRDataModel.debug("Too many images: " + imglist.length + ", deleting alternate frames to keep it <=" + zm.maxGifCount); + NVRDataModel.debug("Too many images: " + imglist.length + ", deleting alternate frames to keep it <=" + zm.maxGifCount2); for (var l = 0; l < imglist.length; l++) { imglist.splice(l + 1, 2); - if (imglist.length <= zm.maxGifCount) break; + if (imglist.length <= zm.maxGifCount2) break; } } + NVRDataModel.debug("final image list length is:" + imglist.length); d.resolve(imglist); return d.promise; @@ -974,12 +978,12 @@ angular.module('zmApp.controllers') return d.promise; } - // force image to be 800px. TBD: rotated foo + // force image to be of zm.maxGifWidth. TBD: rotated foo function adjustAspect(e) { - var w = 800; - var h = Math.round(e.Event.Height / e.Event.Width * 800.0); + var w = zm.maxGifWidth; + var h = Math.round(e.Event.Height / e.Event.Width * zm.maxGifWidth); return { w: w, h: h @@ -987,6 +991,7 @@ angular.module('zmApp.controllers') } + // for devices - handle permission before you download $scope.permissionsDownload = function(e) { if ($rootScope.platformOS == 'desktop') @@ -1031,16 +1036,251 @@ angular.module('zmApp.controllers') } }; + // make sure the user knows the GIF is not full fps/all frames function gifAlert(e) { $ionicPopup.alert( { title: $translate.instant('kNote'), template: "{{'kGifWarning' | translate }}" - }).then(function(){downloadAsGif(e);}); - + }).then(function() + { + downloadAsGif2(e); + }); + + } + + // convert to base64 - devices need this to save to gallery + function blobToBase64(blob) + { + NVRDataModel.debug("converting blob to base64..."); + var d = $q.defer(); + var reader = new window.FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = function() + { + var base64data = reader.result; + //console.log(base64data ); + d.resolve(base64data); + return d.promise; + + }; + return d.promise; + } + + // part of neuquant conversion + function componentizedPaletteToArray(paletteRGB) + { + var paletteArray = [], + i, r, g, b; + for (i = 0; i < paletteRGB.length; i += 3) + { + r = paletteRGB[i]; + g = paletteRGB[i + 1]; + b = paletteRGB[i + 2]; + paletteArray.push(r << 16 | g << 8 | b); + } + return paletteArray; + } + + // part of neuquant conversion + function dataToRGB(data, width, height) + { + var i = 0, + length = width * height * 4, + rgb = []; + while (i < length) + { + rgb.push(data[i++]); + rgb.push(data[i++]); + rgb.push(data[i++]); + i++; + } + return rgb; + } + + // credit Jimmy Warting + // https://github.com/jimmywarting/StreamSaver.js/issues/38 + // he stream-ized and cleaned up the gif creation process + // using GifWriter.js + function createGif(files, w, h) + { + + var cv = document.getElementById("canvas"); + var ctx = cv.getContext("2d"); + var pixels = new Uint8Array(w * h); + var totalImages = files.length; + var processedImages = 0; + + cv.width = w; + cv.height = h; + + var rs = new ReadableStream( + { + // Each time pull gets called you should get the pixel data and + // enqueue it as if it would be good old gif.addFrame() + pull: function pull(controller) + { + var frame = files.shift(); + if (!frame) controller.close(); + + return $http( + { + url: frame, + responseType: "blob" + }) + .then(function(res) + { + + return res.data.image(); + }) + .then(function(img) + { + processedImages++; + + var p = Math.round(processedImages / totalImages * 100); + $ionicLoading.show( + { + template: $translate.instant('kPleaseWait') + "...(" + p + "%)", + noBackdrop: true + }); + + console.log("URL=" + frame); + URL.revokeObjectURL(img.src); + ctx.drawImage(img, 0, 0); + + var data = ctx.getImageData(0, 0, w, h).data; + var rgbComponents = dataToRGB(data, w, h); + var nq = new NeuQuant(rgbComponents, rgbComponents.length, 15); + var paletteRGB = nq.process(); + var paletteArray = new Uint32Array(componentizedPaletteToArray(paletteRGB)); + var numberPixels = w * h; + var k = 0, + i, r, g, b; + + for (i = 0; i < numberPixels; i++) + { + r = rgbComponents[k++]; + g = rgbComponents[k++]; + b = rgbComponents[k++]; + pixels[i] = nq.map(r, g, b); + } + + controller.enqueue([0, 0, w, h, pixels, + { + palette: paletteArray, + delay: 100, // 1 second + }]); + }); + } + }); + + return new GifWriter(rs, w, h, + { + loop: null + }); + } + + function downloadAsGif2(e) + { + $ionicLoading.show( + { + template: $translate.instant('kPleaseWait') + "...", + noBackdrop: true, + duration: 20000 + }); + NVRDataModel.setAwake(true); + + prepareImages(e) + .then(function(files) + { + return $http( + { + url: files[0], + responseType: "blob" + }) + .then(function(res) + { + return res.data.image(); + }) + .then(function(img) + { + URL.revokeObjectURL(img.src); // Revoke object URL to free memory + var stream = createGif(files, img.width, img.height); + var chunks = []; + var reader = stream.getReader(); + + function pull() + { + return reader.read().then(function(result) + { + chunks.push(result.value); + return result.done ? chunks : pull(); + }); + } + + pull().then(function(chunks) + { + var blob = new Blob(chunks, + { + type: "image/gif" + }); + blob.image().then(function(img) + { + + //alert ("WE ARE DONE!"); + if ($rootScope.platformOS == 'desktop') + { + saveAs(blob, e.Event.Id + "-video.gif"); + $ionicLoading.hide(); + } + else + { + blobToBase64(blob) + .then(function(base64Blob) + { + + NVRDataModel.debug("Saving blob to gallery..."); + var album = "zmNinja"; + + cordova.plugins.photoLibrary.saveImage(base64Blob, album, + function() + { + $ionicLoading.hide(); + NVRDataModel.debug("Event saved"); + NVRDataModel.setAwake(false); + }, + function(err) + { + $ionicLoading.hide(); + NVRDataModel.debug("Saving ERROR=" + err); + NVRDataModel.setAwake(false); + }); + }); + + } + + //console.log (img); + //document.body.appendChild(img); + //document.getElementById("canvas").hidden = true; + + }); + }); + }); + + }, + function(err) + { + $ionicLoading.hide(); + NVRDataModel.setAwake(false); + NVRDataModel.log("Error getting frames"); + } + + ); + } + // NOT USED - WILL REMOVE AFTER TESTING OTHER METHOD MORE function downloadAsGif(e) { $ionicLoading.show( -- cgit v1.2.3 From d170a70f8f52577bbedc9bfcc849d0f590168d50 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Wed, 30 Nov 2016 20:25:28 -0500 Subject: rework gallery code to use file transfer and avoid base64 --- www/js/EventCtrl.js | 102 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 34 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 816b4461..827936d7 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -533,6 +533,31 @@ angular.module('zmApp.controllers') } + + function moveImageToGallery(fname) + { + + NVRDataModel.debug("moveImageToGallery called with " + fname); + LibraryHelper.saveImageToLibrary(onSuccess, onError, fname, "zmNinja"); + + function onSuccess(results) + { + NVRDataModel.debug("Removing temp file"); + + if ($rootScope.platformOS == 'ios') + $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-file.gif"); + else + $cordovaFile.removeFile(cordova.file.dataDirectory, "temp-file.gif"); + + } + + function onError(error) + { + console.log("Error: " + error); + + } + } + $scope.downloadFileToDevice = function(path, eid) { @@ -1122,7 +1147,7 @@ angular.module('zmApp.controllers') pull: function pull(controller) { var frame = files.shift(); - if (!frame) controller.close(); + if (!frame) {controller.close(); return;} return $http( { @@ -1183,6 +1208,7 @@ angular.module('zmApp.controllers') function downloadAsGif2(e) { + $rootScope.isDownloading = true; $ionicLoading.show( { template: $translate.instant('kPleaseWait') + "...", @@ -1224,47 +1250,54 @@ angular.module('zmApp.controllers') var blob = new Blob(chunks, { type: "image/gif" + }); - blob.image().then(function(img) + + //alert ("WE ARE DONE!"); + if ($rootScope.platformOS == 'desktop') + { + saveAs(blob, e.Event.Id + "-video.gif"); + $ionicLoading.hide(); + } + else { + // write blob to file + var tp; + if ($rootScope.platformOS == 'ios') + tp = cordova.file.documentsDirectory; + else + tp = cordova.file.dataDirectory; + var th = true, opt = {}; - //alert ("WE ARE DONE!"); - if ($rootScope.platformOS == 'desktop') + $ionicLoading.show( { - saveAs(blob, e.Event.Id + "-video.gif"); + + template:"writing to file...", + noBackdrop: true, + }); + $cordovaFile.writeFile(tp, "temp-file.gif", blob,true) + .then (function (succ) { + NVRDataModel.debug ("write to file successful"); $ionicLoading.hide(); - } - else - { - blobToBase64(blob) - .then(function(base64Blob) - { - - NVRDataModel.debug("Saving blob to gallery..."); - var album = "zmNinja"; - - cordova.plugins.photoLibrary.saveImage(base64Blob, album, - function() - { - $ionicLoading.hide(); - NVRDataModel.debug("Event saved"); - NVRDataModel.setAwake(false); - }, - function(err) - { - $ionicLoading.hide(); - NVRDataModel.debug("Saving ERROR=" + err); - NVRDataModel.setAwake(false); - }); - }); - } + var ntp; + ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; - //console.log (img); - //document.body.appendChild(img); - //document.getElementById("canvas").hidden = true; + ntp = ntp+"temp-file.gif"; + console.log ("ntp="+ntp); + + moveImageToGallery(ntp); + $rootScope.isDownloading = false; + + }, function (err) { + $rootScope.isDownloading = false; + $ionicLoading.hide(); + NVRDataModel.debug ("error writing to file "+err); + + + }); + } - }); }); }); @@ -1274,6 +1307,7 @@ angular.module('zmApp.controllers') $ionicLoading.hide(); NVRDataModel.setAwake(false); NVRDataModel.log("Error getting frames"); + $rootScope.isDownloading = false; } ); -- cgit v1.2.3 From 0122e6656bc54fb94db29dfd99f268c49e6e16de Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 2 Dec 2016 10:59:14 -0500 Subject: updated to use chunk writing (#398) --- www/js/EventCtrl.js | 140 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 8 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 827936d7..c17071ea 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1,7 +1,7 @@ /* jshint -W041 */ /*jshint bitwise: false*/ /* jslint browser: true*/ -/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, ReadableStream , LibraryHelper, GifWriter, NeuQuant*/ +/* global saveAs, cordova,StatusBar,angular,console,moment, MobileAccessibility, gifshot, ReadableStream , LibraryHelper, GifWriter, NeuQuant, LocalFileSystem, FileError*/ // This is the controller for Event view. StateParams is if I recall the monitor ID. // This was before I got access to the new APIs. FIXME: Revisit this code to see what I am doing with it @@ -534,20 +534,135 @@ angular.module('zmApp.controllers') } + + + function writeFile2( path, file, blob, isAppend) + { + var csize = 4 * 1024 * 1024; // 4MB + var d = $q.defer(); + NVRDataModel.debug ("Inside writeFile2 with blob size="+blob.size); + + // nothing more to write, so all good? + if (!blob.size) + { + NVRDataModel.debug ("writeFile2 all done"); + d.resolve(true); + return $q.resolve(true); + } + + + if (!isAppend) + { + // return the delegated promise, even if it fails + return $cordovaFile.writeFile(path, file, blob.slice(0,csize), true) + .then (function (succ) { + return writeFile2(path,file,blob.slice(csize),true); + }); + } + else + { + // return the delegated promise, even if it fails + return $cordovaFile.writeExistingFile(path, file, blob.slice(0,csize)) + .then (function (succ) { + return writeFile2(path,file,blob.slice(csize),true); + }); + } + + + } + + function writeFile(path, __filename, __data){ + var d = $q.defer(); + console.log ("inside write file"); + window.requestFileSystem(LocalFileSystem.TEMPORARY, __data.size+5000, onFileSystemSuccess, fail); + + function fail(e) + { + var msg = ''; + + switch (e.code) { + case FileError.QUOTA_EXCEEDED_ERR: + msg = 'QUOTA_EXCEEDED_ERR'; + break; + case FileError.NOT_FOUND_ERR: + msg = 'NOT_FOUND_ERR'; + break; + case FileError.SECURITY_ERR: + msg = 'SECURITY_ERR'; + break; + case FileError.INVALID_MODIFICATION_ERR: + msg = 'INVALID_MODIFICATION_ERR'; + break; + case FileError.INVALID_STATE_ERR: + msg = 'INVALID_STATE_ERR'; + break; + default: + msg = 'Unknown Error'; + break; + } + + console.log('Error: ' + msg); + } + function onFileSystemSuccess() + { + console.log ("Got temporary FS"); + window.resolveLocalFileSystemURL(path, function(dir){ + dir.getFile(__filename, {create:true}, function(file){ + file.createWriter(function(fileWriter){ + //var blob = new Blob([__data], {type:'text/plain'}); + console.log ("about to write "+__data.size+" bytes"); + //var blob = new Blob([__data], {type:'text/plain'}); + fileWriter.write(__data); + fileWriter.onwrite = function(e) { + NVRDataModel.debug ("write complete"); + d.resolve(); + return d.promise; + }; + + fileWriter.onerror = function(e) { + NVRDataModel.debug ("write error in filewriter:"+JSON.stringify(e)); + d.reject(); + return d.promise; + }; + + }); + }); + + }, + function (err) { + d.reject(err); + return d.promise; + }); + } + return d.promise; + } + + function moveImageToGallery(fname) { + // this is https://github.com/terikon/cordova-plugin-photo-library NVRDataModel.debug("moveImageToGallery called with " + fname); - LibraryHelper.saveImageToLibrary(onSuccess, onError, fname, "zmNinja"); + cordova.plugins.photoLibrary.saveImage(fname, "zmNinja",onSuccess, onError); + //LibraryHelper.saveImageToLibrary(onSuccess, onError, fname, "zmNinja"); function onSuccess(results) { + NVRDataModel.debug("Removing temp file"); - if ($rootScope.platformOS == 'ios') - $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-file.gif"); + if ($rootScope.platformOS == 'ios') { + $cordovaFile.removeFile(cordova.file.documentsDirectory, "temp-file.gif"); + } else $cordovaFile.removeFile(cordova.file.dataDirectory, "temp-file.gif"); + $ionicLoading.show( + { + template: $translate.instant('kDone'), + noBackdrop: true, + duration: 2000 + }); + } @@ -1206,6 +1321,8 @@ angular.module('zmApp.controllers') }); } + + function downloadAsGif2(e) { $rootScope.isDownloading = true; @@ -1233,6 +1350,8 @@ angular.module('zmApp.controllers') { URL.revokeObjectURL(img.src); // Revoke object URL to free memory var stream = createGif(files, img.width, img.height); + //var fileStream = streamSaver.createWriteStream('image.gif'); + var chunks = []; var reader = stream.getReader(); @@ -1275,13 +1394,18 @@ angular.module('zmApp.controllers') template:"writing to file...", noBackdrop: true, }); - $cordovaFile.writeFile(tp, "temp-file.gif", blob,true) + + //var bloburl = URL.createObjectURL(blob); + //NVRDataModel.debug ("blob-url is:"+bloburl); + + writeFile2(tp,"temp-file.gif",blob,false) .then (function (succ) { NVRDataModel.debug ("write to file successful"); + console.log( "write file successful"); $ionicLoading.hide(); - var ntp; - ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; + var ntp = tp; + //ntp = tp.indexOf('file://') === 0 ? tp.slice(7) : tp; ntp = ntp+"temp-file.gif"; console.log ("ntp="+ntp); @@ -1292,7 +1416,7 @@ angular.module('zmApp.controllers') }, function (err) { $rootScope.isDownloading = false; $ionicLoading.hide(); - NVRDataModel.debug ("error writing to file "+err); + NVRDataModel.debug ("error writing to file "+JSON.stringify(err)); }); -- cgit v1.2.3 From 724fec3a208e7f42ed9e657740484b3b6be9f27e Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 2 Dec 2016 11:45:22 -0500 Subject: if running crosswalk, disable this feature (doesn't work) #398 --- www/js/EventCtrl.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index c17071ea..3ff6c1ce 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -1179,14 +1179,30 @@ angular.module('zmApp.controllers') // make sure the user knows the GIF is not full fps/all frames function gifAlert(e) { - $ionicPopup.alert( - { - title: $translate.instant('kNote'), - template: "{{'kGifWarning' | translate }}" - }).then(function() + if(navigator.userAgent.toLowerCase().indexOf('crosswalk') == -1) { + $ionicPopup.confirm( + { + title: $translate.instant('kNote'), + template: "{{'kGifWarning' | translate }}" + }).then(function(res) + { + if (res) + { + downloadAsGif2(e); + } + else + NVRDataModel.debug ("User cancelled GIF"); + + }); + } + else { - downloadAsGif2(e); - }); + $ionicPopup.alert({ + title:$translate.instant ('kNote'), + template:"{{'kGifNoCrosswalk' | translate}}" + }); + } + } -- cgit v1.2.3 From 898d85ded3eb2260a80573bcc7c756c56d37bf15 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 10 Dec 2016 08:27:27 -0500 Subject: added translations for buttons #410 --- www/js/EventCtrl.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'www/js/EventCtrl.js') diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js index 3ff6c1ce..32f8b119 100644 --- a/www/js/EventCtrl.js +++ b/www/js/EventCtrl.js @@ -306,7 +306,9 @@ angular.module('zmApp.controllers') $ionicPopup.alert( { title: pTitle, - template: "{{'kCheckCredentials' | translate }}" + template: "{{'kCheckCredentials' | translate }}", + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), }); $ionicHistory.nextViewOptions( { @@ -762,7 +764,9 @@ angular.module('zmApp.controllers') $ionicPopup.alert( { title: $translate.instant('kNote'), - template: "{{'kVideoMp4Warning' | translate }}" + template: "{{'kVideoMp4Warning' | translate }}", + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), }); }; @@ -1183,7 +1187,9 @@ angular.module('zmApp.controllers') $ionicPopup.confirm( { title: $translate.instant('kNote'), - template: "{{'kGifWarning' | translate }}" + template: "{{'kGifWarning' | translate }}", + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), }).then(function(res) { if (res) @@ -1603,7 +1609,9 @@ angular.module('zmApp.controllers') $rootScope.zmPopup = $ionicPopup.confirm( { title: $translate.instant('kFilterSettings'), - template: $translate.instant('kFilterEventsBetween1') + ':
' + myFrom + " " + $translate.instant('kTo') + " " + toString + '
' + $translate.instant('kFilterEventsBetween2') + template: $translate.instant('kFilterEventsBetween1') + ':
' + myFrom + " " + $translate.instant('kTo') + " " + toString + '
' + $translate.instant('kFilterEventsBetween2'), + okText: $translate.instant('kButtonOk'), + cancelText: $translate.instant('kButtonCancel'), }); $rootScope.zmPopup.then(function(res) { -- cgit v1.2.3