diff options
| -rw-r--r-- | .DS_Store | bin | 12292 -> 12292 bytes | |||
| -rw-r--r-- | resources/.DS_Store | bin | 10244 -> 10244 bytes | |||
| -rw-r--r-- | resources/ios/.DS_Store | bin | 6148 -> 6148 bytes | |||
| -rw-r--r-- | resources/ios/icon/.DS_Store | bin | 6148 -> 6148 bytes | |||
| -rw-r--r-- | www/.DS_Store | bin | 6148 -> 6148 bytes | |||
| -rw-r--r-- | www/external/FileSaver.min.js | 2 | ||||
| -rw-r--r-- | www/external/canvas-toBlob.js | 124 | ||||
| -rw-r--r-- | www/index.html | 2 | ||||
| -rw-r--r-- | www/js/ModalCtrl.js | 205 |
9 files changed, 228 insertions, 105 deletions
| Binary files differ diff --git a/resources/.DS_Store b/resources/.DS_Store Binary files differindex d446f978..2d429286 100644 --- a/resources/.DS_Store +++ b/resources/.DS_Store diff --git a/resources/ios/.DS_Store b/resources/ios/.DS_Store Binary files differindex d0ea94a6..f31696d2 100644 --- a/resources/ios/.DS_Store +++ b/resources/ios/.DS_Store diff --git a/resources/ios/icon/.DS_Store b/resources/ios/icon/.DS_Store Binary files differindex 5008ddfc..6f4f0587 100644 --- a/resources/ios/icon/.DS_Store +++ b/resources/ios/icon/.DS_Store diff --git a/www/.DS_Store b/www/.DS_Store Binary files differindex 03dd21d2..160b5625 100644 --- a/www/.DS_Store +++ b/www/.DS_Store diff --git a/www/external/FileSaver.min.js b/www/external/FileSaver.min.js new file mode 100644 index 00000000..8bbbf769 --- /dev/null +++ b/www/external/FileSaver.min.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),i="download"in r,o=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),f=e.webkitRequestFileSystem,u=e.requestFileSystem||f||e.mozRequestFileSystem,s=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},c="application/octet-stream",d=0,l=500,w=function(t){var r=function(){if(typeof t==="string"){n().revokeObjectURL(t)}else{t.remove()}};if(e.chrome){r()}else{setTimeout(r,l)}},p=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var i=e["on"+t[r]];if(typeof i==="function"){try{i.call(e,n||e)}catch(o){s(o)}}}},v=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob(["\ufeff",e],{type:e.type})}return e},y=function(t,s,l){if(!l){t=v(t)}var y=this,m=t.type,S=false,h,R,O=function(){p(y,"writestart progress write writeend".split(" "))},g=function(){if(R&&a&&typeof FileReader!=="undefined"){var r=new FileReader;r.onloadend=function(){var e=r.result;R.location.href="data:attachment/file"+e.slice(e.search(/[,;]/));y.readyState=y.DONE;O()};r.readAsDataURL(t);y.readyState=y.INIT;return}if(S||!h){h=n().createObjectURL(t)}if(R){R.location.href=h}else{var i=e.open(h,"_blank");if(i==undefined&&a){e.location.href=h}}y.readyState=y.DONE;O();w(h)},b=function(e){return function(){if(y.readyState!==y.DONE){return e.apply(this,arguments)}}},E={create:true,exclusive:false},N;y.readyState=y.INIT;if(!s){s="download"}if(i){h=n().createObjectURL(t);r.href=h;r.download=s;setTimeout(function(){o(r);O();w(h);y.readyState=y.DONE});return}if(e.chrome&&m&&m!==c){N=t.slice||t.webkitSlice;t=N.call(t,0,t.size,c);S=true}if(f&&s!=="download"){s+=".download"}if(m===c||f){R=e}if(!u){g();return}d+=t.size;u(e.TEMPORARY,d,b(function(e){e.root.getDirectory("saved",E,b(function(e){var n=function(){e.getFile(s,E,b(function(e){e.createWriter(b(function(n){n.onwriteend=function(t){R.location.href=e.toURL();y.readyState=y.DONE;p(y,"writeend",t);w(e)};n.onerror=function(){var e=n.error;if(e.code!==e.ABORT_ERR){g()}};"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=y["on"+e]});n.write(t);y.abort=function(){n.abort();y.readyState=y.DONE};y.readyState=y.WRITING}),g)}),g)};e.getFile(s,{create:false},b(function(e){e.remove();n()}),b(function(e){if(e.code===e.NOT_FOUND_ERR){n()}else{g()}}))}),g)}),g)},m=y.prototype,S=function(e,t,n){return new y(e,t,n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){if(!n){e=v(e)}return navigator.msSaveOrOpenBlob(e,t||"download")}}m.abort=function(){var e=this;e.readyState=e.DONE;p(e,"abort")};m.readyState=m.INIT=0;m.WRITING=1;m.DONE=2;m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null;return S}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})}
\ No newline at end of file diff --git a/www/external/canvas-toBlob.js b/www/external/canvas-toBlob.js new file mode 100644 index 00000000..6d895a78 --- /dev/null +++ b/www/external/canvas-toBlob.js @@ -0,0 +1,124 @@ +/* canvas-toBlob.js + * A canvas.toBlob() implementation. + * 2013-12-27 + * + * By Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr + * License: MIT + * See https://github.com/eligrey/canvas-toBlob.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/canvas-toBlob.js/blob/master/canvas-toBlob.js */ + +(function(view) { +"use strict"; +var + Uint8Array = view.Uint8Array + , HTMLCanvasElement = view.HTMLCanvasElement + , canvas_proto = HTMLCanvasElement && HTMLCanvasElement.prototype + , is_base64_regex = /\s*;\s*base64\s*(?:;|$)/i + , to_data_url = "toDataURL" + , base64_ranks + , decode_base64 = function(base64) { + var + len = base64.length + , buffer = new Uint8Array(len / 4 * 3 | 0) + , i = 0 + , outptr = 0 + , last = [0, 0] + , state = 0 + , save = 0 + , rank + , code + , undef + ; + while (len--) { + code = base64.charCodeAt(i++); + rank = base64_ranks[code-43]; + if (rank !== 255 && rank !== undef) { + last[1] = last[0]; + last[0] = code; + save = (save << 6) | rank; + state++; + if (state === 4) { + buffer[outptr++] = save >>> 16; + if (last[1] !== 61 /* padding character */) { + buffer[outptr++] = save >>> 8; + } + if (last[0] !== 61 /* padding character */) { + buffer[outptr++] = save; + } + state = 0; + } + } + } + // 2/3 chance there's going to be some null bytes at the end, but that + // doesn't really matter with most image formats. + // If it somehow matters for you, truncate the buffer up outptr. + return buffer; + } +; +if (Uint8Array) { + base64_ranks = new Uint8Array([ + 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1 + , -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 + , -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 + , 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + ]); +} +if (HTMLCanvasElement && !canvas_proto.toBlob) { + canvas_proto.toBlob = function(callback, type /*, ...args*/) { + if (!type) { + type = "image/png"; + } if (this.mozGetAsFile) { + callback(this.mozGetAsFile("canvas", type)); + return; + } if (this.msToBlob && /^\s*image\/png\s*(?:$|;)/i.test(type)) { + callback(this.msToBlob()); + return; + } + + var + args = Array.prototype.slice.call(arguments, 1) + , dataURI = this[to_data_url].apply(this, args) + , header_end = dataURI.indexOf(",") + , data = dataURI.substring(header_end + 1) + , is_base64 = is_base64_regex.test(dataURI.substring(0, header_end)) + , blob + ; + if (Blob.fake) { + // no reason to decode a data: URI that's just going to become a data URI again + blob = new Blob + if (is_base64) { + blob.encoding = "base64"; + } else { + blob.encoding = "URI"; + } + blob.data = data; + blob.size = data.length; + } else if (Uint8Array) { + if (is_base64) { + blob = new Blob([decode_base64(data)], {type: type}); + } else { + blob = new Blob([decodeURIComponent(data)], {type: type}); + } + } + callback(blob); + }; + + if (canvas_proto.toDataURLHD) { + canvas_proto.toBlobHD = function() { + to_data_url = "toDataURLHD"; + var blob = this.toBlob(); + to_data_url = "toDataURL"; + return blob; + } + } else { + canvas_proto.toBlobHD = canvas_proto.toBlob; + } +} +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); diff --git a/www/index.html b/www/index.html index ffdc78d4..e1c0fde6 100644 --- a/www/index.html +++ b/www/index.html @@ -99,6 +99,8 @@ <script src="external/angular-carousel.js"></script> <script src="external/ion-pullup.js"></script> <script src="lib/ionic-content-banner/dist/ionic.content.banner.min.js"></script> + <script src="external/FileSaver.min.js"></script> + <script src="external/canvas-toBlob.js"></script> diff --git a/www/js/ModalCtrl.js b/www/js/ModalCtrl.js index cdc7af85..4aa56eb7 100644 --- a/www/js/ModalCtrl.js +++ b/www/js/ModalCtrl.js @@ -1,7 +1,7 @@ // Common Controller for the montage view /* jshint -W041 */ /* jslint browser: true*/ -/* global cordova,StatusBar,angular,console,ionic */ +/* global saveAs, cordova,StatusBar,angular,console,ionic, moment */ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootScope', 'zm', 'ZMDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', function ($scope, $rootScope, zm, ZMDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate) { @@ -51,8 +51,8 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco }); - - + + $scope.radialMenuOptions = { content: '', @@ -173,8 +173,8 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco loadModalNotifications(); - - + + function onPause() { ZMDataModel.zmDebug("ModalCtrl: onpause called"); @@ -302,137 +302,121 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco }); } - + $scope.finishedLoadingImage = function () { // console.log("***Monitor image FINISHED Loading***"); $ionicLoading.hide(); }; - - $scope.getZoomLevel = function() - { - console.log ("ON RELEASE"); + + $scope.getZoomLevel = function () { + console.log("ON RELEASE"); var zl = $ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition(); - console.log (JSON.stringify(zl)); - }; + console.log(JSON.stringify(zl)); + }; + + $scope.onTap = function (m, d) { - $scope.onTap = function (m,d) - { - - moveToMonitor(m,d); + moveToMonitor(m, d); }; - - - - - $scope.onSwipe = function (m, d) - { + + + + + $scope.onSwipe = function (m, d) { var ld = ZMDataModel.getLogin(); - if (!ld.canSwipeMonitors) return; - - if - ($ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom!=1) - { - console.log("Image is zoomed in - not honoring swipe"); - return; - } - moveToMonitor(m,d); - - + if (!ld.canSwipeMonitors) return; + + if ($ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom != 1) { + console.log("Image is zoomed in - not honoring swipe"); + return; + } + moveToMonitor(m, d); + + }; - - function moveToMonitor(m,d) - { - var curstate = $ionicHistory.currentStateName(); - var found=0; + + function moveToMonitor(m, d) { + var curstate = $ionicHistory.currentStateName(); + var found = 0; var mid; mid = ZMDataModel.getNextMonitor(m, d); - - if (curstate != "monitors") - { - - do - { + + if (curstate != "monitors") { + + do { mid = ZMDataModel.getNextMonitor(m, d); m = mid; - console.log ("Next Monitor is "+m); - - - found = 0; - for (var i = 0 ; i< $scope.monitors.length; i++) - { - if ($scope.monitors[i].Monitor.Id == mid && $scope.monitors[i].Monitor.listDisplay != 'noshow') - { - found = 1; - console.log (mid + "is part of the monitor list"); - ZMDataModel.zmDebug("ModalCtrl: swipe detected, moving to " + mid); - break; - } + console.log("Next Monitor is " + m); + + + found = 0; + for (var i = 0; i < $scope.monitors.length; i++) { + if ($scope.monitors[i].Monitor.Id == mid && $scope.monitors[i].Monitor.listDisplay != 'noshow') { + found = 1; + console.log(mid + "is part of the monitor list"); + ZMDataModel.zmDebug("ModalCtrl: swipe detected, moving to " + mid); + break; } + } } - while (found !=1); + while (found != 1); } - + var slidein; var slideout; - var dirn=d; - if (dirn==1) - { + var dirn = d; + if (dirn == 1) { slideout = "animated slideOutLeft"; slidein = "animated slideInRight"; - } - else - { + } else { slideout = "animated slideOutRight"; slidein = "animated slideInLeft"; } - + var element = angular.element(document.getElementById("monitorimage")); element.addClass(slideout) .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', outWithOld); - - function outWithOld() - { - - + + function outWithOld() { + + $scope.rand = Math.floor((Math.random() * 100000) + 1); - $scope.animationInProgress = true; - - $timeout (function() - { + $scope.animationInProgress = true; + + $timeout(function () { element.removeClass(slideout); element.addClass(slidein) - .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', inWithNew ); + .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', inWithNew); $scope.monitorId = mid; $scope.monitorName = ZMDataModel.getMonitorName(mid); - },200); + }, 200); } - function inWithNew() - { - - element.removeClass(slidein); - $scope.animationInProgress = false; - + function inWithNew() { + + element.removeClass(slidein); + $scope.animationInProgress = false; + } - + $ionicLoading.hide(); $ionicLoading.show({ template: "please wait...", noBackdrop: true, duration: zm.loadingTimeout, }); - - + + } - - + + //----------------------------------------------------------------------- // Sucess/Error handlers for saving a snapshot of the @@ -474,29 +458,42 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco var loginData = ZMDataModel.getLogin(); var url = loginData.streamingurl + '/cgi-bin/zms?mode=single&monitor=' + mid + - '&user=' + loginData.username + - '&pass=' + loginData.password; + $rootScope.authSession; ZMDataModel.zmLog("SavetoPhone:Trying to save image from " + url); var img = new Image(); img.onload = function () { + console.log("********* ONLOAD"); canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; context = canvas.getContext('2d'); context.drawImage(img, 0, 0); - try { - imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); - imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); - cordova.exec( - SaveSuccess, - SaveError, - 'Canvas2ImagePlugin', - 'saveImageDataToLibrary', [imageData] - ); - } catch (e) { - - SaveError(e.message); + + imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); + imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); + + if ($rootScope.platformOS != "desktop") { + try { + + cordova.exec( + SaveSuccess, + SaveError, + 'Canvas2ImagePlugin', + 'saveImageDataToLibrary', [imageData] + ); + } catch (e) { + + SaveError(e.message); + } + } else { + + + var fname = $scope.monitorName + "-" + + moment().format('MMM-DD-YY_HH-mm-ss') + ".png"; + canvas.toBlob(function (blob) { + saveAs(blob, fname); + }); } }; try { @@ -547,6 +544,4 @@ angular.module('zmApp.controllers').controller('ModalCtrl', ['$scope', '$rootSco }); -}]); - - +}]);
\ No newline at end of file |
