/* jshint -W041 */
/*jshint bitwise: false*/
/* jslint browser: true*/
/* 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
// and whether the new API has a better mechanism
angular.module('zmApp.controllers')
// alarm frames filter
.filter('selectFrames', function ($filter, $translate) {
// Create the return function and set the required parameter name to **input**
return function (input, typeOfFrames) {
var out = [];
angular.forEach(input, function (item) {
if (typeOfFrames == $translate.instant('kShowTimeDiffFrames')) {
if (item.type == $translate.instant('kShowTimeDiffFrames'))
out.push(item);
} else
out.push(item);
});
return out;
};
})
.controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVR', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', '$ionicListDelegate', 'ionPullUpFooterState', 'SecuredPopups', '$window', function ($scope, $rootScope, zm, NVR, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile, $ionicListDelegate, ionPullUpFooterState,SecuredPopups, $window) {
// events in last 5 minutes
// TODO https://server/zm/api/events/consoleEvents/5%20minute.json
//---------------------------------------------------
// Controller main
//---------------------------------------------------
var loginData;
var oldEvent;
var scrollbynumber;
var eventImageDigits = 5; // failsafe
var currEventsPage = 1;
var maxEventsPage = 1;
var moreEvents;
var enableLoadMore;
var lData;
var showHiddenMonitors;
var ionRangeWatcher;
var mycarouselWatcher;
var nolangFrom;
var nolangTo;
var broadcastHandles = [];
var intervalReloadEvents;
var eventHeight = 0;
var currentPagePosition = 0;
var currentPageLength = 0;
var currentPageData;
var loadMoreTime;
var maxEventsToLoad = 5; //limit to 5 to minimise memory usage when displaying gifs
$scope.typeOfFrames = $translate.instant('kShowTimeDiffFrames');
$scope.outlineMotion = false;
$scope.outlineMotionParam = "&show=capture";
$scope.eventsBeingLoaded = true;
var eHandle;
var scrubOngoing = false;
//---------------------------------------------------
// initial code
//---------------------------------------------------
$scope.$on('sizechanged', function() {
$timeout (function () {
recomputeThumbSize();
},10);
});
//we come here is TZ is updated after the view loads
var tzu = $scope.$on('tz-updated', function () {
$scope.tzAbbr = NVR.getTimeZoneNow();
NVR.debug("Timezone API updated timezone to " + NVR.getTimeZoneNow());
});
broadcastHandles.push(tzu);
var lc = $scope.$on("language-changed", function () {
NVR.log(">>>>>>>>>>>>>>> language changed");
doRefresh();
});
broadcastHandles.push(lc);
$scope.$on('$ionicView.afterEnter', function () {
$ionicListDelegate.canSwipeItems(true);
// NVR.debug("enabling options swipe");
// see if we come from monitors, if so, don't filter events
if ($ionicHistory.backTitle() == 'Monitors') {
showHiddenMonitors = true;
} else {
showHiddenMonitors = false;
}
if (NVR.getLogin().useLocalTimeZone) {
$scope.tzAbbr = moment().tz(moment.tz.guess()).zoneAbbr();
} else {
$scope.tzAbbr = moment().tz(NVR.getTimeZoneNow()).zoneAbbr();
}
//console.log ("************** CLEARING EVENTS");
$scope.events = [];
$timeout(function () {
// console.log ("DEFERRED ACTION EVENTS");
getInitialEvents();
setupWatchers();
footerExpand();
// now do event playback if asked
if (parseInt($rootScope.tappedEid) > 0 && $stateParams.playEvent == 'true') {
NVR.debug(" Trying to play event due to push:" + $rootScope.tappedEid);
playSpecificEvent($rootScope.tappedEid);
}
}, 100);
NVR.debug ("Starting page refresh timer");
$interval.cancel(intervalReloadEvents);
intervalReloadEvents = $interval(function () {
timedPageReload();
}.bind(this), zm.eventPageRefresh);
});
function timedPageReload() {
if (!NVR.getLogin().enableEventRefresh) {
NVR.debug ("Event refresh disabled");
return;
}
if ($ionicScrollDelegate.$getByHandle("mainScroll").getScrollPosition().top !=0 ) {
NVR.debug ("Not reloading as you have scrolled");
}
else if ($scope.modal != undefined && $scope.modal.isShown()) {
NVR.debug ("Not reloading as you have a modal open");
}
else if (scrubOngoing) {
NVR.debug ("Not reloading, as video scrub is on");
}
else {
doRefresh();
}
}
function playSpecificEvent(eid) {
NVR.log("Stuffing EID to play back " + eid);
$rootScope.tappedEid = 0;
var event = {
Event: {
Id: eid
}
};
$scope.event = event;
$scope.currentEvent = event;
openModal(event, 'enabled');
}
$scope.$on('$ionicView.beforeLeave', function () {
//$window.removeEventListener('orientationchange', updateUI);
if ($stateParams.lastCheckTime != undefined && $stateParams.lastCheckTime != '' && moment($stateParams.lastCheckTime).isValid()) {
NVR.debug ("removing montage temporary filter");
$rootScope.isEventFilterOn = false;
$rootScope.fromDate = "";
$rootScope.fromTime = "";
$rootScope.toDate = "";
$rootScope.toTime = "";
$rootScope.fromString = "";
$rootScope.toString = "";
$rootScope.monitorsFilter="";
}
NVR.debug ("Cancelling page reload timer");
$interval.cancel(intervalReloadEvents);
document.removeEventListener("pause", onPause, false);
//NVR.debug("EventCtrl: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
// broadcastHandles[i]();
}
broadcastHandles = [];
});
$scope.$on('$ionicView.beforeEnter', function () {
/*
It's a bleeding mess trying to get this working on
multiple devices and orientations with flex-box, primarily
because I'm not a CSS guru.
Plus, collection-repeat offers significant performance benefits
and this requires fixed row sizes across all rows.
The layout I am using:
a) If you are using large thumbs, it's a single column format
b) If you are using small thumbs, it's a two column format
The max size of the image is in computeThumbnailSize()
*/
var ld = NVR.getLogin();
if (ld.eventViewThumbs != 'none') {
if (ld.eventViewThumbsSize == 'large') {
NVR.debug ('Switching to big thumbs style');
$scope.thumbClass = 'large';
$scope.rowHeightRegular = 450;
$scope.rowHeightExpanded = $scope.rowHeightRegular + 230;
} else {
NVR.debug ('using small thumbs style');
$scope.thumbClass = 'small';
$scope.rowHeightRegular = 250;
$scope.rowHeightExpanded = $scope.rowHeightRegular + 200;
}
} else {
NVR.debug ('No thumbs');
$scope.rowHeightRegular = 170;
$scope.rowHeightExpanded = $scope.rowHeightRegular + 200;
}
$scope.rowHeight = $scope.rowHeightRegular;
$scope.mid = '';
$scope.$on ("alarm", function() {
NVR.debug ("EventCtrl: new event notification, doing an immediate reload");
// do an immediate display reload and schedule timer again
$interval.cancel(intervalReloadEvents);
timedPageReload();
intervalReloadEvents = $interval(function () {
timedPageReload();
}.bind(this), zm.eventPageRefresh);
});
$scope.$on ( "process-push", function () {
NVR.debug (">> EventCtrl: push handler");
var s = NVR.evaluateTappedNotification();
NVR.debug("tapped Notification evaluation:"+ JSON.stringify(s));
$scope.mid = $rootScope.tappedMid;
$ionicHistory.nextViewOptions({
disableAnimate:true,
disableBack: true
});
$state.go(s[0],s[1],s[2]);
});
$scope.modalData = {
"doRefresh": false
};
$scope.footerState = ionPullUpFooterState.MINIMIZED;
$scope.gifshotSupported = true;
document.addEventListener("pause", onPause, false);
//console.log("I got STATE PARAM " + $stateParams.id);
$scope.id = parseInt($stateParams.id, 10);
if (isNaN($scope.id)) {
$scope.id = 0;
}
if ($scope.id)
$rootScope.isEventFilterOn = true;
$scope.showEvent = $stateParams.playEvent || false;
$scope.monitors = NVR.getMonitorsNow();
//console.log("lastCheckTime: " + $stateParams.lastCheckTime);
if ($stateParams.lastCheckTime != undefined && $stateParams.lastCheckTime != '' && moment($stateParams.lastCheckTime).isValid()) {
$rootScope.fromString = $stateParams.lastCheckTime;
var mToDate = moment().tz(NVR.getTimeZoneNow());
$rootScope.toString = mToDate
.format("YYYY-MM-DD") + " " + mToDate.format("HH:mm:ss");
$rootScope.isEventFilterOn = true;
$rootScope.fromDate = moment($rootScope.fromString).toDate();
$rootScope.fromTime = moment($rootScope.fromString).toDate();
$rootScope.toDate = moment($rootScope.toString).toDate();
$rootScope.toTime = moment($rootScope.toString).toDate();
//console.log("toString: " + $rootScope.toString);
}
//console.log("BEFORE ENTER >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
NVR.log("EventCtrl called with: E/MID=" + $scope.id + " playEvent = " + $scope.showEvent);
enableLoadMore = true;
$scope.mycarousel = {
index: 0
};
$scope.ionRange = {
index: 1
};
$scope.animationInProgress = false;
$scope.hours = [];
$scope.days = [];
$scope.weeks = [];
$scope.months = [];
$scope.eventList = {
showDelete: false
};
$scope.slides = []; // will hold scrub frames
$scope.totalEventTime = 0; // used to display max of progress bar
$scope.currentEventTime = 0;
oldEvent = ""; // will hold previous event that had showScrub = true
scrollbynumber = 0;
$scope.eventsBeingLoaded = true;
$scope.FrameArray = []; // will hold frame info from detailed Events API
loginData = NVR.getLogin();
NVR.getKeyConfigParams(0)
.then(function (data) {
//console.log ("***GETKEY: " + JSON.stringify(data));
eventImageDigits = parseInt(data);
NVR.log("Image padding digits reported as " + eventImageDigits);
});
$scope.showSearch = false;
moreEvents = true;
$scope.viewTitle = {
title: ""
};
$scope.search = {
text: ""
};
$scope.myfilter = "";
$scope.loginData = NVR.getLogin();
$scope.playbackURL = $scope.loginData.url;
});
function getEventObject(eid) {
var apiurl = NVR.getLogin().apiurl + '/events/' + eid + '.json?'+$rootScope.authSession;
$http.get(apiurl)
.then(function (data) {},
function (err) {});
}
function getTextZoomCallback(tz) {
$rootScope.textScaleFactor = parseFloat(tz + "%") / 100.0;
NVR.debug("text zoom factor is " + $rootScope.textScaleFactor);
}
// --------------------------------------------------------
// Handling of back button in case modal is open should
// close the modal
// --------------------------------------------------------
$ionicPlatform.registerBackButtonAction(function (e) {
e.preventDefault();
if ($scope.modal != undefined && $scope.modal.isShown()) {
// switch off awake, as liveview is finished
NVR.debug("Modal is open, closing it");
NVR.setAwake(false);
$scope.modal.remove();
} else {
NVR.debug("Modal is closed, so toggling or exiting");
if (!$ionicSideMenuDelegate.isOpenLeft()) {
$ionicSideMenuDelegate.toggleLeft();
} else {
navigator.app.exitApp();
}
}
}, 1000);
//--------------------------------------
// monitor the slider for carousels
//--------------------------------------
function setupWatchers() {
NVR.debug("Setting up carousel watchers");
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 () {
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;
$scope.mycarousel.index = 1;
}
}
if (carouselUtils.getStop() == true)
return;
$scope.ionRange.index = ($scope.mycarousel.index + 1).toString();
// console.log ("***IONRANGE RANGE CHANGED TO " + $scope.ionRange.index);
});
}
// --------------------------------------------------------
// Handling of back button in case modal is open should
// close the modal
// --------------------------------------------------------
function getInitialEvents() {
NVR.debug("getInitialEvents called");
$scope.eventsBeingLoaded = true;
$ionicScrollDelegate.$getByHandle("mainScroll").scrollTop();
var lData = NVR.getLogin();
// If you came from Monitors, disregard hidden monitors in montage
/* if (lData.persistMontageOrder && stackState != "Monitors") {
var tempMon = message;
$scope.monitors = NVR.applyMontageMonitorPrefs(tempMon, 2)[0];
} else*/
$scope.monitors = message;
currEventsPage = 1;
maxEventsPage = 1;
currentPagePosition = 0;
currentPageLength = 0;
if ($scope.monitors.length == 0) {
var pTitle = $translate.instant('kNoMonitors');
$ionicPopup.alert({
title: pTitle,
template: "{{'kCheckCredentials' | translate }}",
okText: $translate.instant('kButtonOk'),
cancelText: $translate.instant('kButtonCancel'),
});
$ionicHistory.nextViewOptions({
disableBack: true
});
$state.go("app.login", {
"wizard": false
});
return;
}
$scope.events = [];
if ($scope.id) {
$rootScope.monitorsFilter = "/MonitorId =:" + $scope.id;
//console.log("monitors.length: " + $scope.monitors.length);
for (var i=0; i <= $scope.monitors.length; i++) {
//console.log("i: " + i);
if ($scope.monitors[i] != undefined) {
//console.log("$scope.monitors[i].Id: " + $scope.monitors[i].Monitor.Id);
if ($scope.monitors[i].Monitor.Id == $scope.id)
$scope.monitors[i].Monitor.isChecked = true;
else
$scope.monitors[i].Monitor.isChecked = false;
}
}
$scope.id = 0;
}
nolangFrom = "";
nolangTo = "";
if ($rootScope.fromString)
nolangFrom = moment($rootScope.fromString).locale('en').format("YYYY-MM-DD HH:mm:ss");
if ($rootScope.toString)
nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss");
//NVR.debug ("GETTING EVENTS USING "+$scope.id+" "+nolangFrom+" "+ nolangTo);
NVR.debug("EventCtrl: grabbing events for: id=" + $scope.id + " Date/Time:" + $rootScope.fromString +
"-" + $rootScope.toString);
if ($scope.loginData.eventViewThumbs != 'objdetect_gif') {
maxEventsToLoad = 50; //limit to 5 to minimise memory usage when displaying gifs
}
NVR.debug("maxEventsToLoad: " + maxEventsToLoad);
NVR.getEvents($scope.id, currEventsPage, "", nolangFrom, nolangTo, false, $rootScope.monitorsFilter)
.then(function (data) {
// console.log(JSON.stringify(data.pagination));
if (data.pagination && data.pagination.pageCount)
maxEventsPage = data.pagination.pageCount;
NVR.debug("maxEventsPage: " + maxEventsPage + ", currEventsPage: " + currEventsPage);
// console.log ("WE GOT EVENTS="+JSON.stringify(data));
//NVR.debug("EventCtrl: success, got " + data.events.length + " events");
loadEvents(data);
currentPageData = data;
//$scope.events = data.events;
// we only need to stop the template from loading when the list is empty
// so this can be false once we have _some_ content
$scope.eventsBeingLoaded = false;
moreEvents = true;
// to avoid only few events being displayed
// if last page has less events
//console.log("**Loading Next Page ***");
if ($scope.events < maxEventsToLoad) {
//console.log ("EVENTS LOADED="+JSON.stringify($scope.events));
NVR.debug("EventCtrl:loading one more page just in case we don't have enough to display");
loadMore();
}
navTitle();
});
loadMoreTime = Date.now();
}
//-------------------------------------------------------
// Tapping on a frame shows this image
//------------------------------------------------------
function SaveSuccess() {
$ionicLoading.show({
template: $translate.instant('kDone'),
noBackdrop: true,
duration: 1000
});
NVR.debug("ModalCtrl:Photo saved successfuly");
}
function SaveError(e) {
$ionicLoading.show({
template: $translate.instant('kErrorSave'),
noBackdrop: true,
duration: 2000
});
NVR.log("Error saving image: " + e.message);
//console.log("***ERROR");
}
function saveNow(imgsrc) {
var fname = "zmninja.jpg";
var fn = "cordova.plugins.photoLibrary.saveImage";
var loginData = NVR.getLogin();
$ionicLoading.show({
template: $translate.instant('kSavingSnapshot') + "...",
noBackdrop: true,
duration: zm.httpTimeout
});
var url = imgsrc;
NVR.log("saveNow: File path to grab is " + url);
if ($rootScope.platformOS != 'desktop') {
var album = 'zmNinja';
NVR.debug("Trying to save image to album: " + album);
cordova.plugins.photoLibrary.requestAuthorization(
function () {
//url = "https://picsum.photos/200/300/?random";
var fileTransfer = new FileTransfer();
var urle = encodeURI(url);
fileTransfer.onprogress = function (progressEvent) {
if (progressEvent.lengthComputable) {
$timeout(function () {
var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100);
$ionicLoading.show({
template: $translate.instant('kPleaseWait') + "... (" + perc + "%)",
noBackdrop: true,
//duration: zm.httpTimeout
});
});
}
};
fileTransfer.download(urle, cordova.file.dataDirectory + fname,
function (entry) {
NVR.debug("local download complete: " + entry.toURL());
NVR.debug("Now trying to move it to album");
var pluginName = (fname == "zmNinja.mp4" ? "saveVideo" : "saveImage");
cordova.plugins.photoLibrary[pluginName](entry.toURL(), album,
function (cameraRollAssetId) {
SaveSuccess();
$cordovaFile.removeFile(cordova.file.dataDirectory, fname)
.then(
function () {
NVR.debug("file removed from data directory");
},
function (e) {
NVR.debug("could not delete temp file: " + JSON.stringify(e));
}
);
},
function (err) {
NVR.debug("Saving error:" + JSON.stringify(err));
SaveError();
});
},
function (err) {
NVR.log("error downloading:" + JSON.stringify(err));
SaveError();
}, !loginData.enableStrictSSL, {});
// User gave us permission to his library, retry reading it!
},
function (err) {
// User denied the access
NVR.debug("Permission not granted");
SaveError();
}, // if options not provided, defaults to {read: true}.
{
read: true,
write: true
}
);
} else {
//desktop
$ionicLoading.hide();
$rootScope.zmPopup = SecuredPopups.show('alert', {
title: $translate.instant('kNote'),
template: $translate.instant('kDownloadVideoImage') + "
/,'');
// console.log ("NDATA:"+ndata);
//
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
//$scope.slider_options.scale = [];
var i;
var timestamp = null;
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) {
atype = $translate.instant('kShowTimeDiffFrames');
} else {
atype = $translate.instant('kShowAllFrames');
}
$scope.alarm_images.push({
type: atype,
id: data.event.Frame[i].Id,
frameid: data.event.Frame[i].FrameId,
score: data.event.Frame[i].Score,
fname: padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg",
aname: padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-analyse.jpg",
time: data.event.Frame[i].TimeStamp
});
timestamp = data.event.Frame[i].TimeStamp;
}
}
oldEvent = event;
//console.log (JSON.stringify(data));
},
function (err) {
NVR.log("Error retrieving detailed frame API " + JSON.stringify(err));
// NVR.displayBanner('error', ['could not retrieve frame details', 'please try again']);
});
} // end of groupType == alarms
else // groupType == scrub
{
NVR.debug("EventCtrl: Scrubbing will turn on now");
scrubOngoing = true;
$scope.currentEvent = "";
$scope.event = event;
//$ionicScrollDelegate.freezeScroll(true);
$ionicSideMenuDelegate.canDragContent(false);
$scope.slider_options = {
from: 1,
to: event.Event.Frames,
realtime: true,
step: 1,
className: "mySliderClass",
callback: function (value, released) {
//console.log("CALLBACK"+value+released);
$ionicScrollDelegate.freezeScroll(!released);
//NVR.debug("EventCtrl: freezeScroll called with " + !released);
},
//modelLabels:function(val) {return "";},
css: {
background: {
"background-color": "silver"
},
before: {
"background-color": "purple"
},
default: {
"background-color": "white"
}, // default value: 1px
after: {
"background-color": "green"
}, // zone after default value
pointer: {
"background-color": "red"
}, // circle pointer
range: {
"background-color": "red"
} // use it if double value
},
scale: []
};
event.Event.rowHeight = $scope.rowHeightExpanded;
$ionicScrollDelegate.resize();
$scope.mycarousel.index = 0;
$scope.ionRange.index = 1;
//console.log("**Resetting range");
$scope.slides = [];
var i;
var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json?"+$rootScope.authSession;
NVR.log("API for event details" + myurl_frames);
$http.get(myurl_frames)
.then(function (data) {
data = data.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++) {
//console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length);
$scope.slides.push({
id: data.event.Frame[i].Id,
frameid: data.event.Frame[i].FrameId,
});
}
//console.log (JSON.stringify(data));
},
function (err) {
NVR.log("Error retrieving detailed frame API " + JSON.stringify(err));
NVR.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]);
});
// now get event details to show alarm frames
loginData = NVR.getLogin();
if (typeof event.Event.DefaultVideo === 'undefined')
event.Event.DefaultVideo = "";
// grab video details
event.Event.video = {};
var videoURL;
videoURL = event.Event.recordingURL + "/index.php?view=view_video&eid=" + event.Event.Id;
videoURL += $rootScope.authSession;
videoURL += NVR.insertSpecialTokens();
// console.log("************** VIDEO IS " + videoURL);
event.Event.video.config = {
autoPlay: true,
sources: [{
src: $sce.trustAsResourceUrl(videoURL),
type: "video/mp4"
}
],
theme: "external/videogular2.2.1/videogular.min.css",
};
var myurl2 = loginData.apiurl + '/events/' + event.Event.Id + ".json?"+$rootScope.authSession;
NVR.log("API for event details" + myurl2);
$http.get(myurl2)
.then(function (data) {
data = data.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") {
//console.log ("**ALARM AT " + i + "of " + data.event.Frame.length);
$scope.slider_options.scale.push({
val: data.event.Frame[i].FrameId,
label: ' '
});
} else {
//$scope.slider_options.scale.push(' ');
}
}
//console.log (JSON.stringify(data));
},
function (err) {
NVR.log("Error retrieving detailed frame API " + JSON.stringify(err));
NVR.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));
var locobject = $ionicPosition.offset(elem);
//console.log(JSON.stringify(locobject));
var toplocation = parseInt(locobject.top);
var objheight = parseInt(locobject.height);
// console.log("top location is " + toplocation);
var distdiff = parseInt($rootScope.devHeight) - toplocation - objheight;
if (distdiff < $scope.rowHeight) // size of the scroller with bars
{
scrollbynumber = $scope.rowHeight - distdiff;
$ionicScrollDelegate.$getByHandle("mainScroll").scrollBy(0, scrollbynumber, true);
// we need to scroll up to make space
}
// console.log("*****Space at bottom is " + distdiff);
} // end of groupType == scrub
} // end of ShowScrub == true
else {
// $ionicScrollDelegate.freezeScroll(false);
//
// $ionicListDelegate.canSwipeItems(true);
// NVR.debug ("enabling options swipe");
event.Event.rowHeight = $scope.rowHeightRegular;
$ionicSideMenuDelegate.canDragContent(true);
$ionicScrollDelegate.resize();
if (scrollbynumber) {
$ionicScrollDelegate.$getByHandle("mainScroll").scrollBy(0, -1 * scrollbynumber, true);
scrollbynumber = 0;
}
// we are turning off, so scroll by back
}
}
$scope.closeIfOpen = function (event) {
if (event != undefined) {
if (event.Event.ShowScrub)
toggleGroup(event);
}
};
$scope.isGroupShown = function (event) {
// console.log ("IS SHOW INDEX is " + ndx);
//console.log ("SHOW GROUP IS " + showGroup);
return (event == undefined) ? false : event.Event.ShowScrub;
};
//---------------------------------------------------
// reload view
//---------------------------------------------------
$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
// which is the view - and when you are in the modal it will go away
//console.log("*** Refreshing Modal view ***");
//$state.go($state.current, {}, {reload: true});
$rootScope.rand = Math.floor(Math.random() * (999999 - 111111 + 1)) + 111111;
$ionicLoading.show({
template: $translate.instant('kRefreshedView'),
noBackdrop: true,
duration: 3000
});
};
//---------------------------------------------------
// when you tap a list entry - to break search loop
//---------------------------------------------------
$scope.tapped = function () {
// console.log("*** TAPPED ****");
// if he tapped, the we are not infinite loading on ion-infinite
if (enableLoadMore == false) {
moreEvents = true;
enableLoadMore = true;
// console.log("REMOVING ARTIFICAL LOAD MORE BLOCK");
}
};
$scope.$on('$ionicView.loaded', function () {
// console.log("**VIEW ** Events Ctrl Loaded");
});
//-------------------------------------------------------------------------
// Lets make sure we set screen dim properly as we enter
// The problem is we enter other states before we leave previous states
// from a callback perspective in ionic, so we really can't predictably
// 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 () {
// console.log("**VIEW ** Events Ctrl Entered");
NVR.setAwake(false);
$ionicPopover.fromTemplateUrl('templates/events-popover.html', {
scope: $scope,
}).then(function (popover) {
$scope.popover = popover;
});
// coming to this view clears all notification badges
EventServer.sendMessage('push', {
type: 'badge',
badge: 0,
});
// also clear bells
$rootScope.alarmCount = "0";
$rootScope.isAlarm = 0;
// reset badge count
if (window.FirebasePlugin && $rootScope.platformOS == 'ios') {
NVR.debug ('Clearing app badge count');
window.FirebasePlugin.setBadgeNumber(0);
}
});
$scope.$on('$ionicView.leave', function () {
//console.log("**VIEW ** Events Ctrl Left");
});
$scope.$on('$ionicView.unloaded', function () {
//console.log("**VIEW ** Events Ctrl Unloaded");
//console.log("*** MODAL ** Destroying modal too");
if ($scope.modal !== undefined) {
$scope.modal.remove();
}
});
//---------------------------------------------------
// used to hide loading image toast
//---------------------------------------------------
$scope.finishedLoadingImage = function (ndx) {
// console.log("*** Events image FINISHED loading index: "+ndx+"***");
$ionicLoading.hide();
};
//---------------------------------------------------
//
//---------------------------------------------------
$scope.clearSearch = function () {
$scope.search.text = "";
};
//---------------------------------------------------
// Called when user toggles search
//---------------------------------------------------
$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) {
moreEvents = true;
enableLoadMore = true;
//console.log("REMOVING ARTIFICAL LOAD MORE BLOCK");
}
};
$scope.modalGraph = function () {
$scope.lastVideoStateTime = {
'time':''
};
$ionicModal.fromTemplateUrl('templates/events-modalgraph.html', {
scope: $scope, // give ModalCtrl access to this scope
animation: 'slide-in-up',
id: 'modalgraph',
})
.then(function (modal) {
$scope.modal = modal;
$scope.modal.show();
});
};
$scope.analyzeEvent = function (ev) {
$scope.lastVideoStateTime = {
'time':''
};
$scope.event = ev;
$ionicModal.fromTemplateUrl('templates/timeline-modal.html', {
scope: $scope, // give ModalCtrl access to this scope
animation: 'slide-in-up',
id: 'analyze',
})
.then(function (modal) {
$scope.modal = modal;
$scope.modal.show();
});
};
$scope.$on('modal.removed', function (e, m) {
if (m.id != 'footage')
return;
NVR.debug("Rebinding watchers of eventCtrl");
setupWatchers();
//console.log ("************** FOOTAGE CLOSED");
});
$scope.showThumbnail = function (b, f) {
if (!f) { // api update needed
$ionicPopup.alert({
title: $translate.instant('kNote'),
template: "{{'kApiUpgrade' | translate }}",
okText: $translate.instant('kButtonOk'),
cancelText: $translate.instant('kButtonCancel'),
});
return;
}
$scope.thumbnailLarge = b + '/index.php?view=image&fid=' + f+$rootScope.authSession;
$ionicModal.fromTemplateUrl('templates/image-modal.html', {
scope: $scope,
animation: 'slide-in-up',
id: 'thumbnail',
})
.then(function (modal) {
$scope.modal = modal;
$scope.modal.show();
var ld = NVR.getLogin();
});
};
//--------------------------------------------------------
//This is called when we first tap on an event to see
// the feed. It's important to instantiate ionicModal here
// as otherwise you'd instantiate it when the view loads
// and our "Please wait loading" technique I explained
//earlier won't work
//--------------------------------------------------------
$scope.openModalWithSnapshot = function (event) {
openModal(event, 'enabled');
};
$scope.openModal = function (event) {
openModal(event);
};
function openModal(event, snapshot) {
NVR.debug("unbinding eventCtrl watchers as modal has its own");
ionRangeWatcher();
mycarouselWatcher();
//NVR.debug("EventCtrl: Open Modal with Base path " + relativepath);
$scope.modalData = {
"doRefresh": false
};
$scope.event = event;
NVR.setAwake(NVR.getKeepAwake());
$scope.currentEvent = event;
$scope.followSameMonitor = ($scope.id == "0") ? "0" : "1";
var ld = NVR.getLogin();
var sl = 'disabled';
if (ld.showLiveForInProgressEvents) {
sl = 'enabled';
}
$scope.lastVideoStateTime = {
'time':''
};
NVR.debug("Shall I follow the same monitor for prev/next?:"+$scope.followSameMonitor);
$ionicModal.fromTemplateUrl('templates/events-modal.html', {
scope: $scope,
animation: 'slide-in-up',
id: 'footage',
showLive: sl, // seems bool is not allowed...
snapshot: snapshot,
snapshotId: NVR.getSnapshotFrame(),
eventId: event.Event.Id
})
.then(function (modal) {
$scope.modal = modal;
$scope.modal.show();
var ld = NVR.getLogin();
});
}
//--------------------------------------------------------
//We need to destroy because we are instantiating
// it on open
//--------------------------------------------------------
$scope.closeModal = function () {
NVR.debug(">>>EventCtrl:Close & Destroy Modal");
if ($scope.lastVideoStateTime && $scope.lastVideoStateTime.time) {
var diff = moment().diff($scope.lastVideoStateTime.time);
if (diff <= 300) {
NVR.debug ("Not closing model, time interval was only:"+diff+" ms");
return;
}
}
$ionicLoading.hide();
NVR.setAwake(false);
if ($scope.modal !== undefined) {
$scope.modal.remove();
}
if ($scope.modalData.doRefresh) {
$scope.modalData.doRefresh = false;
NVR.debug("Reloading events since we deleted some...");
doRefresh();
}
};
//--------------------------------------------------------
//Cleanup the modal when we're done with it
// I Don't think it ever comes here
//--------------------------------------------------------
$scope.$on('$destroy', function () {
//console.log("Destroy Modal");
if ($scope.modal !== undefined) {
$scope.modal.remove();
}
if ($scope.popover !== undefined)
$scope.popover.remove();
});
//--------------------------------------------------------
// used by infinite scrolling to see if we can get more
//--------------------------------------------------------
$scope.moreDataCanBeLoaded = function () {
//console.log(new Date() + ' ' + moreEvents);
return moreEvents;
};
//--------------------------------------------------------
// stop searching for more data
//--------------------------------------------------------
$scope.cancelSearch = function () {
$ionicLoading.hide(); //Or whatever action you want to preform
enableLoadMore = false;
//console.log("**** CANCELLED ****");
$ionicLoading.show({
template: $translate.instant('kSearchCancelled'),
animation: 'fade-in',
showBackdrop: false,
duration: 2000,
maxWidth: 200,
showDelay: 0
});
};
//--------------------------------------------------------
// loads next page of events
//--------------------------------------------------------
function loadMore() {
// the events API does not return an error for anything
// except greater page limits than reported
//console.log("***** LOADING MORE INFINITE SCROLL ****");
loadMoreTime = Date.now();
if (currentPagePosition > 0 && currentPagePosition >= currentPageLength) {
currEventsPage++;
currentPagePosition = 0;
currentPageLength = 0;
}
NVR.debug("EventCtrl:loadMore() currEventsPage: " + currEventsPage + ", currentPagePosition: " + currentPagePosition + ", currentPageLength: " + currentPageLength);
if (currEventsPage > maxEventsPage) {
moreEvents = false;
$scope.nextEvents = true;
NVR.debug("No more - We have a total of " + maxEventsPage + " and are at page=" + currEventsPage);
// console.log("*** At Page " + currEventsPage + " of " + maxEventsPage + ", not proceeding");
$ionicLoading.hide();
return;
}
if (!enableLoadMore) {
$ionicLoading.hide();
moreEvents = false; // Don't ion-scroll till enableLoadMore is true;
$scope.nextEvents = true;
$scope.$broadcast('scroll.infiniteScrollComplete');
// console.log("**** LOADMORE ARTIFICALLY DISABLED");
return;
}
var loadingStr = "";
if ($scope.search.text != "") {
var toastStr = $translate.instant('kPleaseWait') +'...'+ currEventsPage;
// console.log ("SHOW " + toastStr );
$ionicLoading.show({
maxwidth: 100,
noBackdrop:true,
scope: $scope,
template: toastStr,
//template: ''
});
loadingStr = "none";
}
nolangFrom = "";
nolangTo = "";
if ($rootScope.fromString)
nolangFrom = moment($rootScope.fromString).locale('en').format("YYYY-MM-DD HH:mm:ss");
if ($rootScope.toString)
nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss");
if (currentPagePosition && currentPageData) {
loadEvents(currentPageData);
//console.log("Got new page of events");
moreEvents = true;
}
else {
NVR.getEvents($scope.id, currEventsPage, loadingStr, nolangFrom, nolangTo, false,$rootScope.monitorsFilter)
.then( function (data) {
// console.log(JSON.stringify(data.pagination));
if (data.pagination && data.pagination.pageCount)
maxEventsPage = data.pagination.pageCount;
loadEvents(data);
currentPageData = data;
//console.log("Got new page of events");
moreEvents = true;
},
function (error) {
// console.log("*** No More Events to Load, Stop Infinite Scroll ****");
moreEvents = false;
$ionicLoading.hide();
});
}
}
$scope.loadMore = function () {
var now = Date.now();
if (now - loadMoreTime > 1500) {
NVR.debug("$scope.loadMore > loadMore() ... delta: " + (now - loadMoreTime));
loadMore();
$scope.$broadcast('scroll.infiniteScrollComplete');
}
else {
NVR.debug("$scope.loadMore ... delta: " + (now - loadMoreTime));
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 250);
}
};
function loadEvents(data) {
var loginData = NVR.getLogin();
var myevents = data.events;
NVR.debug("EventCtrl:loadEvents() myevents.length: " + myevents.length + ", currEventsPage: " + currEventsPage + ", currentPagePosition: " + currentPagePosition);
if (data.events.length == 0) {
NVR.debug("EventCtrl:loadEvents() no events so we must have reached the end.");
moreEvents = false;
$ionicLoading.hide();
currEventsPage++;
return;
}
//console.log ("-------->MON LEN"+$scope.monitors.length);
currentPageLength = myevents.length;
var eventsLoaded = 0;
var prevPagePosition = currentPagePosition;
NVR.debug("maxEventsToLoad: " + maxEventsToLoad);
for (currentPagePosition; currentPagePosition < myevents.length && eventsLoaded < maxEventsToLoad; currentPagePosition++) {
var idfound = true;
if (loginData.persistMontageOrder) {
idfound = false;
for (var i = 0; i < $scope.monitors.length; i++) {
if ($scope.monitors[i].Monitor.Id == myevents[currentPagePosition].Event.MonitorId && (NVR.isNotHidden(myevents[currentPagePosition].Event.MonitorId) || showHiddenMonitors)) {
// console.log ("FOUND IT");
//console.log ( $scope.monitors[i].Monitor.Id + " MATCHES " + myevents[currentPagePosition].Event.MonitorId);
idfound = true;
break;
}
}
}
//console.log ("IDFOUND="+idfound + " AND MON LEN="+$scope.monitors.length);
myevents[currentPagePosition].Event.humanizeTime = humanizeTime(myevents[currentPagePosition].Event.StartTime);
myevents[currentPagePosition].Event.streamingURL = NVR.getStreamingURL(myevents[currentPagePosition].Event.MonitorId);
myevents[currentPagePosition].Event.recordingURL = NVR.getRecordingURL(myevents[currentPagePosition].Event.MonitorId);
myevents[currentPagePosition].Event.imageMode = NVR.getImageMode(myevents[currentPagePosition].Event.MonitorId);
// console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[currentPagePosition].Event.streamingURL);
// console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[currentPagePosition].Event.recordingURL);
myevents[currentPagePosition].Event.MonitorName = NVR.getMonitorName(myevents[currentPagePosition].Event.MonitorId);
myevents[currentPagePosition].Event.ShowScrub = false;
//myevents[currentPagePosition].Event.height = eventsListDetailsHeight;
// now construct base path
// get thumbW/H
var tempMon = NVR.getMonitorObject(myevents[currentPagePosition].Event.MonitorId);
if (tempMon != undefined) {
var mw = parseInt(tempMon.Monitor.Width);
var mh = parseInt(tempMon.Monitor.Height);
var mo = parseInt(tempMon.Monitor.Orientation);
myevents[currentPagePosition].Event.Rotation = '';
var th = computeThumbnailSize(mw, mh, mo);
myevents[currentPagePosition].Event.thumbWidth = th.w;
myevents[currentPagePosition].Event.thumbHeight = th.h;
myevents[currentPagePosition].Event.rowHeight = $scope.rowHeight;
// myevents[currentPagePosition].Event.rowHeight = th.h + 50;
// console.log ("************* RH:"+myevents[currentPagePosition].Event.rowHeight);
}
// in multiserver BasePath is login url for frames
// http://login.url/index.php?view=frame&eid=19696772&fid=21
// console.log ("COMPARING "+NVR.getLogin().url+ " TO " +myevents[currentPagePosition].Event.recordingURL);
myevents[currentPagePosition].Event.videoPath = myevents[currentPagePosition].Event.recordingURL + "/index.php?view=view_video&eid=" + myevents[currentPagePosition].Event.Id;
// if (idfound)
if (idfound) {
//NVR.debug ("PUSHING "+JSON.stringify(myevents[currentPagePosition]));
$scope.events.push(myevents[currentPagePosition]);
eventsLoaded++;
//console.log ("SCOPE EVENTS LEN="+$scope.events.length);
} else {
//NVR.debug ("Skipping Event MID = " + myevents[currentPagePosition].Event.MonitorId);
}
} //for
NVR.debug("EventCtrl:loadEvents() Events added to view: " + (currentPagePosition - prevPagePosition));
}
function recomputeThumbSize() {
// NVR.debug("EventCtrl: recompute thumbnails");
// remember, devHeight/devWidth upate 300ms after rotation
$timeout ( function () {
for (var i = 0; i < $scope.events.length; i++) {
var tempMon = NVR.getMonitorObject($scope.events[i].Event.MonitorId);
if (tempMon != undefined) {
var mw = parseInt(tempMon.Monitor.Width);
var mh = parseInt(tempMon.Monitor.Height);
var mo = parseInt(tempMon.Monitor.Orientation);
var th = computeThumbnailSize(mw, mh, mo);
$scope.events[i].Event.thumbWidth = th.w;
$scope.events[i].Event.thumbHeight = th.h;
//console.log ("Setting to "+th.w+"*"+th.h);
eventHeight = document.getElementById('item-0').offsetHeight;
}
}
},500);
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
// credit: https://stackoverflow.com/a/14731922
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { w: Math.round(srcWidth*ratio), h: Math.round(srcHeight*ratio) };
}
function computeThumbnailSize(mw, mh, mo) {
// if ZM is going to rotate the view, lets flip our dimensions
if (mo != 0 && mo != 180) {
var tmp = mw;
mw = mh;
mh = tmp;
}
var ld = NVR.getLogin();
var landscape = ($rootScope.devWidth > $rootScope.devHeight) ? true:false;
var maxRowHeight;
if (ld.eventViewThumbsSize == 'large') {
maxRowHeight = $scope.rowHeight - 190;
if (landscape) {
// go till 90% of width in large landscape, but restricted to useable row height
return calculateAspectRatioFit(mw, mh, 0.9* $rootScope.devWidth, maxRowHeight);
} else {
// go till 80% of width in large portrait, but restricted to useable row height
return calculateAspectRatioFit(mw, mh, 0.8* $rootScope.devWidth, maxRowHeight);
}
} else { // small
maxRowHeight = $scope.rowHeight - 150;
if (landscape) {
// go till 50% of width in small landscape, but restricted to useable row height
return calculateAspectRatioFit(mw, mh, 0.5* $rootScope.devWidth, maxRowHeight);
} else {
// go till 30% of width in small portrait, but restricted to useable row height
return calculateAspectRatioFit(mw, mh, 0.3* $rootScope.devWidth, maxRowHeight);
}
}
}
$scope.constructThumbnail = function (event) {
var stream = "";
//console.log(event.Event.Notes);
var snapshotFrame = NVR.getSnapshotFrame();
if (($scope.loginData.eventViewThumbs.substring(0, 9) == 'objdetect') && event.Event.Notes.includes("detected:")) {
snapshotFrame = $scope.loginData.eventViewThumbs;
}
stream = event.Event.recordingURL +
"/index.php?view=image&fid=" +
snapshotFrame+"&eid="+event.Event.Id +
"&width=" + event.Event.thumbWidth * 2 +
"&height=" + event.Event.thumbHeight * 2;
stream += $rootScope.authSession;
stream += NVR.insertSpecialTokens();
return stream;
};
$scope.constructScrubFrame = function (event, slide) {
var stream = "";
stream = event.Event.recordingURL + "/index.php?view=image" +
"&fid=" + slide.id + $scope.outlineMotionParam;
stream += $rootScope.authSession;
stream += NVR.insertSpecialTokens();
return stream;
};
$scope.constructAlarmFrame = function (event, alarm, motion) {
var stream = "";
stream = event.Event.recordingURL +
"/index.php?view=image&fid=" + alarm.id;
if (motion) stream += $scope.outlineMotionParam;
stream += $rootScope.authSession;
stream += NVR.insertSpecialTokens();
// console.log ("alarm:"+stream);
return stream;
};
$scope.toggleObjectDetectionFilter = function () {
var ld = NVR.getLogin();
ld.objectDetectionFilter = !ld.objectDetectionFilter;
NVR.setLogin(ld);
NVR.debug ("object detection filter: "+ld.objectDetectionFilter);
$scope.loginData = NVR.getLogin();
doRefresh();
};
$scope.toggleMinAlarmFrameCount = function () {
var ld = NVR.getLogin();
// console.log("Toggling " + ld.enableAlarmCount);
ld.enableAlarmCount = !ld.enableAlarmCount;
NVR.setLogin(ld);
$scope.loginData = NVR.getLogin();
doRefresh();
};
//--------------------------------------
// formats events dates in a nice way
//---------------------------------------
function humanizeTime(str) {
//console.log ("Time:"+str+" TO LOCAL " + moment(str).local().toString());
//if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).fromNow();
// else
// return moment(str).fromNow();
}
$scope.humanize = function (num) {
var min = Math.floor(num / 60);
var sec = Math.floor(num - min * 60);
stime = "";
if (min) stime += min + "m ";
if (sec) stime += sec + "s";
return stime;
};
$scope.prettifyDate = function (str) {
if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).tz(moment.tz.guess()).format('MMM Do');
else
return moment(str).format('MMM Do');
};
function prettifyDate(str) {
if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).tz(moment.tz.guess()).format('MMM Do');
else
return moment(str).format('MMM Do');
}
$scope.prettifyTime = function (str) {
if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).tz(moment.tz.guess()).format(NVR.getTimeFormat());
else
return moment(str).format(NVR.getTimeFormat());
};
$scope.prettifyTimeSec = function (str) {
if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).tz(moment.tz.guess()).format(NVR.getTimeFormatSec());
else
return moment(str).format(NVR.getTimeFormatSec());
};
$scope.prettify = function (str) {
if (NVR.getLogin().useLocalTimeZone)
return moment.tz(str, NVR.getTimeZoneNow()).tz(moment.tz.guess()).format(NVR.getTimeFormat() + ', MMMM Do YYYY');
else
return moment(str).format(NVR.getTimeFormat() + ', MMMM Do YYYY');
};
//--------------------------------------------------------
// For consistency we are keeping the refresher list
// but its a dummy. The reason I deviated is because
// refresh with infinite scroll is a UX problem - its
// easy to pull to refresh when scrolling up with
// a large list
//--------------------------------------------------------
$scope.dummyDoRefresh = function () {
$scope.$broadcast('scroll.refreshComplete');
};
$scope.doRefresh = function () {
doRefresh();
}; //dorefresh
function doRefresh() {
// console.log("***Pull to Refresh");
NVR.debug("Reloading monitors");
maxEventsPage = 1;
currEventsPage = 1;
currentLength = 0;
currentPagePosition = 0;
currentPageLength = 0;
var refresh = NVR.getMonitors(1);
refresh.then(function (data) {
$scope.monitors = data;
message = data;
/* var ld = NVR.getLogin();
if (ld.persistMontageOrder) {
var tempMon = data;
$scope.monitors = NVR.applyMontageMonitorPrefs(tempMon, 2)[0];
} else {
$scope.monitors = data;
}*/
getInitialEvents();
moreEvents = true;
});
$scope.$broadcast('scroll.refreshComplete');
}
}]);