Commit c3cd6228 authored by Benoit Lavenier's avatar Benoit Lavenier

[fix] Fix QRcode on android device (do not mangle JS file, when uglify)

[enh] QRCode: Change the JS lib, and generate as SVG
[enh] QRCode: Generate SVG when loaded wallet data
[enh] QRCode: toggle in fullscreen, on small screen
parent d5ee8fbd
......@@ -42,13 +42,16 @@ if (rootdir && !skip) {
let indexPath = path.join(wwwPath, 'index.html');
const jsFilter = filter(["**/*.js", "!**/vendor/*", '!**/config.js'], { restore: true });
const cssFilter = filter("**/*.css", { restore: true });
const jsFilter = filter(['**/*.js', '!**/vendor/*', '!**/config.js'], { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
const revFilesFilter = filter(['**/*', '!**/index.html', '!**/config.js'], { restore: true });
const uglifyOptions = {
toplevel: true,
warnings: true,
ecma: '2015',
ecma: '5',
mangle: {
reserved: ['qrcode', 'Base58']
},
compress: {
global_defs: {
"@console.log": "alert"
......
......@@ -1129,19 +1129,19 @@ html, body {
right: 0;
width: 0;
height: 0;
background: #fff;
z-index: 1;
background: white;
z-index: 5;
-webkit-backface-visibility: hidden !important;
backface-visibility: hidden !important;
-webkit-transition: all 0.2s ease-in-out !important;
transition: all 0.2s ease-in-out !important;
overflow: hidden;
img {
svg, img {
display: unset;
float: right;
width: 0;
height: 0;
z-index: 1;
z-index: 5;
transition: all 0.2s ease-in-out !important;
}
}
......@@ -1149,37 +1149,64 @@ html, body {
.qrcode.on {
width: 50px;
height: 50px;
padding: 3px;
padding: 0;
margin: 7px;
img {
width: 44px;
height: 44px;
svg, img {
width: 50px;
height: 50px;
}
}
.qrcode.on.active {
margin: 0 !important;
padding: 10px;
padding: 0;
width: 200px;
height: 200px;
img {
width: 180px;
height: 180px;
svg, img {
width: 224px;
height: 224px;
margin: -12px -12px;
}
}
}
@media screen and (max-width: $screen-sm-max) {
.view-wallet,
.view-identity {
.view-wallet-tx,
.view-identity,
.view-identity-tx {
.hero.hero-qrcode-active {
h1, h2, h3, h4, h5, i.avatar {
margin-right: 200px;
//margin-right: 200px;
}
}
.qrcode.on.active {
width: 100%;
height: 100%;
z-index: 10001;
svg, img {
width: calc(100%);
height: 100%;
margin: 0;
}
}
}
}
@media screen and (min-width: $screen-md) {
.view-wallet,
.view-wallet-tx,
.view-identity,
.view-identity-tx {
.qrcode.on.active .footer {
display: none;
visibility: hidden;
}
}
}
.popover-wallet-actions {
height: 400px;
......
......@@ -63,7 +63,6 @@
<!-- build:js dist_js/vendor.js -->
<!-- vendor js -->
<script src="lib/moment/min/moment-with-locales.min.js"></script>
<script src="lib/numeral/numeral.js"></script>
<script src="lib/numeral/languages/fr.js"></script>
......@@ -72,10 +71,13 @@
<script src="lib/numeral/languages/es.js"></script>
<script src="lib/numeral/languages/it.js"></script>
<script src="js/vendor/numeral.eo.js"></script>
<script src="lib/qrcode-generator/js/qrcode.js"></script>
<script src="lib/aes-js/index.js"></script>
<script src="lib/moment/min/moment-with-locales.min.js"></script>
<script src="lib/socket.io-client/dist/socket.io.min.js"></script>
<script src="lib/underscore/underscore-min.js"></script>
<script src="lib/qrcode.js/qrcode.min.js"></script>
<script src="lib/aes-js/index.js"></script>
<script src="lib/chart.js/dist/Chart.min.js"></script>
<!-- ionic/angular js -->
......
......@@ -105,15 +105,17 @@ function WalletController($scope, $rootScope, $q, $ionicPopup, $timeout, $state,
$scope.formData = walletData;
$scope.loading=false; // very important, to avoid TX to be display before wallet.currentUd is loaded
$scope.updateView();
$scope.addListeners();
$scope.showQRCode();
if (wallet.isDefault()) $scope.showHelpTip();
$scope.addListeners();
UIUtils.loading.hide(10); // loading could have be open (e.g. new account)
})
.catch(function(err){
if (err === 'CANCELLED') {
return $scope.showHome();
$scope.showHome();
return;
}
UIUtils.onError('ERROR.LOAD_WALLET_DATA_ERROR')(err);
});
......@@ -469,28 +471,26 @@ function WalletController($scope, $rootScope, $q, $ionicPopup, $timeout, $state,
};
$scope.showQRCode = function(timeout) {
if (!$scope.qrcodeId || !$scope.formData.pubkey) return; // Skip
if (!$scope.qrcode) {
$scope.qrcode = new QRCode(
$scope.qrcodeId,
{
text: $scope.formData.pubkey,
width: 180,
height: 180,
correctLevel: QRCode.CorrectLevel.L
});
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
}
else {
$scope.qrcode.clear();
$scope.qrcode.makeCode($scope.formData.pubkey);
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
if (!wallet || !$scope.qrcodeId) return; // Skip
// Get the DIV element
var element = angular.element(document.querySelector('#' + $scope.qrcodeId + ' .content'));
if (!element) {
console.error("[wallet-controller] Cannot found div #{0} for the QRCode. Skipping.".format($scope.qrcodeId));
return;
}
wallet.loadQrCode()
.then(function(svg) {
element.html(svg);
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
});
};
$scope.hideQRCode = function() {
if ($scope.qrcode) {
$scope.qrcode.clear();
if (!$scope.qrcodeId) return;
var element = angular.element(document.querySelector('#' + $scope.qrcodeId));
if (element) {
UIUtils.motion.toggleOff({selector: '#'+$scope.qrcodeId});
}
};
......@@ -689,6 +689,7 @@ function WalletTxController($scope, $ionicPopover, $state, $timeout, $location,
$scope.loading = true;
$scope.settings = csSettings.data;
$scope.listeners = [];
$scope.qrcodeId = 'qrcode-wallet-tx-' + $scope.$id;
var wallet;
......@@ -723,7 +724,7 @@ function WalletTxController($scope, $ionicPopover, $state, $timeout, $location,
$scope.$on('$ionicView.leave', $scope.leave);
$scope.load = function() {
if (!wallet) return;
if (!wallet) return $q.reject('Missing wallet');
var hasMinData = wallet.isDataLoaded({minData: true});
var options = {
......@@ -740,15 +741,21 @@ function WalletTxController($scope, $ionicPopover, $state, $timeout, $location,
$scope.formData = walletData;
$scope.loading = false; // very important, to avoid TX to be display before wallet.currentUd is loaded
$scope.updateView();
$scope.addListeners();
$scope.showFab('fab-transfer');
$scope.showQRCode();
if (wallet.isDefault()) $scope.showHelpTip();
$scope.addListeners();
UIUtils.loading.hide(); // loading could have be open (e.g. during login phase)
return UIUtils.loading.hide(10); // loading could have be open (e.g. during login phase)
})
.catch(function(err){
if (err === 'CANCELLED') {
$scope.showHome();
return;
}
console.error(err);
UIUtils.onError('ERROR.LOAD_WALLET_DATA_ERROR')(err);
});
};
......@@ -805,6 +812,31 @@ function WalletTxController($scope, $ionicPopover, $state, $timeout, $location,
.catch(UIUtils.onError('ERROR.REFRESH_WALLET_DATA'));
};
$scope.showQRCode = function(timeout) {
if (!wallet || !$scope.qrcodeId) return; // Skip
// Get the DIV element
var element = angular.element(document.querySelector('#' + $scope.qrcodeId + ' .content'));
if (!element) {
console.error("[wallet-controller] Cannot found div #{0} for the QRCode. Skipping.".format($scope.qrcodeId));
return;
}
wallet.loadQrCode()
.then(function(svg) {
element.html(svg);
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
});
};
$scope.hideQRCode = function() {
if (!$scope.qrcodeId) return;
var element = angular.element(document.querySelector('#' + $scope.qrcodeId));
if (element) {
UIUtils.motion.toggleOff({selector: '#'+$scope.qrcodeId});
}
};
/* -- add listeners -- */
$scope.addListeners = function() {
......
......@@ -1079,7 +1079,8 @@ function WotIdentityViewController($scope, $rootScope, $controller, $timeout, $s
if ($scope.loading) { // load once
return $scope.load(state.stateParams.pubkey.trim(), state.stateParams.uid, options)
.then(onLoadSuccess);
.then(onLoadSuccess)
.catch(UIUtils.onError("ERROR.LOAD_IDENTITY_FAILED"));
}
}
......@@ -1138,27 +1139,26 @@ function WotIdentityViewController($scope, $rootScope, $controller, $timeout, $s
$scope.showQRCode = function(timeout) {
if (!$scope.qrcodeId || !$scope.formData.pubkey) return; // Skip
if (!$scope.qrcode) {
$scope.qrcode = new QRCode(
$scope.qrcodeId,
{
text: $scope.formData.pubkey,
width: 180,
height: 180,
correctLevel: QRCode.CorrectLevel.L
});
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
// Get the DIV element
var element = angular.element(document.querySelector('#' + $scope.qrcodeId + ' .content'));
if (!element) {
console.error("[wot-controller] Cannot found div #{0} for the QRCode. Skipping.".format($scope.qrcodeId));
return;
}
else {
$scope.qrcode.clear();
$scope.qrcode.makeCode($scope.formData.pubkey);
console.debug("[wot-controller] Generating QR code for identity...");
$timeout(function() {
var svg = UIUtils.qrcode.svg($scope.formData.pubkey);
element.html(svg);
UIUtils.motion.toggleOn({selector: '#'+$scope.qrcodeId}, timeout || 1100);
}
});
};
$scope.hideQRCode = function() {
if ($scope.qrcode) {
$scope.qrcode.clear();
if (!$scope.qrcodeId) return;
var element = angular.element(document.querySelector('#' + $scope.qrcodeId));
if (element) {
UIUtils.motion.toggleOff({selector: '#'+$scope.qrcodeId});
}
};
......
......@@ -42,6 +42,7 @@ angular.module('cesium.http.services', ['cesium.cache.services'])
reject({ucode: 404, message: 'Resource not found' + (url ? ' ('+url+')' : '')});
}
else if (url) {
console.error('[http] Get HTTP error {status: ' + status + '} on [' + url + ']');
reject('Error while requesting [' + url + ']');
}
else {
......
......@@ -288,6 +288,13 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
function loadData(pubkey, fromTime) {
var now = Date.now();
var data;
// Alert user, when request is too long (> 2s)
$timeout(function() {
if (!data) UIUtils.loading.update({template: "COMMON.LOADING_WAIT"});
}, 2000);
return $q.all([
// Load Sources
......@@ -299,7 +306,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
.then(function(res) {
// Copy sources and balance
var data = res[0];
data = res[0];
data.tx = res[1];
var txPendings = [];
......
// var qrcode;
angular.module('cesium.utils.services', [])
// Replace the '$ionicPlatform.ready()', to enable multiple calls
......@@ -740,6 +742,50 @@ angular.module('cesium.utils.services', [])
toggleOff: toggleOff
};
function createQRCodeObj(text, typeNumber,
errorCorrectionLevel, mode, mb) {
mb = mb || 'default'; // default | SJIS | UTF-8
qrcode.stringToBytes = qrcode.stringToBytesFuncs[mb];
var qr = qrcode(typeNumber || 4, errorCorrectionLevel || 'M');
qr.addData(text, mode);
qr.make();
return qr;
}
/**
* Create a QRCode as an <svg> tag
* @param text
* @param typeNumber
* @param errorCorrectionLevel
* @param mode
* @param mb multibyte ? value: 'default' | 'SJIS' | 'UTF-8'
* @returns {string}
*/
function getSvgQRCode(text, typeNumber,
errorCorrectionLevel, mode, mb) {
var qr = createQRCodeObj(text, typeNumber, errorCorrectionLevel, mode, mb);
return qr.createSvgTag();
}
/**
* Create a QRCode as an <img> tag
* @param text
* @param typeNumber
* @param errorCorrectionLevel
* @param mode
* @param mb multibyte ? value: 'default' | 'SJIS' | 'UTF-8'
* @returns {string}
*/
function getImgQRCode(text, typeNumber,
errorCorrectionLevel, mode, mb) {
var qr = createQRCodeObj(text, typeNumber, errorCorrectionLevel, mode, mb);
return qr.createImgTag();
}
function toggleOn(options, timeout) {
// We have a single option, so it may be passed as a string or property
......@@ -812,6 +858,10 @@ angular.module('cesium.utils.services', [])
ink: ionicMaterialInk.displayEffect,
motion: raw.motion,
setEffects: setEffects,
qrcode: {
svg: getSvgQRCode,
img: getImgQRCode
},
fab: {
show: showFab,
hide: hideFab
......
......@@ -41,6 +41,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
resetData = function(init) {
data.loaded = false;
data.pubkey= null;
data.qrcode=null;
data.uid = null;
data.localName = null;
......@@ -158,8 +159,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
var keepAuth = csSettings.data.keepAuthIdle > 0;
var authData;
return (options && options.authData && $q.when(options.authData) ||
Modals.showLogin(options))
return (options && options.authData ? $q.when(options.authData) : Modals.showLogin(options))
.then(function(res){
if (!res || !res.pubkey ||
(!needLogin && res.pubkey !== data.pubkey) ||
......@@ -843,6 +843,15 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
});
},
loadQrCode = function(){
if (!data.pubkey || data.qrcode) return $q.when(data.qrcode);
console.debug("[wallet] Creating SVG QRCode...");
return $timeout(function() {
data.qrcode = UIUtils.qrcode.svg(data.pubkey);
return data.qrcode;
});
},
loadData = function(options) {
var alertIfUnusedWallet = !csCurrency.data.initPhase && (!csSettings.data.wallet || csSettings.data.wallet.alertIfUnusedWallet) &&
......@@ -865,8 +874,12 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
loadPromise = loadFullData();
}
return loadPromise
return $q.all([
loadPromise,
// Create the QR code
loadQrCode()
])
// Warn if wallet has been never used - see #167
.then(function() {
var unused = isNeverUsed();
......@@ -973,16 +986,16 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
},
refreshData = function(options) {
options = options || {
requirements: true,
sources: true,
tx: {
enable: true,
fromTime: data.tx && data.tx.fromTime !== 'pending' ? data.tx.fromTime : undefined // keep previous time
},
sigStock: true,
api: true
};
options = options || {
requirements: true,
sources: true,
tx: {
enable: true,
fromTime: data.tx && data.tx.fromTime !== 'pending' ? data.tx.fromTime : undefined // keep previous time
},
sigStock: true,
api: true
};
// Force some load (requirements) if not already loaded
options.requirements = angular.isDefined(options.requirements) ? options.requirements : !data.requirements.loaded;
......@@ -1024,7 +1037,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
if (options.sigStock) jobs.push(loadSigStock());
return (jobs.length ? $q.all(jobs) : $q.when())
.then(function(){
.then(function() {
// Skip api
if (angular.isDefined(options.api) && !options.api) return data;
......@@ -1041,6 +1054,11 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
return data;
});
})
.catch(function(err) {
console.error("[wallet] Error while {0} data: ".format(!data.loaded ? 'Loading' : 'Refreshing'), err);
data.loaded = data.requirements.loaded && data.sources && true;
throw err;
});
},
......@@ -2420,6 +2438,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
getData: getData,
loadData: loadData,
refreshData: refreshData,
loadQrCode: loadQrCode,
// internal
internal: {
addListener: addListener,
......
<a ng-attr-id="{{ qrcodeId }}" ng-show="!loading"
class="qrcode fade-in pull-right"
ng-class="{'active': toggleQRCode}"
ng-click="toggleQRCode = !toggleQRCode">
<div class="content"></div>
<div class="footer item item-icon-left item-text-wrap ink"
on-hold="copy(formData.pubkey)"
copy-on-click="{{:rebind:formData.pubkey}}"
ng-click="$event.stopPropagation()">
<i class="icon ion-key"></i>
<span>{{:locale:'COMMON.PUBKEY'|translate}}</span>
<h4 id="pubkey" class="dark">{{:rebind:formData.pubkey}}</h4>
</div>
</a>
......@@ -191,8 +191,8 @@
<ion-item class="item hidden-xs hidden-sm">
<!-- transfer -->
<button class="button button-block button-small button-small-padding button-stable icon-left icon ion-paper-airplane no-margin"
ng-class="{'button-positive': login}"
<button class="button button-block button-small button-small-padding icon-left icon ion-paper-airplane no-margin"
ng-class="{'button-positive': login, 'button-stable': !login}"
ng-click="showTransferModal()">
{{:locale:'COMMON.BTN_SEND_MONEY'|translate}}
</button>
......@@ -279,9 +279,6 @@
<i class="icon ion-log-out assertive"></i>
<span class="assertive" translate> {{:locale:'COMMON.BTN_LOGOUT'|translate}}</span>
</a>
<!-- <a ng-if="login" class="button-icon" ng-click="logout({askConfirm: true})" style="position: absolute; top: 5px; left: 5px; z-index: 999;">-->
<!-- <i class="icon light ion-log-out"></i>-->
<!-- </a>-->
</ion-list>
......
......@@ -22,8 +22,7 @@
</ion-refresher>
<div class="positive-900-bg hero"
style="max-width: 100%; display: block"
ng-class="{'hero-qrcode-active': toggleQRCode}">
style="max-width: 100%; display: block">
<div class="content" ng-if="!loading"
style="max-width: 100%">
......@@ -74,11 +73,7 @@
</div>
<a ng-attr-id="{{ qrcodeId }}"
class="qrcode spin pull-right"
ng-class="{'active': toggleQRCode}"
ng-click="toggleQRCode = !toggleQRCode">
</a>
<ng-include src="::'templates/common/qrcode.html'"></ng-include>
<!-- Buttons bar-->
<a id="wallet-share-anchor"></a>
......
......@@ -67,6 +67,9 @@
</h2>
</div>
<!-- QR code -->
<ng-include src="::'templates/common/qrcode.html'"></ng-include>
<!-- Buttons bar-->
<div class="hidden-xs hidden-sm padding text-center" ng-if="!loading">
......
......@@ -9,7 +9,7 @@
on-refresh="doUpdate(true)">
</ion-refresher>
<div class="hero" ng-class="{'hero-qrcode-active': toggleQRCode}">
<div class="hero">
<div class="content" ng-if="!loading">
<i class="avatar"
ng-if=":rebind:!formData.avatar"
......@@ -35,13 +35,11 @@
<ion-spinner icon="android"></ion-spinner>
</h4>
</div>
<div ng-attr-id="{{ qrcodeId }}"
class="qrcode spin"
ng-class="{'active': toggleQRCode}"
ng-click="toggleQRCode = !toggleQRCode"></div>
<!-- QR code -->
<ng-include src="::'templates/common/qrcode.html'"></ng-include>
<!-- button bar-->
<a id="wot-share-anchor-{{::formData.pubkey}}"></a>
......
......@@ -37,6 +37,7 @@
<ion-spinner icon="android"></ion-spinner>
</div>
<div class="list {{motion.ionListClass}}" ng-if="!loading">
<div class="row">
......
......@@ -192,9 +192,9 @@
version "1.5.6"
resolved "https://codeload.github.com/adamwdraper/Numeral-js/tar.gz/b598d6eeaf7981be55840d5fda5541e598eaf04f"
"@bower_components/qrcode.js@davidshimjs/qrcodejs#*":
"@bower_components/qrcode-generator@kazuhikoarase/qrcode-generator#js1.4.4":
version "0.0.0"
resolved "https://codeload.github.com/davidshimjs/qrcodejs/tar.gz/04f46c6a0708418cb7b96fc563eacae0fbf77674"
resolved "https://codeload.github.com/kazuhikoarase/qrcode-generator/tar.gz/9bd2163ddc1628d1ec8ff22ea288a747275ef442"
"@bower_components/robotodraft@raibutera/robotodraft#1.1.0":
version "0.0.0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment