diff --git a/release.sh b/release.sh index d59745356ecfc9aefa37debf189ba705ef888992..4524609cf798ccfb971caa25514c4f1261985d7e 100755 --- a/release.sh +++ b/release.sh @@ -90,6 +90,9 @@ if [[ $2 =~ ^[0-9]+.[0-9]+.[0-9]+((a|b)[0-9]+)?$ && $3 =~ ^[0-9]+$ ]]; then echo "- Building desktop versions..." echo "----------------------------------" + # Remove old vagrant virtual machines + rm -rf ~/.vagrant.d/* + git submodule update --init git submodule sync cd platforms/desktop diff --git a/scss/ionic.app.scss b/scss/ionic.app.scss index e58699ee122e25595e518317da09be0a7c78fc75..44051ac7d5cfdced4d3edaff1170da2f4fe0288b 100644 --- a/scss/ionic.app.scss +++ b/scss/ionic.app.scss @@ -1306,6 +1306,7 @@ a.underline:hover, } } + /********** Form validation **********/ diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index 4dd8db337f7d8f38e23b0c5d997b371647c6e581..c19c8e56888a31983c339ffc60b3ee308e7ed2fc 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -617,6 +617,7 @@ "IDENTITY_EXPIRED": "This identity has expired: this person must re-apply <b>before</b> being certified.", "IDENTITY_SANDBOX_FULL": "Could not register, because peer's sandbox is full.<br/><br/>Please retry later or choose another Duniter peer (in <b>Settings</b>).", "IDENTITY_NOT_FOUND": "Identity not found", + "IDENTITY_TX_FAILED": "Error while getting identity's transactions", "WOT_PENDING_INVALID_BLOCK_HASH": "Membership not valid.", "WALLET_INVALID_BLOCK_HASH": "Your membership application is no longer valid (because it references a block that network peers are cancelled).<br/>You must <a ng-click=\"doQuickFix('renew')\">renew your application for membership</a> to fix this issue.", "WALLET_IDENTITY_EXPIRED": "The publication of your identity <b>has expired</b>.<br/>You must <a ng-click=\"doQuickFix('fixIdentity')\">re-issue your identity</a> to resolve this issue.", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 6e4347d65240e0dc8f17727fdf318eb595ef41ea..6c77fc94eec1dd60b560a97e95bf48be923e6368 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -617,6 +617,7 @@ "IDENTITY_EXPIRED": "This identity has expired: this person must re-apply <b>before</b> being certified.", "IDENTITY_SANDBOX_FULL": "Could not register, because peer's sandbox is full.<br/><br/>Please retry later or choose another Duniter peer (in <b>Settings</b>).", "IDENTITY_NOT_FOUND": "Identity not found", + "IDENTITY_TX_FAILED": "Error while getting identity's transactions", "WOT_PENDING_INVALID_BLOCK_HASH": "Membership not valid.", "WALLET_INVALID_BLOCK_HASH": "Your membership application is no longer valid (because it references a block that network peers are cancelled).<br/>You must <a ng-click=\"doQuickFix('renew')\">renew your application for membership</a> to fix this issue.", "WALLET_IDENTITY_EXPIRED": "The publication of your identity <b>has expired</b>.<br/>You must <a ng-click=\"doQuickFix('fixIdentity')\">re-issue your identity</a> to resolve this issue.", diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json index 6741c10dea408981f2ee485904015a07e54dba6e..27485257c6c379eed81be5f954c43de30360d397 100644 --- a/www/i18n/locale-es-ES.json +++ b/www/i18n/locale-es-ES.json @@ -565,11 +565,17 @@ "IDENTITY_EXPIRED": "La publicación de esta identidad ha caducada : esta persona debe realizar una nueva solicitud de adhesión <b>antes que</b> estar certificada.", "IDENTITY_SANDBOX_FULL": "EL nodo Duniter utilizado por Cesium ya no puede recibir más nuevas identidades, porque la fila de espera es llena.<br/><br/>Por favor, intenta ulteriormente o cambia de nodo (vÃa el menú <b>Paramètres</b>).", "IDENTITY_NOT_FOUND": "Identidad no encontrada", + "IDENTITY_TX_FAILED": "Las operaciones de carga fallidos", "WOT_PENDING_INVALID_BLOCK_HASH": "Adhesión no validada.", "WALLET_INVALID_BLOCK_HASH": "Su solicitud de adhesión ya no está validada (porque denomina un bloque los nodos de la red han anulado).<br/>Debe <a ng-click=\"doQuickFix('fixMembership')\">mandar una nueva solicitud</a> para resolver este problema.", "WALLET_IDENTITY_EXPIRED": "La publicación de <b>su identidad ha caducada</b>.<br/>Debe <a ng-click=\"doQuickFix('fixIdentity')\">publicar une outra vez su identidad</a> para resolver este problema.", "WALLET_REVOKED": "Su identidad fue <b>revocada</b> : ni su seudónimo ni su llave pública podrán estar utilizados en el futuro por una cuenta miembro.", "WALLET_HAS_NO_SELF": "Su identidad debe en primer lugar haber estado publicado, y no estar caducada.", + "AUTH_REQUIRED": "Autenticación requerida.", + "AUTH_INVALID_PUBKEY": "La llave pública no se corresponde con la cuenta conectada", + "AUTH_INVALID_SCRYPT": "De usuario o contraseña no válidos.", + "AUTH_INVALID_FILE": "archivo de llave no válido.", + "AUTH_FILE_ERROR": "No se pudo abrir el archivo de llave", "IDENTITY_ALREADY_CERTIFY": "Ha <b>ya certificado</b> esta identidad.<br/><br/>Esta certificación todavÃa es valida (expiration {{expiresIn|formatDurationTo}}).", "IDENTITY_ALREADY_CERTIFY_PENDING": "Ha <b>ya certificado</b> esta identidad.<br/><br/>Esta certificación está en espera de tratamiento (fecha lÃmite de tratamiento {{expiresIn|formatDurationTo}}).", "UNABLE_TO_CERTIFY_TITLE": "Certificación imposible", diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 41a2581102333f769de6b18d4db69589a2ef6060..142bc212fa329a76c28f16465dc61266df08eff2 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -437,7 +437,7 @@ "EVENTS": "Evénements", "WAITING_MEMBERSHIP": "Demande d'adhésion envoyée. En attente d'acceptation.", "WAITING_CERTIFICATIONS": "Vous devez obtenir {{needCertificationCount}} certification(s) pour devenir membre.", - "WILL_MISSING_CERTIFICATIONS": "Vous allez bientôt <b>manquer de certification</b> (au moins {{willNeedCertificationCount}} est nécessaire)", + "WILL_MISSING_CERTIFICATIONS": "Vous allez bientôt <b>manquer de certification</b> (au moins {{willNeedCertificationCount}} sont requises)", "WILL_NEED_RENEW_MEMBERSHIP": "Votre adhésion comme membre <b>va expirer {{membershipExpiresIn|formatDurationTo}}</b>. Pensez à <a ng-click=\"doQuickFix('renew')\">renouveler votre adhésion</a> d'ici là .", "NEED_RENEW_MEMBERSHIP": "Vous n'êtes plus membre, car votre adhésion <b>a expiré</b>. Pensez à <a ng-click=\"doQuickFix('renew')\">renouveler votre adhésion</a>.", "CERTIFICATION_COUNT": "Certifications reçues", @@ -617,6 +617,7 @@ "IDENTITY_EXPIRED": "La publication de cette identité a expirée : cette personne doit effectuer une nouvelle demande d'adhésion <b>avant</b> d'être certifiée.", "IDENTITY_SANDBOX_FULL": "Le nÅ“ud Duniter utilisé par Cesium ne peut plus recevoir de nouvelles identités, car sa file d'attente est pleine.<br/><br/>Veuillez réessayer ultérieurement ou changer de nÅ“ud (via le menu <b>Paramètres</b>).", "IDENTITY_NOT_FOUND": "Identité non trouvée", + "IDENTITY_TX_FAILED": "Echec du chargement des opérations", "WOT_PENDING_INVALID_BLOCK_HASH": "Adhésion non valide.", "WALLET_INVALID_BLOCK_HASH": "Votre demande d'adhésion n'est plus valide (car elle référence un bloc que les nÅ“uds du réseau ont annulé).<br/>Vous devez <a ng-click=\"doQuickFix('fixMembership')\">envoyer une nouvelle demande</a> pour résoudre ce problème.", "WALLET_IDENTITY_EXPIRED": "La publication de <b>votre identité a expirée</b>.<br/>Vous devez <a ng-click=\"doQuickFix('fixIdentity')\">publier à nouveau votre identité</a> pour résoudre ce problème.", diff --git a/www/js/app.js b/www/js/app.js index 8c280a5eba4d26b47b923f43e114763ef55211d3..6b52789d4e34b48fb4c896995d8fd3f6929ea8af 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -258,7 +258,7 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht // Ionic Platform Grade is not A, disabling views transitions if (ionic.Platform.grade.toLowerCase() != 'a') { - console.log('[app] Disabling UI effects, because plateform\'s grade is [' + ionic.Platform.grade + ']'); + console.info('[app] Disabling UI effects, because plateform\'s grade is [' + ionic.Platform.grade + ']'); UIUtils.setEffects(false); } diff --git a/www/js/components.js b/www/js/components.js index b280578518bbf75c1ffc0fe310989936d13d6eea..34ba027d79a9ba0411352e67e436d18094f133d7 100644 --- a/www/js/components.js +++ b/www/js/components.js @@ -1,15 +1,5 @@ angular.module('cesium') - .component('csAvatar', { - bindings: { - avatar: '<', - icon: '@' - }, - template: - '<i ng-if="!$ctrl.avatar" class="item-image icon {{$ctrl.icon}}"></i>' + - '<i ng-if="$ctrl.avatar" class="item-image avatar" style="background-image: url({{::$ctrl.avatar.src}})"></i>' - }) - .component('csBadgeCertification', { bindings: { requirements: '=', @@ -35,25 +25,8 @@ angular.module('cesium') toggle: '<' }, template: - '<i class="ion-chevron-up" ng-class="{gray: !$ctrl.asc || $ctrl.sort != $ctrl.toggle}" style="position: relative;left : 5px; top:-5px; font-size: 9px;"></i>' + + '<i class="ion-chevron-up" ng-class="{gray: !$ctrl.asc || $ctrl.sort != $ctrl.toggle}" style="position: relative; left: 5px; top:-5px; font-size: 9px;"></i>' + '<i class="ion-chevron-down" ng-class="{gray : $ctrl.asc || $ctrl.sort != $ctrl.toggle}" style="position: relative; left: -2.6px; top: 3px; font-size: 9px;"></i>' }) - .component('csRemovableSelectionItem', { - transclude: true, - controller: function(){ - this.$onInit = function(){ - console.log("$onInit called: ", this); - }; - this.remove = function(){ - console.log("remove called: ", this); - }; - }, - template: - '<div >' + - ' <ng-transclude></ng-transclude>' + - ' <i class="icon ion-close" ng-click="$ctrl.remove();"></i>' + - '</div>' - }) - ; diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js index 8604bd2c042a0fe2dd2e14709b4db8799eb1f8b7..bd968685f443b9fb994608ec3677cb608916f3a2 100644 --- a/www/js/controllers/app-controllers.js +++ b/www/js/controllers/app-controllers.js @@ -85,7 +85,7 @@ function PluginExtensionPointController($scope, PluginService) { */ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $timeout, $ionicHistory, $controller, $window, csPlatform, - UIUtils, BMA, csWallet, csCurrency, Device, Modals, csSettings, csConfig + UIUtils, BMA, csWallet, Device, Modals, csConfig ) { 'ngInject'; diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js index e1426513e8f9952b54c8d06d678cefde01a14fba..7e56d8f91c86513dbc06e12ecb59dc8d418b6a1a 100644 --- a/www/js/controllers/settings-controllers.js +++ b/www/js/controllers/settings-controllers.js @@ -113,7 +113,6 @@ function SettingsController($scope, $q, $ionicHistory, $ionicPopup, $timeout, $t $scope.changeNode= function(node) { $scope.showNodePopup(node || $scope.formData.node) .then(function(newNode) { - console.log(newNode); if (newNode.host === $scope.formData.node.host && newNode.port === $scope.formData.node.port && newNode.useSsl === $scope.formData.node.useSsl) { diff --git a/www/js/controllers/wallet-controllers.js b/www/js/controllers/wallet-controllers.js index a2c6b03ef18a07844c2869b5dde45b3618461dd2..ecc2d47e5070d977f84d702835ba1c55c2406dc6 100644 --- a/www/js/controllers/wallet-controllers.js +++ b/www/js/controllers/wallet-controllers.js @@ -521,22 +521,23 @@ function WalletController($scope, $rootScope, $q, $ionicPopup, $timeout, $state, } -function WalletTxController($scope, $filter, $ionicPopover, $state, $timeout, UIUtils, csWallet, - Modals, csSettings, BMA,csTx) { +function WalletTxController($scope, $ionicPopover, $state, $timeout, + UIUtils, Modals, BMA, csSettings, csWallet, csTx) { 'ngInject'; $scope.loading = true; $scope.settings = csSettings.data; $scope.$on('$ionicView.enter', function(e, state) { - if (!$scope.loading && (!state.stateParams || state.stateParams.refresh != 'true')) { + if (!$scope.loading && (!state.stateParams || !state.stateParams.refresh)) { // Make sure to display new pending (e.g. sending using another screen button) - $scope.updateView(); + $timeout($scope.updateView, 300); return; // skip loading } + $scope.loadWallet() - .then(function(walletData) { - $scope.formData = walletData; + .then(function(res) { + $scope.formData = res; $scope.loading=false; // very important, to avoid TX to be display before wallet.currentUd is loaded $scope.updateView(); $scope.showFab('fab-transfer'); @@ -550,30 +551,14 @@ function WalletTxController($scope, $filter, $ionicPopover, $state, $timeout, UI }); }); - $scope.updateUnit = function() { - if (!$scope.formData || $scope.loading) return; - $scope.unit = $filter('currencySymbol')($scope.formData.currency, csSettings.data.useRelative); - $scope.secondaryUnit = $filter('currencySymbol')($scope.formData.currency, !csSettings.data.useRelative); - }; - - $scope.onSettingsChanged = function() { - $scope.updateUnit(); - }; - $scope.$watch('settings.useRelative', $scope.onSettingsChanged); - - // Reload if show UD changed - $scope.$watch('settings.showUDHistory', function() { - if (!$scope.formData || $scope.loading) return; - $scope.doUpdate(); - }, true); // Update view $scope.updateView = function() { + if (!$scope.formData || $scope.loading) return; $scope.$broadcast('$$rebind::' + 'balance'); // force rebind balance - $scope.updateUnit(); - $scope.motion.show({ink: false}); + $scope.$broadcast('$$rebind::' + 'rebind'); // force rebind + $scope.motion.show({selector: '.view-wallet-tx .item', ink: false}); }; - csWallet.api.data.on.balanceChanged($scope, $scope.updateView); $scope.downloadHistoryFile = function(options) { options = options || {}; @@ -592,6 +577,16 @@ function WalletTxController($scope, $filter, $ionicPopover, $state, $timeout, UI .catch(UIUtils.onError('ERROR.REFRESH_WALLET_DATA')); }; + /* -- add listeners -- */ + + csWallet.api.data.on.balanceChanged($scope, $scope.updateView); + $scope.$watch('settings.useRelative', $scope.updateView); + $scope.$watch('settings.showUDHistory', function() { + // Reload if show UD changed + if (!$scope.formData || $scope.loading) return; + $scope.doUpdate(); + }, true); + /* -- popup / UI -- */ // Transfer @@ -624,7 +619,7 @@ function WalletTxController($scope, $filter, $ionicPopover, $state, $timeout, UI // If http rest limitation: wait then retry if (err.ucode == BMA.errorCodes.HTTP_LIMITATION) { $timeout(function() { - return $scope.showMoreTx(); + return $scope.showMoreTx(fromTime); }, 2000); } else { @@ -735,11 +730,9 @@ function WalletTxErrorController($scope, UIUtils, csWallet) { $scope.doUpdate = function() { UIUtils.loading.show(); csWallet.refreshData() - .then(function() { - $scope.updateView(); - UIUtils.loading.hide(); - }) - .catch(UIUtils.onError('ERROR.REFRESH_WALLET_DATA')); + .then(UIUtils.loading.hide) + .then($scope.doMotion) + .catch(UIUtils.onError('ERROR.REFRESH_WALLET_DATA')); }; $scope.filterReceivedTx = function(tx){ @@ -978,7 +971,6 @@ function WalletSecurityModalController($scope, UIUtils, csWallet, $translate, Cr }) .then(function(res) { if (!res) return; - console.log(res); var file = { file: _.filter($scope.formData.questions, function (question) { return question.checked; diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js index 172181ff9881294b365d1f40a021837c75f53ee2..167cba3b8eeb03630e91937e6f88851e1f4e1271 100644 --- a/www/js/controllers/wot-controllers.js +++ b/www/js/controllers/wot-controllers.js @@ -606,7 +606,6 @@ function WotIdentityAbstractController($scope, $rootScope, $state, $translate, $ // Need user auth - fix #513 return csWallet.auth({minData: true}) .then(function(walletData) { - console.log(walletData); UIUtils.loading.hide(); if (!csCurrency.data.initPhase && !walletData.isMember) { @@ -951,36 +950,56 @@ function WotIdentityViewController($scope, $rootScope, $controller, $timeout, UI /** * Identity tx view controller */ -function WotIdentityTxViewController($scope, $timeout, csSettings, $controller, csTx, csWallet, BMA, UIUtils) { +function WotIdentityTxViewController($scope, $timeout, $q, BMA, csSettings, csCurrency, csWot, csTx, UIUtils) { 'ngInject'; - // Initialize the super class and extend it. - angular.extend(this, $controller('WotIdentityAbstractCtrl', {$scope: $scope})); - $scope.formData= {}; $scope.loading = true; $scope.motion = UIUtils.motion.fadeSlideInRight; $scope.$on('$ionicView.enter', function(e, state) { + if ($scope.loading) { + $scope.pubkey = state.stateParams.pubkey; + $scope.uid = state.stateParams.uid; + $scope.load(); + } + else { + // update view + $scope.updateView(); + } + }); - $scope.pubkey= state.stateParams.pubkey; - $scope.uid= state.stateParams.uid; - - // Load account TX data - csTx.load($scope.pubkey) - .then(function(result) { - if (result && result.tx && result.tx.history) { - $scope.tx = result.tx; - $scope.history = result.tx.history; - } - $scope.balance = result.balance; - $scope.load($scope.pubkey, true, $scope.uid) - .then(function(){ - $scope.motion.show(); - $scope.loading = false; - }); + // Load data + $scope.load = function(fromTime) { + return $q.all([ + csCurrency.get(), + csWot.extend({pubkey: $scope.pubkey}), + csTx.load($scope.pubkey, fromTime) + ]) + .then(function(res) { + $scope.currency = res[0]; + $scope.formData = angular.merge(res[1], res[2]); + $scope.loading = false; + $scope.updateView(); }); - }); + }; + + // Updating data + $scope.doUpdate = function() { + console.debug('[wot] TX history reloading...'); + return UIUtils.loading.show() + .then($scope.load) + .then(UIUtils.loading.hide) + .then($scope.updateView) + .catch(UIUtils.onError('ERROR.IDENTITY_TX_FAILED')); + }; + + // Update view + $scope.updateView = function() { + $scope.$broadcast('$$rebind::' + 'balance'); // force rebind balance + $scope.$broadcast('$$rebind::' + 'rebind'); // force rebind + $scope.motion.show(); + }; $scope.downloadHistoryFile = function(options) { options = options || {}; @@ -988,7 +1007,31 @@ function WotIdentityTxViewController($scope, $timeout, csSettings, $controller, csTx.downloadHistoryFile($scope.pubkey, options); }; - //TODO : Manque l'actualisation des transactions + afficher plus/tout + bouton statistiques du compte + $scope.showMoreTx = function(fromTime) { + + fromTime = fromTime || + ($scope.formData.tx.fromTime - csSettings.data.walletHistoryTimeSecond) || + (Math.trunc(new Date().getTime() / 1000) - 2 * csSettings.data.walletHistoryTimeSecond); + + UIUtils.loading.show(); + return csTx.load($scope.pubkey, fromTime) + .then(function(res) { + angular.merge($scope.formData, res); + $scope.updateView(); + UIUtils.loading.hide(); + }) + .catch(function(err) { + // If http rest limitation: wait then retry + if (err.ucode == BMA.errorCodes.HTTP_LIMITATION) { + $timeout(function() { + return $scope.showMoreTx(fromTime); + }, 2000); + } + else { + UIUtils.onError('ERROR.IDENTITY_TX_FAILED')(err); + } + }); + }; } diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js index fb722339d2a3ba271626931c92639859b54a30b8..a04ffc2820d74017e414ba7678e55dc59963cab5 100644 --- a/www/js/services/bma-services.js +++ b/www/js/services/bma-services.js @@ -43,6 +43,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. MEMBERSHIP_ALREADY_SEND: 2007, NO_CURRENT_BLOCK: 2010, BLOCK_NOT_FOUND: 2011, + SOURCE_ALREADY_CONSUMED: 2015, TX_INPUTS_OUTPUTS_NOT_EQUAL: 2024, TX_OUTPUT_SUM_NOT_EQUALS_PREV_DELTAS: 2025, TX_ALREADY_PROCESSED: 2030 @@ -684,8 +685,6 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. if (exact(regexp.PUBKEY).test(uri)) { resolve({ pubkey: uri - - }); } else if(uri.startsWith('duniter://')) { @@ -733,7 +732,6 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. }); }) .catch(function(err) { - console.log(err); reject({message: 'Could not get node parameter. Currency could not be retrieve'}); }); } diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js index c2f5a41a35535ac83f504ee073ba2b99e74d22f5..19833ed012bb07ccd93dd8ab59fbad40a8c2cf8f 100644 --- a/www/js/services/crypto-services.js +++ b/www/js/services/crypto-services.js @@ -444,10 +444,8 @@ angular.module('cesium.crypto.services', ['cesium.utils.services']) 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 + ']'); + console.info('Reduce NaCl memory because plateform grade is not [a] but [' + ionic.Platform.grade + ']'); 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 } var loadedLib = 0; var checkAllLibLoaded = function() { diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js index f4ea519633a63ca3dbabd584823117cf9b21100e..da81f75ecf0faa214f1518ad5c095d6515656bfa 100644 --- a/www/js/services/device-services.js +++ b/www/js/services/device-services.js @@ -123,7 +123,7 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti exports.camera = { getPicture : getPicture, scan: function(n){ - console.log('Deprecated use of Device.camera.scan(). Use Device.barcode.scan() instead'); + console.warn('Deprecated use of Device.camera.scan(). Use Device.barcode.scan() instead'); return scan(n); } }; diff --git a/www/js/services/tx-services.js b/www/js/services/tx-services.js index cd0a11be43437a298a867830b2bb58a480b0a737..59ccff35a677dd615b0e9641386e47e260ffc807 100644 --- a/www/js/services/tx-services.js +++ b/www/js/services/tx-services.js @@ -122,7 +122,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', }); }, - loadTx = function(pubkey, fromTime, existingPendings) { + loadTx = function(pubkey, fromTime) { return $q(function(resolve, reject) { var txHistory = []; var udHistory = []; @@ -138,7 +138,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', var _reduceTx = function(res){ _reduceTxAndPush(pubkey, res.history.sent, txHistory, processedTxMap); _reduceTxAndPush(pubkey, res.history.received, txHistory, processedTxMap); - _reduceTxAndPush(pubkey, res.history.sending, txHistory, processedTxMap); + _reduceTxAndPush(pubkey, res.history.sending, txPendings, processedTxMap, true /*allow pendings*/); _reduceTxAndPush(pubkey, res.history.pending, txPendings, processedTxMap, true /*allow pendings*/); }; diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index aefe3318c00b700f30a3ed065d6816d42a3a88dc..37c171b21729b98b5b455b09895a30932c6c9d72 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -21,7 +21,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se IDTY_VERSION: csConfig.compatProtocol_0_80 ? 2 : BMA.constants.PROTOCOL_VERSION, MS_VERSION: csConfig.compatProtocol_0_80 ? 2 : BMA.constants.PROTOCOL_VERSION, CERT_VERSION: csConfig.compatProtocol_0_80 ? 2 : BMA.constants.PROTOCOL_VERSION, - REVOKE_VERSION: csConfig.compatProtocol_0_80 ? 2 : BMA.constants.PROTOCOL_VERSION + REVOKE_VERSION: csConfig.compatProtocol_0_80 ? 2 : BMA.constants.PROTOCOL_VERSION, + TX_MAX_INPUTS_COUNT: 40 // Allow to get a TX with less than 100 rows (=max row count in Duniter protocol) }, data = {}, listeners, @@ -524,6 +525,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se loadTxAndSources = function(fromTime) { return csTx.load(data.pubkey, fromTime) .then(function(res){ + resetTxAndSources(); angular.merge(data, res); }) .catch(function(err) { @@ -936,8 +938,19 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se }); }) .catch(function(err) { - if (err && err.ucode === BMA.errorCodes.TX_INPUTS_OUTPUTS_NOT_EQUAL) { - // Send log message for debugging - issue #524 - https://github.com/duniter/cesium/issues/524 + + // Source already consumed: whould refresh wallet sources + if (err && err.ucode === BMA.errorCodes.SOURCE_ALREADY_CONSUMED) { + console.debug('[wallet] TX rejected by node with error [{0}]. Reloading sources then retry...'.format(err.message||'Source already consumed')); + return $timeout(loadTxAndSources, 500) + .then(function() { + return transfer(destPub, amount, comments, useRelative); + }); + } + + // Error in generated TX - issue #524 + else if (err && err.ucode === BMA.errorCodes.TX_INPUTS_OUTPUTS_NOT_EQUAL) { + // Ask user to send log to developers var esEnable = csSettings.data.plugins && csSettings.data.plugins.es && csSettings.data.plugins.es.enable; if (esEnable) { UIUtils.loading.hide(); @@ -980,7 +993,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se // Make sure a TX in compact mode has no more than 100 lines (fix #118) // (If more than 100 lines, send to TX to himself first, then its result as sources for the final TX) - if (inputs.sources.length > 40) { + if (inputs.sources.length > constants.TX_MAX_INPUTS_COUNT) { console.debug("[Wallet] TX has to many sources. Will chain TX..."); // Compute a slice of sources @@ -988,7 +1001,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se minBase: block.unitbase, maxBase: 0, amount: 0, - sources: inputs.sources.slice(0, 39) + sources: inputs.sources.slice(0, constants.TX_MAX_INPUTS_COUNT) /* end index is excluded, so array length=TX_MAX_INPUTS_COUNT - issue #524 */ }; _.forEach(firstSlice.sources, function(source) { if (source.base < firstSlice.minBase) firstSlice.minBase = source.base; @@ -1002,13 +1015,13 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se _.forEach(firstSlice.sources, function(source) { source.consumed=true; }); - data.sources.push(res.sources); + addSources(res.sources); var secondSlice = { minBase: block.unitbase, maxBase: 0, amount: 0, - sources: inputs.sources.slice(40).concat(res.sources) + sources: inputs.sources.slice(constants.TX_MAX_INPUTS_COUNT).concat(res.sources) }; _.forEach(secondSlice.sources, function(source) { if (source.base < secondSlice.minBase) secondSlice.minBase = source.base; diff --git a/www/plugins/es/js/controllers/group-controllers.js b/www/plugins/es/js/controllers/group-controllers.js index 032500e4361c62ea59022e43e9deb82836022807..60cab476f7189580827f9c15b5cfb3eb4a707d79 100644 --- a/www/plugins/es/js/controllers/group-controllers.js +++ b/www/plugins/es/js/controllers/group-controllers.js @@ -55,11 +55,9 @@ angular.module('cesium.es.group.controllers', ['cesium.es.services']) .controller('ESGroupEditCtrl', ESGroupEditController) - .controller('PopoverGroupCtrl', PopoverGroupController) - ; -function ESGroupListController($scope, UIUtils, $state, BMA, csWallet, esGroup, ModalUtils) { +function ESGroupListController($scope, UIUtils, $state, csWallet, esGroup, ModalUtils) { 'ngInject'; var defaultSearchLimit = 40; @@ -179,122 +177,6 @@ function ESGroupListController($scope, UIUtils, $state, BMA, csWallet, esGroup, }; } -function PopoverGroupController($scope, $timeout, UIUtils, $state, csWallet, esNotification, esGroup, esModals) { - 'ngInject'; - - var defaultSearchLimit = 40; - - $scope.search = { - loading : true, - results: null, - hasMore : false, - loadingMore : false, - limit: defaultSearchLimit, - options: { - codes: { - includes: esNotification.constants.GROUP_CODES - } - } - }; - - $scope.load = function(from, size) { - var options = angular.copy($scope.search.options); - options.from = options.from || from || 0; - options.size = options.size || size || defaultSearchLimit; - - return esNotification.load(csWallet.data.pubkey, options) - .then(function(notifications) { - if (!from) { - $scope.search.results = notifications; - } - else { - $scope.search.results = $scope.search.results.concat(notifications); - } - $scope.search.loading = false; - $scope.search.hasMore = ($scope.search.results && $scope.search.results.length >= $scope.search.limit); - $scope.updateView(); - }) - .catch(function(err) { - $scope.search.loading = false; - if (!from) { - $scope.search.results = []; - } - $scope.search.hasMore = false; - UIUtils.onError('MESSAGE.ERROR.LOAD_NOTIFICATIONS_FAILED')(err); - }); - }; - - $scope.updateView = function() { - - $timeout(function() { - UIUtils.ink({selector: '.popover-notification .item.ink'}); - }, 100); - }; - - $scope.showMore = function() { - $scope.search.limit = $scope.search.limit || defaultSearchLimit; - $scope.search.limit = $scope.search.limit * 2; - if ($scope.search.limit < defaultSearchLimit) { - $scope.search.limit = defaultSearchLimit; - } - $scope.search.loadingMore = true; - $scope.load( - $scope.search.results.length, // from - $scope.search.limit) - .then(function() { - $scope.search.loadingMore = false; - $scope.$broadcast('scroll.infiniteScrollComplete'); - }); - }; - - $scope.onNewNotification = function(notification) { - if (!$scope.search.loading && !$scope.search.loadingMore && notification.isMessage) { - console.debug("[popover] detected new message (from notification service)"); - - if (notification.reference) { - console.log("[popover] new message has a reference !"); - } - $scope.search.results.splice(0,0,notification); - $scope.updateView(); - } - }; - - $scope.select = function(notification) { - if (!notification.read) notification.read = true; - $state.go('app.user_view_message', {id: notification.id}); - $scope.closePopover(notification); - }; - - $scope.resetData = function() { - if ($scope.search.loading) return; - console.debug("[ES] [messages] Resetting data (settings or account may have changed)"); - $scope.search.hasMore = false; - $scope.search.results = []; - $scope.search.loading = true; - delete $scope.search.limit; - }; - - csWallet.api.data.on.logout($scope, $scope.resetData); - - /* -- Modals -- */ - - $scope.showNewMessageModal = function(parameters) { - $scope.closePopover(); - return esModals.showMessageCompose(parameters) - .then(function(sent) { - if (sent) UIUtils.toast.show('MESSAGE.INFO.MESSAGE_SENT'); - }); - }; - - esNotification.api.data.on.new($scope, $scope.onNewNotification); - - /* -- default popover action -- */ - if ($scope.search.loading) { - $scope.load(); - } - -} - function ESGroupViewController($scope, $state, UIUtils, esGroup, csWallet) { 'ngInject'; @@ -350,7 +232,7 @@ function ESGroupViewController($scope, $state, UIUtils, esGroup, csWallet) { } function ESGroupEditController($scope, esGroup, UIUtils, $state, $q, Device, - $ionicHistory, ModalUtils, $focus, $timeout, esHttp) { + $ionicHistory, ModalUtils, $focus, esHttp) { 'ngInject'; $scope.walletData = {}; diff --git a/www/plugins/es/js/services/social-services.js b/www/plugins/es/js/services/social-services.js index ed1c385872cb8935d936be948496a50e0b2adc85..de204dee445652ba3f9fac7b72316b3a0e382b89 100644 --- a/www/plugins/es/js/services/social-services.js +++ b/www/plugins/es/js/services/social-services.js @@ -49,7 +49,7 @@ angular.module('cesium.es.social.services', ['cesium.es.crypto.services']) urlToMatch = url.substring(0, slashPathIndex); } } - console.log("match URI, try to match: " + urlToMatch); + //console.debug("[social] match URI, try to match: " + urlToMatch); _.keys(regexp.socials).forEach(function(key){ if (regexp.socials[key].test(urlToMatch)) { type = key; @@ -63,9 +63,7 @@ angular.module('cesium.es.social.services', ['cesium.es.crypto.services']) else if (regexp.EMAIL.test(url)) { type = 'email'; } - if (!type) { - console.log("match type: " + type); - } + //if (!type) console.debug("[social] match type: " + type); return type; } diff --git a/www/plugins/map/js/services/wot-services.js b/www/plugins/map/js/services/wot-services.js index cffc91381ebae33dad6445f8c4704e7cd831f8b5..02aab8ad5292ccff59b512c95dd3034bc611d327 100644 --- a/www/plugins/map/js/services/wot-services.js +++ b/www/plugins/map/js/services/wot-services.js @@ -182,7 +182,7 @@ angular.module('cesium.map.wot.services', ['cesium.services']) // Resolve missing positions by addresses (only if google API enable) if (searchAddressItems.length) { var now = new Date().getTime(); - console.log('[map] [wot] Search positions of {0} addresses...'.format(searchAddressItems.length)); + console.debug('[map] [wot] Search positions of {0} addresses...'.format(searchAddressItems.length)); var counter = 0; return $q.all(searchAddressItems.reduce(function(res, item) { @@ -202,7 +202,7 @@ angular.module('cesium.map.wot.services', ['cesium.services']) .catch(function() {/*silent*/})); }, [])) .then(function(){ - console.log('[map] [wot] Resolved {0}/{1} addresses in {2}ms'.format(counter, searchAddressItems.length, new Date().getTime()-now)); + console.debug('[map] [wot] Resolved {0}/{1} addresses in {2}ms'.format(counter, searchAddressItems.length, new Date().getTime()-now)); return items; }); } diff --git a/www/templates/wallet/item_tx.html b/www/templates/wallet/item_tx.html index c526814360255aaf41cfb1a020431ec00cd175eb..a9afffa13f13d35686e8a7cb12e6f1ed9b02accd 100644 --- a/www/templates/wallet/item_tx.html +++ b/www/templates/wallet/item_tx.html @@ -35,8 +35,7 @@ <!-- not locked TX --> <span ng-if="::!tx.lockedOutputs" class="badge item-note" ng-class="{'badge-calm': tx.amount > 0}"> - <span ng-bind-html=":rebind:tx.amount| formatAmount"></span> - <span ng-bind-html=":rebind:$root.currency.name|currencySymbol"></span> + <span ng-bind-html=":rebind:tx.amount| formatAmount:{currency:$root.currency.name}"></span> </span> <!-- Locked TX --> @@ -45,14 +44,11 @@ ng-class="{'badge-calm': tx.amount > 0}" ng-click="showLockedOutputsPopover(tx, $event)"> <i class="icon ion-locked" ></i> - <span ng-bind-html=":rebind:tx.amount| formatAmount"></span> - <span ng-bind-html=":rebind:$root.currency.name|currencySymbol"></span> + <span ng-bind-html=":rebind:tx.amount| formatAmount:{currency:$root.currency.name}"></span> </a> <div class="badge badge-secondary" ng-if="$root.settings.expertMode"> - (<ng-bind-html ng-bind-html=":rebind:tx.amount| formatAmount:{useRelative: !$root.settings.useRelative}"> - </ng-bind-html> - <span ng-bind-html=":rebind:secondaryUnit"></span>) + (<span ng-bind-html=":rebind:tx.amount| formatAmount:{useRelative: !$root.settings.useRelative, currency:$root.currency.name}"></span>) </div> </div> </div> diff --git a/www/templates/wallet/view_wallet_tx.html b/www/templates/wallet/view_wallet_tx.html index e0346fe38f6c266581ca91aeb1025efd6b4fb030..e2ddba2218a648dd22c045d25699acaa45552de1 100644 --- a/www/templates/wallet/view_wallet_tx.html +++ b/www/templates/wallet/view_wallet_tx.html @@ -15,14 +15,11 @@ <div class="positive-900-bg hero"> <div class="content" ng-if="!loading"> <h1 class="light"> - <span ng-bind-html=":balance:rebind:formData.balance | formatAmount"></span> - <span ng-bind-html=":rebind:unit"></span> - + <span ng-bind-html=":balance:rebind:formData.balance | formatAmount:{currency: $root.currency.name}"></span> </h1> <h4 ng-if="!loading && $root.settings.expertMode" style="font-style: italic;"> - (<span ng-bind-html=":balance:rebind:formData.balance | formatAmount:{useRelative:!$root.settings.useRelative}"></span> - <span ng-bind-html=":rebind:secondaryUnit"></span>) + (<span ng-bind-html=":balance:rebind:formData.balance | formatAmount:{useRelative:!$root.settings.useRelative, currency: $root.currency.name}"></span>) </h4> <div class="helptip-anchor-center"> <a id="helptip-wallet-balance"> </a> diff --git a/www/templates/wallet/view_wallet_tx_error.html b/www/templates/wallet/view_wallet_tx_error.html index 78e4eb481a197bc94656785041969200ec159d3a..b23a813b51a573577fbc543010f9010e16a42bd7 100644 --- a/www/templates/wallet/view_wallet_tx_error.html +++ b/www/templates/wallet/view_wallet_tx_error.html @@ -6,23 +6,20 @@ <ion-nav-buttons side="secondary"> - <button class="button button-icon button-clear icon ion-loop" ng-click="doUpdate()"> - </button> - <button class="button button-icon button-clear" ng-click="actionsPopover.show($event)"> - <i class="icon ion-android-more-vertical"></i> + <button class="button button-icon button-clear icon ion-loop visible-xs visible-sm " ng-click="doUpdate()"> </button> </ion-nav-buttons> <ion-content scroll="true"> - <!-- Buttons bar - <div class="hidden-xs hidden-sm padding" style="text-align:center" - ng-if="!!convertedBalance"> - <button class="button button-raised button-energized-900 ink-dark" - ng-click="openTransfer()"> - {{'ACCOUNT.BTN_SEND_MONEY' | translate}} + <!-- Buttons bar --> + <div class="hidden-xs hidden-sm padding text-center"> + + <button class="button button-stable button-small-padding icon ion-loop ink" + ng-click="doUpdate()" + title="{{'COMMON.BTN_REFRESH' | translate}}"> </button> - </div>--> + </div> <div class="row no-padding"> <div class="col col-20 hidden-xs hidden-sm"> @@ -44,7 +41,7 @@ </span> <div class="item item-pending item-tx item-icon-left" - ng-repeat="tx in formData.tx.errors | filter: filterReceivedTx('amount')" + ng-repeat="tx in formData.tx.errors | filter: filterReceivedTx" ng-init="pending=true;" ng-include="'templates/wallet/item_tx.html'"> </div> @@ -63,7 +60,7 @@ </span> <div class="item item-pending item-tx item-icon-left" - ng-repeat="tx in formData.tx.errors | filter: filterSentTx('amount')" + ng-repeat="tx in formData.tx.errors | filter: filterSentTx" ng-init="error=true;" ng-include="'templates/wallet/item_tx.html'"> </div> diff --git a/www/templates/wot/view_identity_tx.html b/www/templates/wot/view_identity_tx.html index 44e61948c1e1dfb74678c764409bdd81fc299032..16499945901dc431bf23c02c4397a6937d0e7389 100644 --- a/www/templates/wot/view_identity_tx.html +++ b/www/templates/wot/view_identity_tx.html @@ -8,7 +8,7 @@ <ion-content> - <div class="hidden-xs hidden-sm padding text-center" ng-if="!loading"> + <div class="hidden-xs hidden-sm padding text-center"> <button class="button button-stable button-small-padding icon ion-loop ink" ng-click="doUpdate()" @@ -37,10 +37,12 @@ <div class="col"> <!-- the balance --> - <div class="item item-divider item-tx"> + <div class="item item-tx item-divider"> {{'ACCOUNT.BALANCE_ACCOUNT'|translate}} - <div class="badge badge-balanced"> - {{balance|formatAmount}} <span ng-bind-html="$root.currency.name|currencySymbol"></span> + <div class="badge item-note badge-balanced" ng-bind-html=":balance:formData.balance|formatAmount:{currency: $root.currency.name}"> + </div> + <div class="badge badge-secondary" ng-if="$root.settings.expertMode"> + (<span ng-bind-html=":balance:formData.balance| formatAmount: {useRelative: !$root.settings.useRelative, currency: $root.currency.name} "></span>) </div> </div> @@ -51,11 +53,11 @@ <!-- iterate on each TX --> <div class="item item-tx item-icon-left" - ng-repeat="tx in history" + ng-repeat="tx in formData.tx.history" ng-include="'templates/wallet/item_tx.html'"> </div> - <div class="item item-text-wrap text-center" ng-if="tx.fromTime > 0"> + <div class="item item-text-wrap text-center" ng-if="formData.tx.fromTime > 0"> <p> <a ng-click="showMoreTx()">{{:locale:'ACCOUNT.SHOW_MORE_TX'|translate}}</a> <span class="gray" translate="ACCOUNT.TX_FROM_DATE" translate-values="{fromTime: tx.fromTime}"></span>