From d39d58aab6c6a6d17baa2515e35acb32d977fc69 Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Thu, 12 Jan 2017 17:03:44 +0100
Subject: [PATCH] - Wallet: button "renew membership" does not work -fix #241 -
 Certification count (Wallet & Wot): refactoring into a component

---
 www/i18n/locale-en.json                       |  3 +-
 www/i18n/locale-fr-FR.json                    |  7 +--
 www/index.html                                |  3 +-
 www/js/app.js                                 |  2 +-
 www/js/components.js                          | 21 +++++++++
 www/js/config.js                              | 32 ++++++++------
 www/js/controllers/help-controllers.js        |  2 +-
 www/js/controllers/wot-controllers.js         |  1 +
 www/js/directives.js                          | 14 +-----
 www/js/services/wallet-services.js            |  3 +-
 www/js/services/wot-services.js               | 44 +++++++++++++------
 .../common/badge_certification_count.html     | 15 +++++++
 www/templates/wallet/view_wallet.html         |  9 ++--
 .../wot/tabs/item_certification.html          |  4 +-
 .../wot/tabs/view_certifications.html         | 19 ++------
 www/templates/wot/view_identity.html          | 21 +++------
 16 files changed, 118 insertions(+), 82 deletions(-)
 create mode 100644 www/js/components.js
 create mode 100644 www/templates/common/badge_certification_count.html

diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 0d7a013b..16df1439 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -369,7 +369,8 @@
     "TRANSFER_SENT": "Transfer request successfully sent",
     "COPY_TO_CLIPBOARD_DONE": "Copy succeed",
     "MEMBERSHIP_OUT_SENT": "Membership revocation sent",
