added a new way to scan qr codes from mobile browsers
This commit is contained in:
parent
dac2f8b949
commit
83681967df
@ -32,7 +32,7 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
vendors: {
|
||||
src: ['public/lib/qrcode-generator/js/qrcode.js', 'public/src/js/jsqrcode/grid.js', 'public/src/js/jsqrcode/version.js', 'public/src/js/jsqrcode/detector.js', 'public/src/js/jsqrcode/formatinf.js', 'public/src/js/jsqrcode/errorlevel.js', 'public/src/js/jsqrcode/bitmat.js', 'public/src/js/jsqrcode/datablock.js', 'public/src/js/jsqrcode/bmparser.js', 'public/src/js/jsqrcode/datamask.js', 'public/src/js/jsqrcode/rsdecoder.js', 'public/src/js/jsqrcode/gf256poly.js', 'public/src/js/jsqrcode/gf256.js', 'public/src/js/jsqrcode/decoder.js', 'public/src/js/jsqrcode/qrcode.js', 'public/src/js/jsqrcode/findpat.js', 'public/src/js/jsqrcode/alignpat.js', 'public/src/js/jsqrcode/databr.js', 'public/lib/momentjs/min/moment.min.js', 'public/lib/zeroclipboard/ZeroClipboard.min.js'],
|
||||
src: ['public/src/js/ios-imagefile-megapixel/megapix-image.js', 'public/lib/qrcode-generator/js/qrcode.js', 'public/src/js/jsqrcode/grid.js', 'public/src/js/jsqrcode/version.js', 'public/src/js/jsqrcode/detector.js', 'public/src/js/jsqrcode/formatinf.js', 'public/src/js/jsqrcode/errorlevel.js', 'public/src/js/jsqrcode/bitmat.js', 'public/src/js/jsqrcode/datablock.js', 'public/src/js/jsqrcode/bmparser.js', 'public/src/js/jsqrcode/datamask.js', 'public/src/js/jsqrcode/rsdecoder.js', 'public/src/js/jsqrcode/gf256poly.js', 'public/src/js/jsqrcode/gf256.js', 'public/src/js/jsqrcode/decoder.js', 'public/src/js/jsqrcode/qrcode.js', 'public/src/js/jsqrcode/findpat.js', 'public/src/js/jsqrcode/alignpat.js', 'public/src/js/jsqrcode/databr.js', 'public/lib/momentjs/min/moment.min.js', 'public/lib/zeroclipboard/ZeroClipboard.min.js'],
|
||||
dest: 'public/js/vendors.js'
|
||||
},
|
||||
angular: {
|
||||
|
||||
2
public/css/main.min.css
vendored
2
public/css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -18,9 +18,20 @@
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Scan Code</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<canvas id="qr-canvas" width="300" height="225"></canvas>
|
||||
<video id="qrcode-scanner-video" width="300" height="225"></video>
|
||||
<div class="modal-body text-center">
|
||||
<canvas id="qr-canvas" width="200" height="150"></canvas>
|
||||
<div data-ng-show="isMobile">
|
||||
<div id="file-input-wrapper" class="btn btn-primary">
|
||||
<span class="pull-left text-center">
|
||||
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
|
||||
Get QR code
|
||||
</span>
|
||||
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
<div data-ng-hide="isMobile">
|
||||
<video id="qrcode-scanner-video" width="300" height="225" data-ng-hide="isMobile"></video>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-ng-click="cancel()" data-dismiss="modal">Close</button>
|
||||
|
||||
4
public/js/angularjs-all.min.js
vendored
4
public/js/angularjs-all.min.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/main.min.js
vendored
2
public/js/main.min.js
vendored
File diff suppressed because one or more lines are too long
8
public/js/vendors.min.js
vendored
8
public/js/vendors.min.js
vendored
File diff suppressed because one or more lines are too long
@ -51,24 +51,16 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
|
||||
}
|
||||
|
||||
/* QR modal */
|
||||
#qrcode-scanner-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
z-index: 10000;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
#qrcode-scanner-container.active { display: block; }
|
||||
#qr-canvas { display: none; }
|
||||
#qrcode-scanner-video {
|
||||
margin: 0 auto 10px auto;
|
||||
display: block;
|
||||
}
|
||||
#file-input-wrapper { width: 100%; }
|
||||
#file-input-wrapper input { opacity: 0; }
|
||||
#file-input-wrapper span { width: 100%; }
|
||||
#file-input-wrapper i { display: none; }
|
||||
#file-input-wrapper:hover i { display: inline-block; }
|
||||
|
||||
/* Wrapper for page content to push down footer */
|
||||
#wrap {
|
||||
@ -103,7 +95,7 @@ margin-left: 0;
|
||||
.table-hover>tbody>tr:hover>td, .table-hover>tbody>tr:hover>th {
|
||||
background-color: #F0F7E2;
|
||||
}
|
||||
|
||||
.navbar { min-height: 64px; }
|
||||
.navbar-default .navbar-toggle {
|
||||
border-color: #fff;
|
||||
margin-top: 15px;
|
||||
@ -176,7 +168,7 @@ margin-left: 0;
|
||||
|
||||
.navbar-default .navbar-brand {
|
||||
color: #FFFFFF;
|
||||
padding: 22px 15px;
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
.navbar-form .form-control {
|
||||
@ -195,10 +187,9 @@ margin-left: 0;
|
||||
padding-bottom: 22px;
|
||||
}
|
||||
|
||||
#search {
|
||||
color: #fff;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
}
|
||||
#search-form { color: #fff; }
|
||||
|
||||
#search { font-family: 'Ubuntu', sans-serif; }
|
||||
|
||||
#search.loading {
|
||||
background-image: url('/img/loading.gif');
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
angular.module('insight.system').controller('HeaderController',
|
||||
function($scope, $rootScope, $modal, getSocket, Global, Block) {
|
||||
$scope.global = Global;
|
||||
$scope.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||
|
||||
$rootScope.currency = {
|
||||
factor: 1,
|
||||
|
||||
@ -4,28 +4,87 @@ angular.module('insight.system').controller('ScannerController',
|
||||
function($scope, $rootScope, $modalInstance, Global) {
|
||||
$scope.global = Global;
|
||||
|
||||
// Detect mobile devices
|
||||
var isMobile = {
|
||||
Android: function() {
|
||||
return navigator.userAgent.match(/Android/i);
|
||||
},
|
||||
BlackBerry: function() {
|
||||
return navigator.userAgent.match(/BlackBerry/i);
|
||||
},
|
||||
iOS: function() {
|
||||
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
|
||||
},
|
||||
Opera: function() {
|
||||
return navigator.userAgent.match(/Opera Mini/i);
|
||||
},
|
||||
Windows: function() {
|
||||
return navigator.userAgent.match(/IEMobile/i);
|
||||
},
|
||||
any: function() {
|
||||
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
|
||||
}
|
||||
};
|
||||
|
||||
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
|
||||
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
||||
|
||||
$scope.isMobile = isMobile.any();
|
||||
$scope.scannerLoading = false;
|
||||
|
||||
var $searchInput = angular.element(document.getElementById('search')),
|
||||
cameraInput,
|
||||
video,
|
||||
canvas,
|
||||
$video,
|
||||
context,
|
||||
localMediaStream;
|
||||
|
||||
var _scan = function() {
|
||||
if (localMediaStream) {
|
||||
context.drawImage(video, 0, 0, 300, 225);
|
||||
var _scan = function(evt) {
|
||||
if ($scope.isMobile) {
|
||||
$scope.scannerLoading = true;
|
||||
var files = evt.target.files;
|
||||
|
||||
try {
|
||||
qrcode.decode();
|
||||
} catch(e) {
|
||||
//qrcodeError(e);
|
||||
if (files.length === 1 && files[0].type.indexOf('image/') === 0) {
|
||||
var file = files[0];
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.onload = (function(theFile) {
|
||||
return function(e) {
|
||||
var mpImg = new MegaPixImage(file);
|
||||
mpImg.render(canvas, { maxWidth: 200, maxHeight: 200, orientation: 6 });
|
||||
|
||||
setTimeout(function() {
|
||||
//qrcode.width = canvas.width;
|
||||
//qrcode.height = canvas.height;
|
||||
//qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
|
||||
|
||||
try {
|
||||
//alert(JSON.stringify(qrcode.process(context)));
|
||||
qrcode.decode();
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
})(file);
|
||||
|
||||
// Read in the file as a data URL
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (localMediaStream) {
|
||||
context.drawImage(video, 0, 0, 300, 225);
|
||||
|
||||
setTimeout(_scan, 500);
|
||||
try {
|
||||
qrcode.decode();
|
||||
} catch(e) {
|
||||
//qrcodeError(e);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(_scan, 500);
|
||||
}
|
||||
};
|
||||
|
||||
var _successCallback = function(stream) {
|
||||
@ -36,10 +95,13 @@ angular.module('insight.system').controller('ScannerController',
|
||||
};
|
||||
|
||||
var _scanStop = function() {
|
||||
$scope.scannerLoading = false;
|
||||
$modalInstance.close();
|
||||
if (localMediaStream.stop) localMediaStream.stop();
|
||||
localMediaStream = null;
|
||||
video.src = '';
|
||||
if (!$scope.isMobile) {
|
||||
if (localMediaStream.stop) localMediaStream.stop();
|
||||
localMediaStream = null;
|
||||
video.src = '';
|
||||
}
|
||||
};
|
||||
|
||||
var _videoError = function(err) {
|
||||
@ -54,23 +116,34 @@ angular.module('insight.system').controller('ScannerController',
|
||||
console.log('QR code detected: ' + str);
|
||||
$searchInput
|
||||
.val(str)
|
||||
.triggerHandler('change');
|
||||
.triggerHandler('change')
|
||||
.triggerHandler('submit');
|
||||
};
|
||||
|
||||
$modalInstance.opened.then(function() {
|
||||
//Start the scanner
|
||||
setTimeout(function() {
|
||||
video = document.getElementById('qrcode-scanner-video');
|
||||
canvas = document.getElementById('qr-canvas');
|
||||
$video = angular.element(video);
|
||||
context = canvas.getContext('2d');
|
||||
context.clearRect(0, 0, 300, 225);
|
||||
|
||||
navigator.getUserMedia({video: true}, _successCallback, _videoError);
|
||||
}, 800);
|
||||
});
|
||||
|
||||
$scope.cancel = function() {
|
||||
_scanStop();
|
||||
};
|
||||
|
||||
$modalInstance.opened.then(function() {
|
||||
$rootScope.isCollapsed = true;
|
||||
|
||||
// Start the scanner
|
||||
setTimeout(function() {
|
||||
canvas = document.getElementById('qr-canvas');
|
||||
context = canvas.getContext('2d');
|
||||
|
||||
if ($scope.isMobile) {
|
||||
cameraInput = document.getElementById('qrcode-camera');
|
||||
cameraInput.addEventListener('change', _scan, false);
|
||||
} else {
|
||||
video = document.getElementById('qrcode-scanner-video');
|
||||
$video = angular.element(video);
|
||||
canvas.width = 300;
|
||||
canvas.height = 225;
|
||||
context.clearRect(0, 0, 300, 225);
|
||||
|
||||
navigator.getUserMedia({video: true}, _successCallback, _videoError);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
|
||||
@ -15,9 +15,9 @@
|
||||
<a href="/{{item.link}}">{{item.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form data-ng-controller="SearchController" class="navbar-form navbar-left hidden-xs" role="search" data-ng-submit="search()">
|
||||
<form id="search-form" data-ng-controller="SearchController" class="navbar-form navbar-left hidden-xs" role="search" data-ng-submit="search()">
|
||||
<div class="form-group" data-ng-class="{'has-error': badQuery}">
|
||||
<input id="search" type="text" class="form-control" data-ng-model="q" data-ng-class="{'loading': loading}" placeholder="Search for block, transaction or address" data-ng-change="search()">
|
||||
<input id="search" type="text" class="form-control" data-ng-model="q" data-ng-class="{'loading': loading}" placeholder="Search for block, transaction or address" data-ng-submit="search()">
|
||||
</div>
|
||||
<div class="no_matching text-danger" data-ng-show="badQuery">No matching records found!</div>
|
||||
</form>
|
||||
@ -42,7 +42,7 @@
|
||||
<strong>Height</strong> {{totalBlocks || info.blocks}}
|
||||
</div>
|
||||
</li>
|
||||
<li data-ng-if="getUserMedia">
|
||||
<li>
|
||||
<a href="#" data-ng-click="openScannerModal()"><span class="glyphicon glyphicon-qrcode"></span> Scan</a>
|
||||
</li>
|
||||
<li class="dropdown" data-ng-controller="CurrencyController" data-ng-include="'/views/includes/currency.html'"></li>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<form data-ng-controller="SearchController" class="visible-xs" role="search" data-ng-submit="search()">
|
||||
<form id="search-form-mobile" data-ng-controller="SearchController" class="visible-xs" role="search" data-ng-submit="search()">
|
||||
<div class="form-group" data-ng-class="{'has-error': badQuery}">
|
||||
<input id="search" type="text" class="form-control" data-ng-model="q" data-ng-class="{'loading': loading}" placeholder="Search for block, transaction or address">
|
||||
<input id="search" type="text" class="form-control" data-ng-model="q" data-ng-class="{'loading': loading}" placeholder="Search for block, transaction or address" data-ng-submit="search()">
|
||||
</div>
|
||||
<div class="no_matching text-danger" data-ng-show="badQuery">No matching records found!</div>
|
||||
</form>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user