diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 7bb1658831d1635974523bd5833119bffb731ded..5bcced84b4933f72dc0863e9772b1345c599999b 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -121,7 +121,9 @@
"POPUP_NODE": {
"TITLE" : "Duniter Node",
"HELP" : "Set the address of the node to use:"
- }
+ },
+ "SHOW_NODE_LIST" : "Choose a node"
+
},
"CURRENCY": {
"SELECT": {
@@ -160,7 +162,10 @@
"PEERS": "Peers",
"KNOWN_PEERS": "Known peers",
"SIGNED_ON_BLOCK": "Signed on block",
- "MIRROR": "mirror"
+ "MIRROR": "mirror",
+ "NODE_LIST" : "Node's list",
+ "MEMBERS" : "Member Nodes",
+ "ALL_NODES" : "All nodes"
},
"WOT": {
"SEARCH_HELP": "Search (member or public key)",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index d0f17a46a83d2b175600809df279b7aac1f71f2a..01bf470174b8536dee5cc71c11d057e52cf72f31 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -121,7 +121,8 @@
"POPUP_NODE": {
"TITLE" : "Noeud Duniter",
"HELP" : "Saisissez l'adresse du noeud que vous voulez utiliser :"
- }
+ },
+ "SHOW_NODE_LIST" : "Choisir un noeud"
},
"CURRENCY": {
"SELECT": {
@@ -160,7 +161,10 @@
"PEERS": "Noeuds",
"KNOWN_PEERS": "Noeuds connus",
"SIGNED_ON_BLOCK": "Signé sur le bloc",
- "MIRROR": "mirroir"
+ "MIRROR": "mirroir",
+ "NODE_LIST" : "Liste des noeuds",
+ "MEMBERS" : "Noeuds membres",
+ "ALL_NODES" : "Tous les noeuds"
},
"WOT": {
"SEARCH_HELP": "Recherche (pseudo ou clé publique)",
diff --git a/www/js/controllers/network-controllers.js b/www/js/controllers/network-controllers.js
index a2649840eab92ba731a9c00e953f4a79ad68b89e..4aa30c686f11d25c99f2e1c7998dae395002ab5e 100644
--- a/www/js/controllers/network-controllers.js
+++ b/www/js/controllers/network-controllers.js
@@ -35,6 +35,8 @@ angular.module('cesium.network.controllers', ['cesium.services'])
.controller('PeerCtrl', PeerController)
+.controller('NetworkModalCtrl', NetworkModalController)
+
;
function NetworkViewController($scope, $q, $translate, $timeout, BMA, UIUtils, csSettings, csCurrency, csNetwork) {
@@ -42,7 +44,6 @@ function NetworkViewController($scope, $q, $translate, $timeout, BMA, UIUtils, c
$scope.formData = {
useRelative: csSettings.data.useRelative
};
-
$scope.screen = UIUtils.screen;
$scope.$on('$ionicParentView.enter', function(e, state) {
@@ -53,7 +54,7 @@ function NetworkViewController($scope, $q, $translate, $timeout, BMA, UIUtils, c
}
})
- .catch(UIUtils.onError('ERROR.GET_CURRENCY_FAILED'));
+ .catch(UIUtils.onError('ERROR.GET_CURRENCY_FAILED'));
});
$scope.$on('$ionicParentView.beforeLeave', function(){
@@ -85,11 +86,11 @@ function NetworkViewController($scope, $q, $translate, $timeout, BMA, UIUtils, c
$scope.$on('$destroy', function(){
csNetwork.close();
});
- }
+ }
// Show help tip
$scope.showHelpTip();
- };
+ };
$scope.refresh = function() {
// Network
@@ -115,3 +116,89 @@ function NetworkViewController($scope, $q, $translate, $timeout, BMA, UIUtils, c
});
};
}
+
+function NetworkModalController($scope, $q, $translate, $timeout, $ionicPopover, BMA,
+ UIUtils, csSettings, csCurrency, csNetwork) {
+ $scope.loadingPeers = true;
+ $scope.formData = {
+ useRelative: csSettings.data.useRelative
+ };
+ $scope.enableFilter = true;
+ $scope.display='members';
+ $scope.screen = UIUtils.screen;
+
+ csCurrency.all()
+ .then(function (currencies) {
+ if (currencies && currencies.length > 0) {
+ $scope.load(currencies[0]);
+ }
+
+ })
+ .catch(UIUtils.onError('ERROR.GET_CURRENCY_FAILED'));
+
+ $scope.load = function(currency) {
+ $scope.node = !BMA.node.same(currency.peer.host, currency.peer.port) ?
+ BMA.instance(currency.peer.host, currency.peer.port) : BMA;
+
+ if ($scope.loadingPeers){
+ csNetwork.start($scope.node);
+
+ // Catch event on new peers
+ var refreshing = false;
+ csNetwork.api.data.on.changed($scope, function(data){
+ if (!refreshing) {
+ refreshing = true;
+ $timeout(function() { // Timeout avoid to quick updates
+ console.debug("Updating UI Peers");
+ $scope.peers = data.peers;
+ // Update currency params
+
+ $scope.loadingPeers = csNetwork.isBusy();
+ refreshing = false;
+ }, 1100);
+ }
+ });
+ $scope.$on('$destroy', function(){
+ csNetwork.close();
+ });
+ }
+ };
+
+ $scope.refresh = function() {
+ // Network
+ $scope.loadingPeers = true;
+ csNetwork.loadPeers();
+ };
+
+ $scope.changeDisplay = function(type){
+ $scope.hideActionsPopover();
+ $scope.display = type;
+ }
+
+ /* -- show/hide popup -- */
+
+ $scope.showActionsPopover = function(event) {
+ if (!$scope.actionsPopover) {
+ $ionicPopover.fromTemplateUrl('templates/network/lookup_popover_actions.html', {
+ scope: $scope
+ }).then(function(popover) {
+ $scope.actionsPopover = popover;
+ //Cleanup the popover when we're done with it!
+ $scope.$on('$destroy', function() {
+ $scope.actionsPopover.remove();
+ });
+ $scope.actionsPopover.show(event);
+ });
+ }
+ else {
+ $scope.actionsPopover.show(event);
+ }
+ };
+
+ $scope.hideActionsPopover = function() {
+ if ($scope.actionsPopover) {
+ $scope.actionsPopover.hide();
+ }
+ };
+
+}
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index a653c3e60ccba3db2aae48b0957a4134e41b59c3..5777488bc0d22a96b12051f2b4dd7ff7e21e3c67 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -20,12 +20,14 @@ angular.module('cesium.settings.controllers', ['cesium.services', 'cesium.curren
.controller('SettingsCtrl', SettingsController)
;
-function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHttp, UIUtils, BMA, csSettings, $ionicPopover) {
+function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHttp,
+ UIUtils, BMA, csSettings, $ionicPopover, ModalUtils) {
'ngInject';
$scope.formData = angular.copy(csSettings.data);
$scope.popupData = {}; // need for the node popup
$scope.loading = true;
+ $scope.nodePopup = {};
$scope.$on('$ionicView.enter', function() {
$scope.load();
@@ -93,6 +95,30 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
});
};
+ $scope.showNodeList = function(){
+ $ionicPopup._popupStack[0].responseDeferred.resolve();
+ return ModalUtils.show('/templates/network/modal_network.html', 'NetworkModalCtrl')
+ .then(function(result){
+ if (result){
+ var parts = result.server.split(':');
+ var newNode;
+ if(result.dns){
+ newNode = {
+ host: result.dns,
+ port: parts[1]
+ };
+ }
+ else{
+ newNode = {
+ host: parts[0],
+ port: parts[1]
+ }
+ };
+ $scope.changeNode(newNode);
+ }
+ });
+ };
+
// Show node popup
$scope.showNodePopup = function(node) {
return $q(function(resolve, reject) {
@@ -100,7 +126,8 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
if (!!$scope.popupForm) {
$scope.popupForm.$setPristine();
}
- $translate(['SETTINGS.POPUP_NODE.TITLE', 'SETTINGS.POPUP_NODE.HELP', 'COMMON.BTN_OK', 'COMMON.BTN_CANCEL'])
+ $translate(['SETTINGS.POPUP_NODE.TITLE', 'SETTINGS.POPUP_NODE.HELP',
+ 'COMMON.BTN_OK', 'COMMON.BTN_CANCEL'])
.then(function (translations) {
// Choose UID popup
$ionicPopup.show({
diff --git a/www/js/services/network-services.js b/www/js/services/network-services.js
index 0ed037e05030eeab8b65b8a18674c4b6e98912b9..137b3a35ee5619445679083588eae7a541a5939c 100644
--- a/www/js/services/network-services.js
+++ b/www/js/services/network-services.js
@@ -151,18 +151,9 @@ angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.se
return peer;
})
.then(function(peer) {
- // Exit, if offline, not expert mode, or too small device
- if (!peer.online || !csSettings.data.expertMode || UIUtils.screen.isSmall()) return peer;
+ // Exit if offline
+ if (!peer.online) return peer;
var jobs = [];
- // Get Version
- jobs.push(node.node.summary()
- .then(function(res){
- peer.version = res && res.duniter && res.duniter.version;
- })
- .catch(function() {
- peer.version = null; // continue
- }));
-
// Get hardship (only for a member peer)
if (peer.uid) {
jobs.push(node.blockchain.stats.hardship({pubkey: peer.pubkey})
@@ -173,6 +164,17 @@ angular.module('cesium.network.services', ['ngResource', 'ngApi', 'cesium.bma.se
peer.level = null; // continue
}));
}
+ // Exit if not expert mode or too small device
+ if (!csSettings.data.expertMode || UIUtils.screen.isSmall()) return peer;
+
+ // Get Version
+ jobs.push(node.node.summary()
+ .then(function(res){
+ peer.version = res && res.duniter && res.duniter.version;
+ })
+ .catch(function() {
+ peer.version = null; // continue
+ }));
$q.all(jobs);
return peer;
diff --git a/www/templates/network/lookup_popover_actions.html b/www/templates/network/lookup_popover_actions.html
new file mode 100644
index 0000000000000000000000000000000000000000..248014d196e986d7f01d0c5b15df8fe0dede7de3
--- /dev/null
+++ b/www/templates/network/lookup_popover_actions.html
@@ -0,0 +1,22 @@
+<ion-popover-view class="fit has-header visible-sm visible-xs">
+ <ion-header-bar>
+ <h1 class="title" translate>COMMON.POPOVER_ACTIONS_TITLE</h1>
+ </ion-header-bar>
+ <ion-content scroll="false">
+ <div class="list item-text-wrap">
+
+ <a class="item item-icon-left ink"
+ ng-click="changeDisplay('members')">
+ <i class="icon ion-android-people"></i>
+ {{'PEER.MEMBERS' | translate}}
+ </a>
+
+ <a class="item item-icon-left ink"
+ ng-click="changeDisplay('allNodes')">
+ <i class="icon ion-ios-infinite"></i>
+ {{'PEER.ALL_NODES' | translate}}
+ </a>
+
+ </div>
+ </ion-content>
+</ion-popover-view>
diff --git a/www/templates/network/modal_network.html b/www/templates/network/modal_network.html
new file mode 100644
index 0000000000000000000000000000000000000000..bc18080bf8a67b81865f2647cd983608f8a40408
--- /dev/null
+++ b/www/templates/network/modal_network.html
@@ -0,0 +1,77 @@
+<ion-modal-view id="nodes" class="modal-full-height" cache-view="false">
+ <ion-header-bar class="bar-positive">
+ <button class="button button-clear" ng-click="closeModal()" translate>COMMON.BTN_CANCEL</button>
+ <h1 class="title" translate>PEER.NODE_LIST</h1>
+ <button class="button button-icon button-clear icon ion-android-more-vertical visible-xs visible-sm"
+ ng-click="showActionsPopover($event)">
+ </button>
+ </ion-header-bar>
+
+ <ion-content scroll="true">
+ <div class="list">
+ <div id="helptip-currency-peers"
+ class="item item-divider item-icon-right visible-xs visible-sm"
+ ng-if="display=='allNodes'||!enableFilter">
+ {{'PEER.ALL_NODES' | translate}}
+ <ion-spinner class="icon" icon="android" ng-if="loadingPeers"></ion-spinner>
+ </div>
+
+ <div id="helptip-currency-peers"
+ class="item item-divider item-icon-right visible-xs visible-sm"
+ ng-if="display=='members'">
+ {{'PEER.MEMBERS' | translate}}
+ <ion-spinner class="icon" icon="android" ng-if="loadingPeers"></ion-spinner>
+ <a class="icon ion-loop gray hidden-xs hidden-sm" ng-if="!loadingPeers" ng-click="refresh()">
+ </a>
+ </div>
+
+ <div id="helptip-currency-peers"
+ class="item item-divider item-icon-right hidden-xs hidden-sm">
+ {{'PEER.PEERS' | translate}}
+ <ion-spinner class="icon" icon="android" ng-if="loadingPeers"></ion-spinner>
+ <a class="icon ion-loop gray " ng-if="!loadingPeers" ng-click="refresh()">
+ </a>
+ </div>
+
+ <div class="text-center hidden-xs hidden-sm" ng-if="enableFilter">
+ <a class="button button-text button-small ink icon ion-android-people"
+ ng-class="{'button-text-positive': display=='members'}"
+ ng-click="changeDisplay('members')">
+ {{'PEER.MEMBERS' | translate}}
+ </a>
+
+ <a class="button button-text button-small ink icon ion-ios-infinite"
+ ng-class="{'button-text-positive': display=='allNodes'}"
+ ng-click="changeDisplay('allNodes')">
+ {{'PEER.ALL_NODES' | translate}}
+ </a>
+
+ </div>
+ <ng-click class="peer-item item item-icon-left"
+ ng-repeat="peer in peers track by peer.server"
+ id="helptip-currency-peer-{{$index}}"
+ ng-class="{ assertive: !peer.online, balanced: (peer.online && peer.hasMainConsensusBlock), energized: (peer.online && !peer.hasMainConsensusBlock)}"
+ ng-click="closeModal(peer)" ng-if="(!peer.level && display=='allNodes') || peer.level || !enableFilter">
+
+ <i class="icon ion-android-globe"></i>
+ <div class="row no-padding">
+ <div class="col no-padding">
+ <h3><i ng-class="{'ion-person': peer.uid, 'ion-key': !peer.uid}"></i> <span>{{peer.uid || peer.pubkey.substr(0,8)}}</span> <span class="gray">{{peer.dns && ' | ' + peer.dns}}</span></h3>
+ <h4>{{peer.server}}</h4>
+ </div>
+ <div class="col col-10 no-padding" ng-if="settings.expertMode">
+ <h3 class="hidden-sm hidden-xs hidden-md">
+ <span ng-if="peer.level"><i class="ion-lock-combination"></i> {{peer.level}}</span>
+ <span ng-if="!peer.level" translate>PEER.MIRROR</span>
+ </h3>
+ <h4 class="hidden-sm hidden-xs hidden-md gray">v{{peer.version}}</h4>
+ </div>
+ <div class="col col-20 no-padding">
+ <span id="helptip-currency-peer-{{$index}}-block"
+ class="badge" ng-class="{ 'badge-balanced': peer.hasMainConsensusBlock, 'badge-energized': peer.hasConsensusBlock }">{{peer.currentNumber}}</span>
+ </div>
+ </div>
+ </ng-click>
+ </div>
+ </ion-content>
+</ion-modal-view>
diff --git a/www/templates/network/tabs/view_nodes.html b/www/templates/network/tabs/view_nodes.html
index 24ef977b118a8f7d4eda125fb584be9f2bcada1c..e3cfd11f9651b2fa4fb7277e96c9b1ec8a4db857 100644
--- a/www/templates/network/tabs/view_nodes.html
+++ b/www/templates/network/tabs/view_nodes.html
@@ -14,7 +14,7 @@
<i class="icon ion-android-globe"></i>
<div class="row no-padding">
<div class="col no-padding">
- <h3><i ng-class="{'ion-person': peer.uid, 'ion-key': !peer.uid}"></i> {{peer.uid || peer.pubkey.substr(0,8)}}</span> <span class="gray">{{peer.dns && ' | ' + peer.dns}}</h3>
+ <h3><i ng-class="{'ion-person': peer.uid, 'ion-key': !peer.uid}"></i> <span>{{peer.uid || peer.pubkey.substr(0,8)}}</span> <span class="gray">{{peer.dns && ' | ' + peer.dns}}</span></h3>
<h4>{{peer.server}}</h4>
</div>
<div class="col col-10 no-padding" ng-if="settings.expertMode">
diff --git a/www/templates/settings/popup_node.html b/www/templates/settings/popup_node.html
index c1232d3b3bac6dee65679f6bb607e1f52fa26d54..313129bf1c5da560c441cd1509373e3fa3b4d0e6 100644
--- a/www/templates/settings/popup_node.html
+++ b/www/templates/settings/popup_node.html
@@ -1,12 +1,17 @@
<form name="popupForm" ng-submit="">
<div class="list" ng-init="setPopupForm(popupForm)">
- <label class="item item-input"
- ng-class="{'item-input-error': popupForm.$submitted && popupForm.newNode.$invalid}">
- <input name="newNode" type="text" placeholder="{{'SETTINGS.NODE_HELP' | translate}}"
- ng-model="popupData.newNode"
- ng-minlength="3"
- required>
- </label>
+ <label class="item item-input"
+ ng-class="{'item-input-error': popupForm.$submitted && popupForm.newNode.$invalid}">
+ <input name="newNode" type="text" placeholder="{{'SETTINGS.NODE_HELP' | translate}}"
+ ng-model="popupData.newNode"
+ ng-minlength="3"
+ required>
+ </label>
+ <button class="button-clear button-small gray pull-right"
+ ng-mousedown="showNodeList()">{{'SETTINGS.SHOW_NODE_LIST' | translate}}
+ <i class="icon-right ion-chevron-right gray"></i>
+ </button>
+
<div class="form-errors"
ng-if="popupForm.$submitted && popupForm.newNode.$error"
ng-messages="popupForm.newNode.$error">
@@ -19,3 +24,5 @@
</div>
</div>
</form>
+
+