diff --git a/bower.json b/bower.json index c77d917e7cb857c73a942b904fd3ce5464168497..ad399022e432c39118411164a455ebe1ed0f87bd 100644 --- a/bower.json +++ b/bower.json @@ -11,7 +11,8 @@ "angular-moment": "^0.10.3", "angular-animate": "1.4.3", "angular-sanitize": "1.5.3", - "angular": "1.5.3" + "angular": "1.5.3", + "js-scrypt": "1.2.0" }, "resolutions": { "angular-sanitize": "1.5.3", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 39533aa7cc12e1584924b8f4e6d6c4f2bca0cacc..e138a02279face8e5a815053f11c77d142513d44 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -161,8 +161,8 @@ "NOT_MEMBER_PARENTHESIS": "(not member)", "EXPIRE_IN": "Expires", "PSEUDO": "Pseudonym", - "SIGNED_ON_BLOCK": "Certify on block", - "WRITTEN_ON_BLOCK": "Written on block", + "SIGNED_ON_BLOCK": "Certify on block #{{block}}", + "WRITTEN_ON_BLOCK": "Written on block #{{block}}", "GENERAL_DIVIDER": "General data", "TECHNICAL_DIVIDER": "Technical data", "BTN_CERTIFY": "Certify", @@ -175,7 +175,7 @@ "NEWCOMERS": "New members:", "PENDING": "Pending registrations:", "REGISTERED": "Registered {{sigDate | formatFromNow}}", - "MEMBER_FROM": "Membre from {{memberDate|formatFromNowShort}} ago", + "MEMBER_FROM": "Member from {{memberDate|formatFromNowShort}} ago", "BTN_NEWCOMERS": "Last registrations", "BTN_PENDING": "Pending registrations", "SHOW_MORE": "Show more", @@ -189,6 +189,7 @@ "TITLE": "{{uid}} - Certifications", "SUMMARY": "Received certifications", "LIST": "Details of received certifications", + "PENDING_LIST": "Pending certifications", "RECEIVED": "Received certifications", "RECEIVED_BY": "Certifications received by {{uid}}" }, diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 6fd44ea43469d467cbf8cc3f2572131afe806f72..10520b5d6eebb1271a5f6f23e1c00f730c894264 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -161,8 +161,8 @@ "NOT_MEMBER_PARENTHESIS": "(non membre)", "EXPIRE_IN": "Expiration", "PSEUDO": "Pseudonyme", - "SIGNED_ON_BLOCK": "Certifié au bloc", - "WRITTEN_ON_BLOCK": "Ecrit au bloc", + "SIGNED_ON_BLOCK": "Certifié au bloc #{{block}}", + "WRITTEN_ON_BLOCK": "Ecrit au bloc #{{block}}", "GENERAL_DIVIDER": "Informations générales", "TECHNICAL_DIVIDER": "Informations techniques", "BTN_CERTIFY": "Certifier", @@ -189,6 +189,7 @@ "TITLE": "{{uid}} - Certifications", "SUMMARY": "Certifications reçues", "LIST": "Détail des certifications reçues", + "PENDING_LIST": "Certifications en attente de traitement", "RECEIVED": "Certifications reçues", "RECEIVED_BY": "Certifications reçues par {{uid}}" }, diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js index f4b19c1ab4792268b9e0974cf2a53bf6c6d9ae48..6ec64b209f04a1c0f959e2cc8a006621ffd7a618 100644 --- a/www/js/controllers/app-controllers.js +++ b/www/js/controllers/app-controllers.js @@ -71,8 +71,7 @@ function PluginExtensionPointController($scope, PluginService) { * Abstract controller (inherited by other controllers) */ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $timeout, $ionicHistory, $controller, - $ionicPopover, - screenmatch, UIUtils, BMA, Wallet, Device, Modals, csSettings, csConfig + UIUtils, BMA, Wallet, Device, Modals, csSettings, csConfig ) { 'ngInject'; @@ -84,9 +83,13 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $ $rootScope.login = Wallet.isLogin(); //////////////////////////////////////// - // Show currency view + // Show view //////////////////////////////////////// + $scope.showHome = function() { + $state.go('app.home'); + }; + $scope.showCurrencyView = function() { $state.go(UIUtils.screen.isSmall() ? 'app.currency_view': 'app.currency_view_lg'); }; diff --git a/www/js/controllers/help-controllers.js b/www/js/controllers/help-controllers.js index 8874353a572fdea8365552bbe8229c0b0f9bd2bd..e672919a14e77b9a7bc3a8ed131da3c809bc66cc 100644 --- a/www/js/controllers/help-controllers.js +++ b/www/js/controllers/help-controllers.js @@ -332,7 +332,8 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe bindings: { content: 'HELP.TIP.CURRENCY_RULES', icon: { - position: 'bottom-left' + position: 'center', + glyph: 'ion-information-circled' } } }); @@ -453,7 +454,9 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe icon: { position: 'center' } - } + }, + timeout: 700, + retry: 15 }); }, @@ -493,7 +496,8 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe content: 'HELP.TIP.WOT_VIEW_CERTIFICATIONS_CLICK', icon: { position: 'center' - } + }, + hasNext: hasNext } }); } @@ -616,7 +620,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe position: 'center' } }, - retry: 10 // 10 * 500 = 5s max + retry: 20 // 10 * 500 = 5s max }); }); }, @@ -677,6 +681,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe if (!Wallet.isLogin()) return $scope.emptyPromise(true); var contentParams; + var skipAll = false; var steps = [ @@ -684,7 +689,10 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe // If on wallet : click on certifications if ($state.is('app.view_wallet')) { var element = $window.document.getElementById('helptip-wallet-certifications'); - if (!element) return true; + if (!element) { + skipAll = true; + return true; + } $timeout(function() { angular.element(element).triggerHandler('click'); }); @@ -698,6 +706,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe }, function() { + if (skipAll) return true; if ($state.is('app.wallet_view_cert')) { // Select the second tabs $timeout(function() { @@ -721,7 +730,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe function() { - if ($scope.tour) return true; // skip Rules if features tour (already display) + if ($scope.tour || skipAll) return hasNext; // skip Rules if features tour (already display) return $scope.showHelpTip('helptip-certs-stock', { bindings: { content: 'HELP.TIP.CERTIFY_RULES', @@ -762,13 +771,19 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe $scope.startHeaderTour = function(startIndex, hasNext) { if (UIUtils.screen.isSmall()) return $scope.emptyPromise(true); + function _getProfilBtnElement() { + var elements = $window.document.querySelectorAll('#helptip-header-bar-btn-profile'); + if (!elements || !elements.length) return null; + return _.find(elements, function(el) {return el.offsetWidth > 0;}); + } + var steps = [ function () { if (UIUtils.screen.isSmall()) return true; // skip for small screen - var elements = $window.document.querySelectorAll('#helptip-header-bar-btn-profile'); - if (!elements || !elements.length) return true; - return $scope.showHelpTip(elements[elements.length -1], { + var element = _getProfilBtnElement(); + if (!element) return true; + return $scope.showHelpTip(element, { bindings: { content: 'HELP.TIP.HEADER_BAR_BTN_PROFILE', icon: { @@ -795,9 +810,8 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe } // wide screens else { - var elements = $window.document.querySelectorAll('#helptip-header-bar-btn-profile'); - if (!elements || !elements.length) return true; - var element = elements[elements.length -1]; + var element = _getProfilBtnElement(); + if (!element) return true; $timeout(function() { angular.element(element).triggerHandler('click'); }); diff --git a/www/js/controllers/join-controllers.js b/www/js/controllers/join-controllers.js index 33480b4363e418a7f69560dd3efa014b5519dff7..ed5227d21733848c45018eebaeb7a74bae060dfd 100644 --- a/www/js/controllers/join-controllers.js +++ b/www/js/controllers/join-controllers.js @@ -56,6 +56,7 @@ function JoinModalController($scope, $state, $timeout, UIUtils, CryptoUtils, Mod }; $scope.showUsername = false; $scope.showPassword = false; + $scope.smallscreen = UIUtils.screen.isSmall(); csCurrency.load() .then(function (data) { @@ -77,7 +78,6 @@ function JoinModalController($scope, $state, $timeout, UIUtils, CryptoUtils, Mod $scope.slides.slider.unlockSwipes(); $scope.slides.slider.slideNext(); $scope.slides.slider.lockSwipes(); - console.log($scope.slides.slider.activeIndex); $scope.isLastSlide = $scope.formData.isMember ? ($scope.slides.slider.activeIndex === 5) : ($scope.slides.slider.activeIndex === 4); }; diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js index 7287b4cad190215d7687b01ef69b32ec3ae45bc4..ca73a2e1d97cd8aef2a554250c980789b3cfa839 100644 --- a/www/js/services/crypto-services.js +++ b/www/js/services/crypto-services.js @@ -5,12 +5,12 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services' .factory('CryptoUtils', function($q, $timeout, Device) { 'ngInject'; - var async_load_scrypt = function(on_ready) { + var async_load_scrypt = function(on_ready, options) { if (scrypt_module_factory !== null){ - return on_ready(scrypt_module_factory()); + on_ready(scrypt_module_factory(options.requested_total_memory)); } else { - return $timeout(function(){async_load_scrypt(on_ready);}, 100); + $timeout(function(){async_load_scrypt(on_ready, options);}, 100); } }, @@ -242,20 +242,22 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services' console.debug('Loading NaCl...'); var now = new Date().getTime(); var naclOptions = {}; + var scryptOptions = {}; if (ionic.Platform.grade.toLowerCase()!='a') { console.log('Reduce NaCl memory because plateform grade is not [a] but [' + ionic.Platform.grade + ']'); - naclOptions.requested_total_memory = 16777216; + naclOptions.requested_total_memory = 16 * 1048576; // 16 Mo + console.log('Reduce Scrypt memory because plateform grade is not [a] but [' + ionic.Platform.grade + ']'); + scryptOptions.requested_total_memory = 16 * 1048576; // 16 Mo } async_load_nacl(function(lib) { nacl = lib; loadedLib++; console.debug('Loaded NaCl in ' + (new Date().getTime() - now) + 'ms'); }, naclOptions); - async_load_scrypt(function(lib) { scrypt = lib; loadedLib++; - }); + }, scryptOptions); async_load_base58(function(lib) { base58 = lib; loadedLib++; @@ -268,12 +270,6 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services' // Service's exposed methods return { - /* - TODO: uncomment if need to expose - nacl: nacl, - scrypt: scrypt, - base58: base58, - base64: base64,*/ isLoaded: isLoaded, util: { encode_utf8: encode_utf8, @@ -295,7 +291,6 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services' pack: box, open: box_open } - //,isCompatible: isCompatible }; } diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js index 0ea2ddc78033bc498a8daa32eccae9760998f13d..9e5dd6bf58fbef44a7d39360117e45755dcddc3a 100644 --- a/www/js/services/utils-services.js +++ b/www/js/services/utils-services.js @@ -461,6 +461,7 @@ angular.module('cesium.utils.services', ['ngResource']) // Do timeout if ask if (options.timeout) { var timeout = options.timeout; + options.retryTimeout = options.retryTimeout || timeout; delete options.timeout; options.deferred = deferred; $timeout(function () { @@ -469,7 +470,7 @@ angular.module('cesium.utils.services', ['ngResource']) } // No element: reject - else if (!angular.isUndefined(options.retry) && !options.retry) { + else if (angular.isDefined(options.retry) && !options.retry) { if (options.onError === 'continue') { $timeout(function () { @@ -489,7 +490,7 @@ angular.module('cesium.utils.services', ['ngResource']) options.deferred = deferred; $timeout(function() { showHelptip(id, options); - }, options.timeout || 100); + }, options.timeout || options.retryTimeout || 100); } } diff --git a/www/js/services/wot-services.js b/www/js/services/wot-services.js index d7ac8d16975a25c7d3d31abd08f439e75f0d2c6b..278b86fcd6fa9c63f0fafffe70bae3521bdf44db 100644 --- a/www/js/services/wot-services.js +++ b/www/js/services/wot-services.js @@ -89,7 +89,7 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic return $q(function(resolve, reject) { BMA.wot.lookup({ search: pubkey }) .then(function(res){ - var identity = res.results.reduce(function(idties, res) { + var identities = res.results.reduce(function(idties, res) { return idties.concat(res.uids.reduce(function(uids, idty) { var blockUid = idty.meta.timestamp.split('-', 2); return uids.concat({ @@ -103,7 +103,12 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic sig: idty.self }); }, [])); - }, [])[0]; // TODO : check if a sort before is not better ? + }, []); + // Choose the more updated identity + var identity = identities.length == 1 ? + identities[0] : + _.sortBy(identities, 'number')[identities.length-1]; + identity.hasSelf = !!(identity.uid && identity.timestamp && identity.sig); // Retrieve certifications @@ -112,6 +117,7 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic return map; }, {}); var certPubkeys = []; + identity.hasPendingCertifications = false; var certifications = !res.results ? [] : res.results.reduce(function(certs, res) { return certs.concat(res.uids.reduce(function(certs, idty) { return certs.concat(idty.others.reduce(function(certs, cert) { @@ -122,9 +128,12 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic block: (cert.meta && cert.meta.block_number) ? cert.meta.block_number : 0, expiresIn: expiresIn, willExpire: (expiresIn && expiresIn <= csSettings.data.timeWarningExpire), - valid: (expiresIn && expiresIn > 0), + pending: !expiresIn, isMember: cert.isMember }; + if (result.pending && !identity.hasPendingCertifications) { + identity.hasPendingCertifications = true; + } if (!certPubkeys[cert.pubkey]) { certPubkeys[cert.pubkey] = result; } @@ -133,10 +142,10 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic certPubkeys[cert.pubkey] = result; } else { - result = null; // skip + return certs; // skip this result } } - return result !== null ? certs.concat(result) : certs; + return certs.concat(result); }, certs)); }, certs)); }, []); diff --git a/www/plugins/es/js/services/user-services.js b/www/plugins/es/js/services/user-services.js index 1023dd85eb2b605e0fa11ffe4b3c545425b59235..7d44d48194e3c1a60b70f558c90750566ab80084 100644 --- a/www/plugins/es/js/services/user-services.js +++ b/www/plugins/es/js/services/user-services.js @@ -276,7 +276,6 @@ angular.module('cesium.es.user.services', ['cesium.services', 'cesium.es.http.se restoringSettings = true; csSettings.store(); console.debug('[esUser] Successfully loaded user settings from ES node'); - console.debug(settings); resolve(data); }); }) diff --git a/www/templates/menu.html b/www/templates/menu.html index 4779ec608d3889e56c5fa081bb91cfabc5fe5285..8b0c6c4b4d6fbac764ae5a517cc29ac7cffae5f4 100644 --- a/www/templates/menu.html +++ b/www/templates/menu.html @@ -38,8 +38,8 @@ expose-aside-when="large" enable-menu-with-back-views="false" width="225"> - <ion-header-bar class="bar bar-header"> - <h1 class="title royal" translate> + <ion-header-bar class="bar bar-header" ng-click="showHome()" menu-close> + <h1 class="title dark" translate> MENU.TITLE </h1> </ion-header-bar> @@ -47,7 +47,7 @@ <ion-list class="list"> <!-- DISCOVER Section --> - <ion-item menu-close class="item-icon-left" href="#/app/home" active-link="active"> + <ion-item menu-close class="item-icon-left hidden-xs" href="#/app/home" active-link="active"> <i class="icon ion-home"></i> <span translate>MENU.HOME</span> </ion-item> diff --git a/www/templates/wot/tabs/view_certifications.html b/www/templates/wot/tabs/view_certifications.html index c1370102670b5a82369c84030081b4c4a6466002..e1fd7a38c3530873d536095d24a0e21596e6d895 100644 --- a/www/templates/wot/tabs/view_certifications.html +++ b/www/templates/wot/tabs/view_certifications.html @@ -11,6 +11,42 @@ <span class="badge" ng-class="{'badge-balanced': formData.certificationCount >= formData.sigQty, 'badge-assertive': formData.certificationCount < formData.sigQty}">{{formData.certificationCount}}</span> </div> + <span class="item item-divider" ng-if="formData.hasPendingCertifications"> + <span translate>WOT.CERTIFICATIONS.PENDING_LIST</span> + </span> + + <a class="item ink" + ng-if="formData.hasPendingCertifications" + ng-repeat="cert in formData.certifications | filter: {pending: true}" + ui-sref="app.wot_view_identity({pubkey:cert.pubkey, uid:cert.uid})"> + <span ng-if="cert.isMember"> + <h3> + <i class="icon ion-clock"> </i> + <span class="positive"> + <i class="ion-person"> </i> + {{::cert.uid}} + </span> + </h3> + <h4 class="gray"> + <i class="ion-key"></i> + {{::cert.pubkey | formatPubkey}} + <span class="gray"> | {{::'WOT.SIGNED_ON_BLOCK' | translate:cert}}</span> + </h4> + </span> + <span ng-if="!cert.isMember"> + <h3 class="gray"> + <i class="icon ion-clock"> </i> + <span ng-if="cert.uid"> + <i class="ion-person"> </i> + {{::cert.uid}} + </span> + </h3> + <h5 class="assertive">{{'WOT.NOT_MEMBER_PARENTHESIS'|translate}}</h5> + <h4 class="gray"><i class="ion-key"></i> + {{::cert.pubkey | formatPubkey}} | {{'WOT.SIGNED_ON_BLOCK' | translate}} #{{::cert.block}}</h4> + </span> + </a> + <span class="item item-divider"> <span translate>WOT.CERTIFICATIONS.LIST</span> <div class="badge item-note" translate>WOT.EXPIRE_IN</div> @@ -21,11 +57,10 @@ </span> <a class="item ink" - ng-repeat="cert in formData.certifications" + ng-repeat="cert in formData.certifications | filter: {pending: false}" ui-sref="app.wot_view_identity({pubkey:cert.pubkey, uid:cert.uid})"> <span ng-if="cert.isMember"> <h3> - <i ng-if="!cert.valid" class="icon ion-clock"> </i> <span class="positive"> <i class="ion-person"> </i> {{::cert.uid}} @@ -34,8 +69,7 @@ <h4 class="gray"> <i class="ion-key"></i> {{::cert.pubkey | formatPubkey}} - <span class="gray" ng-if="cert.valid"> | {{'WOT.WRITTEN_ON_BLOCK' | translate}} #{{::cert.block}}</span> - <span class="gray" ng-if="!cert.valid"> | {{'WOT.SIGNED_ON_BLOCK' | translate}} #{{::cert.block}}</span> + <span class="gray"> | {{::'WOT.WRITTEN_ON_BLOCK' | translate:cert}}</span> </h4> </span> <span ng-if="!cert.isMember"> @@ -51,7 +85,6 @@ <h4 ng-if="!cert.isMember" class="gray">{{'WOT.SIGNED_ON_BLOCK' | translate}} #{{::cert.block}}</h4> </span> <div class="badge item-note" - ng-if="cert.valid" ng-class="{'badge-balanced': !cert.willExpire, 'badge-energized': cert.willExpire}"> {{::cert.expiresIn | formatDuration}} </div>