-    "NOT_NEED_MEMBERSHIP": "Already a member."
+    "NOT_NEED_MEMBERSHIP": "Already a member.",
+    "IDENTITY_WILL_MISSING_CERTIFICATIONS": "This identity will soon lack certification (at least {{willNeedCertificationCount}}).",
   },
   "CONFIRM": {
     "POPUP_TITLE": "<b>Confirmation</b>",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index e0f17667..a9ac9f11 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -242,8 +242,8 @@
     "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 manquer de certifications",
-    "WILL_NEED_RENEW_MEMBERSHIP": "Votre adhésion comme membre va expirer {{membershipExpiresIn|formatDurationTo}}. Pensez <a ng-click=\"doQuickFix('renew')\">renouveller votre adhésion</a> d'ici là.",
+    "WILL_MISSING_CERTIFICATIONS": "Vous allez bientôt <b>manquer de certification</b> (au moins {{willNeedCertificationCount}} est nécessaire)",
+    "WILL_NEED_RENEW_MEMBERSHIP": "Votre adhésion comme membre <b>va expirer {{membershipExpiresIn|formatDurationTo}}</b>. Pensez <a ng-click=\"doQuickFix('renew')\">renouveller votre adhésion</a> d'ici là.",
     "CERTIFICATION_COUNT": "Certifications reçues",
     "SIG_STOCK": "Certifications envoyées",
     "BTN_RECEIVE_MONEY": "Encaisser",
@@ -369,7 +369,8 @@
     "TRANSFER_SENT": "Demande de virement envoyée avec succès",
     "COPY_TO_CLIPBOARD_DONE": "Copie effectuée",
     "MEMBERSHIP_OUT_SENT": "Résiliation envoyée avec succès",
-    "NOT_NEED_MEMBERSHIP": "Vous êtes déjà membre."
+    "NOT_NEED_MEMBERSHIP": "Vous êtes déjà membre.",
+    "IDENTITY_WILL_MISSING_CERTIFICATIONS": "Cette identité va bientôt manquer de certification (au moins {{willNeedCertificationCount}}).",
   },
   "CONFIRM": {
     "POPUP_TITLE": "<b>Confirmation</b>",
diff --git a/www/index.html b/www/index.html
index d50ae1e5..0e0c1aa2 100644
--- a/www/index.html
+++ b/www/index.html
@@ -123,8 +123,9 @@
     <!--endRemoveIf(no-plugin)-->
 
       <!-- App -->
-      <script src="dist/dist_js/app/directives.js"></script>
       <script src="dist/dist_js/app/app.js"></script>
+      <script src="dist/dist_js/app/components.js"></script>
+      <script src="dist/dist_js/app/directives.js"></script>
     <!-- endbuild -->
     <!-- build:js config.js -->
       <!-- config  -->
diff --git a/www/js/app.js b/www/js/app.js
index 4d0b2593..2e722453 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -14,7 +14,7 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   // removeIf(no-plugin)
   'cesium.plugins',
   // endRemoveIf(no-plugin)
-  'cesium.directives', 'cesium.controllers', 'cesium.templates', 'cesium.translations'
+  'cesium.controllers', 'cesium.templates', 'cesium.translations'
   ])
 
   .filter('formatInteger', function() {
diff --git a/www/js/components.js b/www/js/components.js
new file mode 100644
index 00000000..703c0ec0
--- /dev/null
+++ b/www/js/components.js
@@ -0,0 +1,21 @@
+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: '=',
+      parameters: '<',
+      csId: '@'
+    },
+    templateUrl: 'templates/common/badge_certification_count.html'
+  })
+;
diff --git a/www/js/config.js b/www/js/config.js
index a0808574..80ae6d91 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -10,31 +10,35 @@ angular.module("cesium.config", [])
 
 .constant("csConfig", {
 	"cacheTimeMs": 60000,
-	"fallbackLanguage": "en",
-	"rememberMe": false,
+	"fallbackLanguage": "fr-FR",
+	"defaultLanguage": "fr-FR",
+	"rememberMe": true,
 	"showUDHistory": false,
-	"timeout": 10000,
+	"timeout": 6000,
 	"timeWarningExpireMembership": 5184000,
 	"timeWarningExpire": 7776000,
 	"useLocalStorage": true,
 	"useRelative": true,
 	"initPhase": false,
-	"expertMode": false,
-	"decimalCount": 4,
+	"expertMode": true,
 	"helptip": {
-		"enable": true,
-		"installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
+		"enable": false,
+		"installDocUrl": {
+			"fr-FR": "http://www.le-sou.org/devenir-noeud/",
+			"en": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
+		}
 	},
 	"node": {
-		"host": "cgeek.fr",
-		"port": "9330"
+		"host": "fakenet.cgeek.fr",
+		"port": "10900"
 	},
 	"plugins": {
 		"es": {
-			"enable": true,
+			"enable": false,
 			"askEnable": false,
-			"host": "data.duniter.fr",
-			"port": "80",
+			"host": "localhost",
+			"port": 9200,
+			"wsPort": 9400,
 			"notifications": {
 				"txSent": true,
 				"txReceived": true,
@@ -44,8 +48,8 @@ angular.module("cesium.config", [])
 		}
 	},
 	"version": "0.9.2",
-	"build": "2017-01-11T16:47:07.715Z",
+	"build": "2017-01-11T16:51:25.948Z",
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
-;
\ No newline at end of file
+;
diff --git a/www/js/controllers/help-controllers.js b/www/js/controllers/help-controllers.js
index 9c01e4e2..21db1203 100644
--- a/www/js/controllers/help-controllers.js
+++ b/www/js/controllers/help-controllers.js
@@ -144,7 +144,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     $scope.continue = true;
 
     // Currency tour
-    return $scope.startCurrencyTour(0, true)
+    return $scope.startWotTour(0, true)
       .then(function(endIndex){
         if (!endIndex || $scope.cancelled) return false;
         csSettings.data.helptip.currency=endIndex;
diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js
index 74534544..d2625994 100644
--- a/www/js/controllers/wot-controllers.js
+++ b/www/js/controllers/wot-controllers.js
@@ -80,6 +80,7 @@ angular.module('cesium.wot.controllers', ['cesium.services'])
 
   .controller('WotCertificationsViewCtrl', WotCertificationsViewController)
 
+
 ;
 
 function WotLookupController($scope, BMA, $state, UIUtils, $timeout, csConfig, csSettings, Device, csWallet, csWot, $focus, $ionicPopover) {
diff --git a/www/js/directives.js b/www/js/directives.js
index c9f987f7..f73568a1 100644
--- a/www/js/directives.js
+++ b/www/js/directives.js
@@ -1,4 +1,4 @@
-angular.module('cesium.directives', ['cesium.services'])
+angular.module('cesium')
 
   // Add new compare-to directive (need for form validation)
   .directive("compareTo", function() {
@@ -250,16 +250,4 @@ angular.module('cesium.directives', ['cesium.services'])
   };
 })
 
-  // FIXME use Angular1.5 component
-  // see doc: https://medium.com/google-developer-experts/angular-new-features-in-angularjs-1-5-24f9b503af15#.wiklfv58s)
-  /*.component('csAvatar', {
-    bindings: {
-      avatar: '@',
-      icon: '@'
-    },
-    transclude: true,
-    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>'
-  })*/
 ;
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 374cc7a2..2f2db0b6 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -662,7 +662,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
           (data.parameters.sigQty - data.requirements.certificationCount) : 0;
       data.requirements.willNeedCertificationCount = (!data.requirements.needMembership &&
           data.requirements.needCertificationCount === 0 && (data.requirements.certificationCount - data.requirements.willExpireCertificationCount) < data.parameters.sigQty) ?
-          (data.parameters.sigQty - data.requirements.certificationCount - data.requirements.willExpireCertificationCount) : 0;
+          (data.parameters.sigQty - data.requirements.certificationCount + data.requirements.willExpireCertificationCount) : 0;
+      data.requirements.pendingCertificationCount = 0 ; // init to 0, because not loaded here (see wot-service.js)
 
       // Add user events
       data.events = data.events.reduce(function(res, event) {
diff --git a/www/js/services/wot-services.js b/www/js/services/wot-services.js
index 9ff707fa..7509ec36 100644
--- a/www/js/services/wot-services.js
+++ b/www/js/services/wot-services.js
@@ -104,11 +104,13 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
             requirements.certificationCount = (requirements.certifications) ? requirements.certifications.length : 0;
             requirements.willExpireCertificationCount = requirements.certifications ? requirements.certifications.reduce(function(count, cert){
               if (cert.expiresIn <= csSettings.data.timeWarningExpire) {
+                cert.willExpire = true;
                 return count + 1;
               }
               return count;
             }, 0) : 0;
             requirements.isMember = (requirements.membershipExpiresIn > 0);
+
             resolve(requirements);
           })
           .catch(function(err) {
@@ -442,6 +444,32 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
           ;
       },
 
+      finishLoadRequirements = function(data) {
+        data.requirements.needCertificationCount = (!data.requirements.needMembership && (data.requirements.certificationCount < data.sigQty)) ?
+          (data.sigQty - data.requirements.certificationCount) : 0;
+        data.requirements.willNeedCertificationCount = (!data.requirements.needMembership && !data.requirements.needCertificationCount &&
+          (data.requirements.certificationCount - data.requirements.willExpireCertificationCount) < data.sigQty) ?
+          (data.sigQty - data.requirements.certificationCount + data.requirements.willExpireCertificationCount) : 0;
+        data.requirements.pendingCertificationCount = data.received_cert_pending ? data.received_cert_pending.length : 0;
+
+        // Add events
+        if (data.hasBadSelfBlock) {
+          delete data.hasBadSelfBlock;
+          if (!data.isMember) {
+            addEvent(data, {type: 'error', message: 'ERROR.IDENTITY_INVALID_BLOCK_HASH'});
+            console.debug("[wot] Invalid membership for {0}: block hash changed".format(data.uid));
+          }
+        }
+        else if (data.requirements.expired) {
+          addEvent(data, {type: 'error', message: 'ERROR.IDENTITY_EXPIRED'});
+          console.debug("[wot] Identity {0} expired".format(data.uid));
+        }
+        else if (data.requirements.willNeedCertificationCount > 0) {
+          addEvent(data, {type: 'error', message: 'INFO.IDENTITY_WILL_MISSING_CERTIFICATIONS', messageParams: data.requirements});
+          console.debug("[wot] Identity {0} will need {1} certification(s)".format(data.uid, data.requirements.willNeedCertificationCount));
+        }
+      },
+
       loadSources = function(pubkey) {
         return BMA.tx.sources({pubkey: pubkey})
           .then(function(res){
@@ -517,19 +545,6 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
               })
           ])
           .then(function() {
-            // Add events
-            if (data.hasBadSelfBlock) {
-              delete data.hasBadSelfBlock;
-              if (!data.isMember) {
-                addEvent(data, {type: 'error', message: 'ERROR.IDENTITY_INVALID_BLOCK_HASH'});
-                console.debug("[wot] Invalid membership for {0}: block hash changed".format(data.uid));
-              }
-            }
-            else if (data.requirements.expired) {
-              addEvent(data, {type: 'error', message: 'ERROR.IDENTITY_EXPIRED'});
-              console.debug("[wot] Identity expired for {0}".format(data.uid));
-            }
-
             if (!data.requirements.uid)
               return api.data.raisePromise.load(data)
                 .catch(function(err) {
@@ -566,6 +581,9 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
             ]);
           })
           .then(function() {
+            // Add compute some additional requirements (that required all data like certifications)
+            finishLoadRequirements(data);
+
             // API extension
             return api.data.raisePromise.load(data)
               .catch(function(err) {
diff --git a/www/templates/common/badge_certification_count.html b/www/templates/common/badge_certification_count.html
new file mode 100644
index 00000000..75397e96
--- /dev/null
+++ b/www/templates/common/badge_certification_count.html
@@ -0,0 +1,15 @@
+<span id="{{$ctrl.id}}"
+    class="badge badge-balanced"
+    ng-class="{'badge-energized': $ctrl.requirements.willNeedCertificationCount || ($ctrl.requirements.needCertificationCount + $ctrl.requirements.pendingCertificationCount >= $ctrl.parameters.sigQty),
+               'badge-assertive': ($ctrl.requirements.needCertificationCount + $ctrl.requirements.pendingCertificationCount < $ctrl.parameters.sigQty)}">
+  <span ng-if="$ctrl.requirements.certificationCount || !$ctrl.requirements.pendingCertificationCount">
+    <i ng-if="!$ctrl.requirements.needCertificationCount" class="ion-android-done"></i>
+    {{$ctrl.requirements.certificationCount}}
+    <i ng-if="$ctrl.requirements.willNeedCertificationCount" class="ion-android-warning"></i>
+  </span>
+  <span ng-if="$ctrl.requirements.pendingCertificationCount">
+    <ng-if ng-if="$ctrl.requirements.certificationCount">+ </ng-if>
+    <i class="ion-clock"></i>
+    {{$ctrl.requirements.pendingCertificationCount}}
+  </span>
+</span>
diff --git a/www/templates/wallet/view_wallet.html b/www/templates/wallet/view_wallet.html
index 7a8c737d..8fa8777b 100644
--- a/www/templates/wallet/view_wallet.html
+++ b/www/templates/wallet/view_wallet.html
@@ -64,7 +64,7 @@
 
       <button class="button button-raised icon-left ion-loop ink"
               ng-if="walletData.requirements.needRenew"
-              ng-click="membershipRenew()">
+              ng-click="renewMembership()">
         {{'ACCOUNT.BTN_MEMBERSHIP_RENEW' | translate}}
       </button>
 
@@ -90,8 +90,11 @@
              ng-click="showCertifications()">
             <i class="icon ion-ribbon-b"></i>
             <span clas="input-label">{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>
-            <span class="badge"
-                  ng-class="{'badge-balanced': walletData.requirements.needCertificationCount==0 && walletData.requirements.willNeedCertificationCount==0, 'badge-assertive': walletData.requirements.needCertificationCount>0 || walletData.requirements.willNeedCertificationCount>0}">{{walletData.requirements.certificationCount}}</span>
+
+            <cs-badge-certification requirements="walletData.requirements"
+                                    parameters="{sigQty: walletData.parameters.sigQty}">
+            </cs-badge-certification>
+
             <i class="gray icon ion-ios-arrow-right"></i>
           </a>
 
diff --git a/www/templates/wot/tabs/item_certification.html b/www/templates/wot/tabs/item_certification.html
index 38b3e0d5..7af7b1de 100644
--- a/www/templates/wot/tabs/item_certification.html
+++ b/www/templates/wot/tabs/item_certification.html
@@ -43,7 +43,9 @@
                 <span class="gray" ng-if="$root.settings.expertMode"> | {{::cert.pending ? 'WOT.SIGNED_ON_BLOCK' : 'WOT.WRITTEN_ON_BLOCK' | translate:cert}}</span>
               </h4>
             </span>
-            <div class="badge badge-stable" ng-if="cert.expiresIn">
+            <div class="badge badge-stable"
+                 ng-class="{'badge-energized': cert.willExpire}"
+                 ng-if="cert.expiresIn">
               {{::cert.expiresIn | formatDurationTo}}
             </div>
             <div class="badge badge-assertive" ng-if="!cert.expiresIn">
diff --git a/www/templates/wot/tabs/view_certifications.html b/www/templates/wot/tabs/view_certifications.html
index c10b5f48..e7105bd3 100644
--- a/www/templates/wot/tabs/view_certifications.html
+++ b/www/templates/wot/tabs/view_certifications.html
@@ -9,21 +9,10 @@
             <i class="icon ion-ribbon-b"></i>
             <span translate>WOT.CERTIFICATIONS.RECEIVED</span>
 
-            <span id="helptip-wot-view-certifications-count"
-                  class="badge"
-                  ng-class="{'badge-balanced': formData.received_cert.length >= formData.sigQty,
-                             'badge-energized': formData.received_cert.length < formData.sigQty && formData.received_cert.length + formData.received_cert_pending.length >= formData.sigQty,
-                             'badge-assertive': formData.received_cert.length + formData.received_cert_pending.length < formData.sigQty}">
-              <span ng-if="formData.received_cert.length || !formData.received_cert_pending.length">
-                 <i ng-if="formData.received_cert.length >= formData.sigQty" class="ion-android-done"></i>
-                {{formData.received_cert.length}}
-              </span>
-              <span ng-if="formData.received_cert_pending.length">
-                <ng-if ng-if="formData.received_cert.length">+ </ng-if>
-                <i class="ion-clock"></i>
-                {{formData.received_cert_pending.length}}
-              </span>
-            </span>
+            <cs-badge-certification cs-id="helptip-wot-view-certifications-count"
+                                    requirements="formData.requirements"
+                                    parameters="{sigQty: formData.sigQty}">
+            </cs-badge-certification>
           </div>
 
           <!-- Error certifications count -->
diff --git a/www/templates/wot/view_identity.html b/www/templates/wot/view_identity.html
index 879edb15..f9666216 100644
--- a/www/templates/wot/view_identity.html
+++ b/www/templates/wot/view_identity.html
@@ -55,21 +55,12 @@
            ng-click="showCertifications()">
           <i class="icon ion-ribbon-b"></i>
           <span translate>ACCOUNT.CERTIFICATION_COUNT</span>
-          <span id="helptip-wot-view-certifications-count"
-                class="badge"
-                ng-class="{'badge-balanced': formData.received_cert.length >= formData.sigQty,
-                 'badge-energized': formData.received_cert.length < formData.sigQty && formData.received_cert.length + formData.received_cert_pending.length >= formData.sigQty,
-                 'badge-assertive': formData.received_cert.length < formData.sigQty}">
-            <span ng-if="formData.received_cert.length || !formData.received_cert_pending.length">
-              <i ng-if="formData.received_cert.length >= formData.sigQty" class="ion-android-done"></i>
-              {{formData.received_cert.length}}
-            </span>
-            <span ng-if="formData.received_cert_pending.length">
-              <ng-if ng-if="formData.certificationCount">+ </ng-if>
-              <i class="ion-clock"></i>
-              {{formData.received_cert_pending.length}}
-            </span>
-          </span>
+
+          <cs-badge-certification cs-id="helptip-wot-view-certifications-count"
+                                  requirements="formData.requirements"
+                                  parameters="{sigQty: formData.sigQty}">
+          </cs-badge-certification>
+
           <i class="gray icon ion-ios-arrow-right"></i>
         </a>
 
-- 
GitLab