diff --git a/www/index.html b/www/index.html index 3ba552d6ae6bc873ac73138cf68a2a82ab4d238d..451caedeff0a2d9e9f7b7af0760c8606bb2689a7 100644 --- a/www/index.html +++ b/www/index.html @@ -193,7 +193,6 @@ <script src="dist/dist_js/plugins/map/js/plugin.js"></script> <script src="dist/dist_js/plugins/map/js/services.js"></script> <script src="dist/dist_js/plugins/map/js/services/wot-services.js"></script> - <script src="dist/dist_js/plugins/map/js/services/network-services.js"></script> <script src="dist/dist_js/plugins/map/js/services/utils-services.js"></script> <script src="dist/dist_js/plugins/map/js/controllers/wot-controllers.js"></script> <script src="dist/dist_js/plugins/map/js/controllers/network-controllers.js"></script> diff --git a/www/js/config.js b/www/js/config.js index 4ce3354a20d2cbc411f7075cee86cba0a28dff16..a2ed9f897604529e0c18bb2c9bc23c5afa7ffbab 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -55,7 +55,9 @@ angular.module("cesium.config", []) "txReceived": true, "certSent": true, "certReceived": true - } + }, + "defaultCountry": "France", + "googleApiKey": "AIzaSyBSMd4vSr3P6TV8WI-trqio9z0Qpr1hKVk" } }, "version": "0.15.0", @@ -63,4 +65,4 @@ angular.module("cesium.config", []) "newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug" }) -; \ No newline at end of file +; diff --git a/www/plugins/es/i18n/locale-en-GB.json b/www/plugins/es/i18n/locale-en-GB.json index a8fcc0de4aa904f23dba696fe7e58458434bd086..5dfa7831a239ed1d98dbb661c2d060d060b5e3d3 100644 --- a/www/plugins/es/i18n/locale-en-GB.json +++ b/www/plugins/es/i18n/locale-en-GB.json @@ -361,12 +361,17 @@ "RESIZE_HELP": "<b>Re-crop the image</b> if necessary. A click on the image allows to move it. Click on the area at the bottom left to zoom in.", "RESULT_HELP": "<b>Here is the result</b> as seen on your profile:" }, + "MODAL_LOCATIONS": { + "TITLE": "Validation de l'adresse", + "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :" + }, "ERROR": { "LOAD_PROFILE_FAILED": "Could not load user profile.", "SAVE_PROFILE_FAILED": "Saving profile failed", "INVALID_SOCIAL_NETWORK_FORMAT": "Invalid format: please fill a valid Internet address.<br/><br/>Examples :<ul><li>- A Facebook page (https://www.facebook.com/user)</li><li>- A web page (http://www.domain.com)</li><li>- An email address (joe@dalton.com)</li></ul>", "IMAGE_RESIZE_FAILED": "Error while resizing picture", - "GEO_LOCATION_FAILED": "Unable to retrieve your current position" + "GEO_LOCATION_FAILED": "Unable to retrieve your current position", + "ADDRESS_LOCATION_FAILED": "Unable to retrieve the address position" }, "INFO": { "PROFILE_SAVED": "Profile saved" diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json index a8fcc0de4aa904f23dba696fe7e58458434bd086..5dfa7831a239ed1d98dbb661c2d060d060b5e3d3 100644 --- a/www/plugins/es/i18n/locale-en.json +++ b/www/plugins/es/i18n/locale-en.json @@ -361,12 +361,17 @@ "RESIZE_HELP": "<b>Re-crop the image</b> if necessary. A click on the image allows to move it. Click on the area at the bottom left to zoom in.", "RESULT_HELP": "<b>Here is the result</b> as seen on your profile:" }, + "MODAL_LOCATIONS": { + "TITLE": "Validation de l'adresse", + "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :" + }, "ERROR": { "LOAD_PROFILE_FAILED": "Could not load user profile.", "SAVE_PROFILE_FAILED": "Saving profile failed", "INVALID_SOCIAL_NETWORK_FORMAT": "Invalid format: please fill a valid Internet address.<br/><br/>Examples :<ul><li>- A Facebook page (https://www.facebook.com/user)</li><li>- A web page (http://www.domain.com)</li><li>- An email address (joe@dalton.com)</li></ul>", "IMAGE_RESIZE_FAILED": "Error while resizing picture", - "GEO_LOCATION_FAILED": "Unable to retrieve your current position" + "GEO_LOCATION_FAILED": "Unable to retrieve your current position", + "ADDRESS_LOCATION_FAILED": "Unable to retrieve the address position" }, "INFO": { "PROFILE_SAVED": "Profile saved" diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json index c4d28a409385d340d557e18d636847f3cc0092fd..0181266c1329187bf18cfd2265344fe9e03301af 100644 --- a/www/plugins/es/i18n/locale-fr-FR.json +++ b/www/plugins/es/i18n/locale-fr-FR.json @@ -402,12 +402,17 @@ "RESIZE_HELP": "<b>Recadrez l'image</b>, si besoin. Un clic maintenu sur l'image permet de la déplacer. Cliquez sur la zone en bas à gauche pour zoomer.", "RESULT_HELP": "<b>Voici le résultat</b> tel que visible sur votre profil :" }, + "MODAL_LOCATIONS": { + "TITLE": "Validation de l'addresse", + "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :" + }, "ERROR": { "LOAD_PROFILE_FAILED": "Erreur de chargement du profil utilisateur.", "SAVE_PROFILE_FAILED": "Erreur lors de la sauvegarde", "INVALID_SOCIAL_NETWORK_FORMAT": "Format non pris en compte : veuillez indiquer une adresse valide.<br/><br/>Exemples :<ul><li>- Une page Facebook (https://www.facebook.com/user)</li><li>- Une page web (http://www.monsite.fr)</li><li>- Une adresse email (joe@dalton.com)</li></ul>", "IMAGE_RESIZE_FAILED": "Erreur lors du redimensionnement de l'image", - "GEO_LOCATION_FAILED": "Impossible de récupérer votre position actuelle" + "GEO_LOCATION_FAILED": "Impossible de récupérer votre position actuelle", + "ADDRESS_LOCATION_FAILED": "Impossible de récupérer la position à partir de l'adresse" }, "INFO": { "PROFILE_SAVED": "Profil sauvegardé" diff --git a/www/plugins/es/js/controllers/common-controllers.js b/www/plugins/es/js/controllers/common-controllers.js index ed6aa01af5c0525d465a7443cfff44a98c1d7a1c..6ec8300080c03fa238d580422a590b4a17e8501c 100644 --- a/www/plugins/es/js/controllers/common-controllers.js +++ b/www/plugins/es/js/controllers/common-controllers.js @@ -80,6 +80,9 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) { $scope.categories = []; this.searchText = ''; + // modal title + this.title = parameters && parameters.title; + $scope.afterLoad = function(result) { $scope.categories = result; $scope.allCategories = result; @@ -118,6 +121,7 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) { }); } + } diff --git a/www/plugins/es/js/controllers/profile-controllers.js b/www/plugins/es/js/controllers/profile-controllers.js index 67a9d396836a0ef960f133acb880ebb13497f42c..0e53ff8c06e46de1e27f07632c7e3fe4ec1dc317 100644 --- a/www/plugins/es/js/controllers/profile-controllers.js +++ b/www/plugins/es/js/controllers/profile-controllers.js @@ -25,9 +25,12 @@ angular.module('cesium.es.profile.controllers', ['cesium.es.services']) ; function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $focus, $translate, $ionicHistory, - UIUtils, esHttp, esProfile, esGeo, ModalUtils, Device) { + csConfig, UIUtils, esHttp, esProfile, esGeo, ModalUtils, Device) { 'ngInject'; + // The default country used for address localisation + var defaultCountry = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.es.defaultCountry; + $scope.loading = true; $scope.dirty = false; $scope.walletData = null; @@ -313,27 +316,32 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $ $scope.localizeByAddress = function() { - return $scope.searchPositions() + return UIUtils.loading.show() + .then($scope.searchPositions) .then(function(res) { + UIUtils.loading.hide(); + if (!res) return; // no result, or city value just changed if (res.length == 1) { return res[0]; } return ModalUtils.show('plugins/es/templates/common/modal_category.html', 'ESCategoryModalCtrl as ctrl', - {categories : res}, + { + categories : res, + title: 'PROFILE.MODAL_LOCATIONS.TITLE' + }, {focusFirstInput: true} ); }) - .then(function(position) { - if (position && position.lat && position.lon) { + .then(function(res) { + if (res && res.lat && res.lon) { $scope.formData.geoPoint = $scope.formData.geoPoint || {}; - $scope.formData.geoPoint.lat = parseFloat(position.lat); - $scope.formData.geoPoint.lon = parseFloat(position.lon); - - //$scope.dirty = true; // not need ?? + $scope.formData.geoPoint.lat = parseFloat(res.lat); + $scope.formData.geoPoint.lon = parseFloat(res.lon); } - }); + }) + .catch(UIUtils.onError('PROFILE.ERROR.ADDRESS_LOCATION_FAILED')); }; $scope.searchPositions = function(query) { @@ -346,7 +354,8 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $ var cityPart = $scope.formData.city.split(','); var city = cityPart[0]; - var country = cityPart.length > 1 ? cityPart[1].trim() : undefined; + + var country = cityPart.length > 1 ? cityPart[1].trim() : defaultCountry; var street = $scope.formData.address ? angular.copy($scope.formData.address.trim()) : undefined; if (street) { // Search with AND without street @@ -373,23 +382,24 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $ } } + var queryString = (query.street ? query.street + ', ' : '') + + query.city + + (query.country ? ', ' + query.country : '') // Execute the given query - return esGeo.point.searchByAddress(query) + return $q.all([ + $translate('PROFILE.MODAL_LOCATIONS.RESULT_DIVIDER', {address: queryString}), + esGeo.point.searchByAddress(query) + ]) .then(function(res) { + var dividerText = res[0]; + res = res[1]; if (!res) return $q.when(); // no result // Ask user to choose - var index = 0; - var parent = {name: 'Résultat pour <b>' + - (query.street ? query.street + ', ' : '') + - query.city + - (query.country ? ', ' + query.country : '') + - '</b>', id: 0}; + var parent = {name: dividerText}; var hits = res.reduce(function(res, hit){ - index++; if (hit.class == 'waterway') return res; return res.concat({ - id: index, name: hit.display_name, parent: parent, lat: hit.lat, diff --git a/www/plugins/es/js/services/geo-services.js b/www/plugins/es/js/services/geo-services.js index e05efc3570a8c9388d5ac65adaefd2168886d62a..b92660f9a9feb6d33d480ed34527afe1d7f3305e 100644 --- a/www/plugins/es/js/services/geo-services.js +++ b/www/plugins/es/js/services/geo-services.js @@ -10,27 +10,61 @@ angular.module('cesium.es.geo.services', ['cesium.services', 'cesium.es.http.ser }) - .factory('esGeo', function($q, csHttp) { + .factory('esGeo', function($q, csConfig, csHttp) { 'ngInject'; var that = this; that.raw = { - searchByString: csHttp.get('nominatim.openstreetmap.org', 80, '/search.php?format=json&q=:query'), - searchByQuery: csHttp.get('nominatim.openstreetmap.org', 80, '/search.php?format=json'), + osm: { + searchByString: csHttp.get('nominatim.openstreetmap.org', 443, '/search.php?format=json&q=:query'), + searchByQuery: csHttp.get('nominatim.openstreetmap.org', 443, '/search.php?format=json') + }, + google: { + search: csHttp.get('maps.google.com', 443, '/maps/api/geocode/json') + }, searchByIP: csHttp.get('freegeoip.net', 80, '/json/:ip') }; - function searchPositionByString(queryString) { + function _fallbackSearchPositionByString(err, address) { + + console.debug('[ES] [geo] Search position failed on [OSM]. Trying [google] service'); + var apiKey = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.googleApiKey; + + return that.raw.google.search({address: address, key: apiKey}) + .then(function(res) { + if (!res || !res.results || !res.results.length) return; + return res.results.reduce(function(res, hit) { + return res.concat({ + display_name: hit.address_components && hit.address_components.reduce(function(res, address){ + return address.long_name ? res.concat(address.long_name) : res; + }, []).join(', '), + lat: hit.geometry && hit.geometry.location && hit.geometry.location.lat, + lon: hit.geometry && hit.geometry.location && hit.geometry.location.lng + }); + }, []); + }) + .catch(function() { + console.debug('[ES] [geo] Search position failed on [google] service'); + throw err; // throw first error (OMS error) + }); + } + + function searchPositionByString(address) { var now = new Date(); - console.debug('[ES] [geo] Searching position by string query [{0}]...'.format(queryString)); + console.debug('[ES] [geo] Searching position by string query [{0}]...'.format(address)); - return that.raw.searchByString({query: queryString}) + return that.raw.osm.searchByString({query: address}) .then(function(res) { console.debug('[ES] [geo] Found {0} address position(s) in {0}ms'.format(res && res.length || 0, new Date().getTime() - now.getTime())); return res; + }) + + // Fallback service + .catch(function(err) { + return _fallbackSearchPositionByString(err, address); }); } @@ -41,10 +75,16 @@ angular.module('cesium.es.geo.services', ['cesium.services', 'cesium.es.http.ser var now = new Date(); console.debug('[ES] [geo] Searching position by query...', query); - return that.raw.searchByQuery(query) + return that.raw.osm.searchByQuery(query) .then(function(res) { console.debug('[ES] [geo] Found {0} address position(s) in {0}ms'.format(res && res.length || 0, new Date().getTime() - now.getTime()), res); return res; + }) + + // Fallback service + .catch(function(err) { + var address = (query.street ? query.street +', ' : '') + query.city + (query.country ? ', '+ query.country : ''); + return _fallbackSearchPositionByString(err, address); }); } diff --git a/www/plugins/es/templates/common/modal_category.html b/www/plugins/es/templates/common/modal_category.html index bda21a8fafba0cde86b07a2c7b8e4e84dc104e0a..82045784b3688061562676674fc5bea0984c20bf 100644 --- a/www/plugins/es/templates/common/modal_category.html +++ b/www/plugins/es/templates/common/modal_category.html @@ -1,7 +1,7 @@ <ion-modal-view> <ion-header-bar class="bar-positive"> <button class="button button-clear" ng-click="closeModal()" translate>COMMON.BTN_CANCEL</button> - <h1 class="title" translate>COMMON.CATEGORIES</h1> + <h1 class="title" >{{ (ctrl.title || 'COMMON.CATEGORIES') | translate}}</h1> </ion-header-bar> <ion-content class="categoryModal"> diff --git a/www/plugins/es/templates/user/edit_profile.html b/www/plugins/es/templates/user/edit_profile.html index 0dc08b5e514741c84ef84541a82d213ea83cfe5a..7fc1f170b2c79b9ce6dcdafa903f043f5b4e9622 100644 --- a/www/plugins/es/templates/user/edit_profile.html +++ b/www/plugins/es/templates/user/edit_profile.html @@ -142,7 +142,7 @@ </label> </div> - <div class="col no-padding"> + <div class="col col-40 no-padding"> <div class="item no-padding text-center"> <span class="input-label"></span> diff --git a/www/plugins/map/i18n/locale-en-GB.json b/www/plugins/map/i18n/locale-en-GB.json index 4d23c5c79d9b9f615c470459e2bdf36963304c18..e25af76ebab057bb6e322c5da639aac80405d7db 100644 --- a/www/plugins/map/i18n/locale-en-GB.json +++ b/www/plugins/map/i18n/locale-en-GB.json @@ -26,6 +26,7 @@ "TITLE": "Members map", "LAYER": { "MEMBER": "Members", + "PENDING": "Pending registrations", "WALLET": "Simple wallets" } } diff --git a/www/plugins/map/i18n/locale-en.json b/www/plugins/map/i18n/locale-en.json index 4d23c5c79d9b9f615c470459e2bdf36963304c18..e25af76ebab057bb6e322c5da639aac80405d7db 100644 --- a/www/plugins/map/i18n/locale-en.json +++ b/www/plugins/map/i18n/locale-en.json @@ -26,6 +26,7 @@ "TITLE": "Members map", "LAYER": { "MEMBER": "Members", + "PENDING": "Pending registrations", "WALLET": "Simple wallets" } } diff --git a/www/plugins/map/i18n/locale-fr-FR.json b/www/plugins/map/i18n/locale-fr-FR.json index 4083d3d55a1b7e8b927536b7d1ca142f734a052f..7433568d28fcb7c6fb910477e32ebe39f5986320 100644 --- a/www/plugins/map/i18n/locale-fr-FR.json +++ b/www/plugins/map/i18n/locale-fr-FR.json @@ -24,9 +24,9 @@ }, "VIEW": { "TITLE": "Carte des membres", - "SEARCH_DOTS": "Rechercher...", "LAYER": { "MEMBER": "Membres", + "PENDING": "Inscriptions en attente", "WALLET": "Simples portefeuilles" } } diff --git a/www/plugins/map/js/controllers/network-controllers.js b/www/plugins/map/js/controllers/network-controllers.js index f511a09b4f1547710694af497e49a43381af82ab..a6b8b21f47a6a3bfb6df774f99eef5a02c1e9805 100644 --- a/www/plugins/map/js/controllers/network-controllers.js +++ b/www/plugins/map/js/controllers/network-controllers.js @@ -215,9 +215,9 @@ angular.module('cesium.map.network.controllers', ['cesium.services', 'cesium.map // Create a search marker (will be hide) var searchServer = peer.dns || peer.server; var searchText = searchServer + - (peer.uid ? (' | ' + peer.name||peer.uid) : '') + + (peer.uid ? (' | ' + (peer.name||peer.uid)) : '') + ' | ' + formatPubkey(peer.pubkey); - var searchIp;; + var searchIp; if (bma.ipv4 && !(peer.dns || peer.server).startsWith(bma.ipv4)) { searchIp = bma.ipv4; searchText += ' | ' + bma.ipv4; diff --git a/www/plugins/map/js/controllers/wot-controllers.js b/www/plugins/map/js/controllers/wot-controllers.js index a5dc55dd1b69aeb8c7f396e16087f20d29651b83..89c69ba62f73536039958fb00db7f7e9127a1a44 100644 --- a/www/plugins/map/js/controllers/wot-controllers.js +++ b/www/plugins/map/js/controllers/wot-controllers.js @@ -47,6 +47,12 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser icon: 'person', markerColor: 'blue' }, + pending: { + type: 'awesomeMarker', + icon: 'clock', + markerColor: 'lightgreen', + iconColor: 'gray' + }, wallet: { type: 'awesomeMarker', icon: 'key', @@ -69,14 +75,19 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser $scope.map = MapUtils.map({ layers: { overlays: { - wallet: { + member: { type: 'group', - name: 'MAP.WOT.VIEW.LAYER.WALLET', + name: 'MAP.WOT.VIEW.LAYER.MEMBER', visible: true }, - member: { + pending: { type: 'group', - name: 'MAP.WOT.VIEW.LAYER.MEMBER', + name: 'MAP.WOT.VIEW.LAYER.PENDING', + visible: true + }, + wallet: { + type: 'group', + name: 'MAP.WOT.VIEW.LAYER.WALLET', visible: true } } @@ -163,13 +174,13 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser });*/ _.forEach(res, function (hit) { - var type = hit.uid ? 'member' : 'wallet'; - var shortPubkey = formatPubkey(hit.issuer); + var type = hit.pending ? 'pending' : (hit.uid ? 'member' : 'wallet'); + var shortPubkey = formatPubkey(hit.pubkey); var marker = { layer: type, icon: icons[type], - opacity: 0.8, - title: hit.title + ' | ' + shortPubkey, + opacity: hit.uid ? 1 : 0.7, + title: hit.name + ' | ' + shortPubkey, lat: hit.geoPoint.lat, lng: hit.geoPoint.lon, getMessageScope: function () { @@ -180,11 +191,11 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser focus: false, message: markerTemplate }; - var id = hit.uid ? (hit.uid + ':' + hit.issuer) : hit.issuer; + var id = hit.uid ? (hit.uid + ':' + hit.pubkey) : hit.pubkey; $scope.map.markers[id] = marker; // Create a search marker (will be hide) - var searchText = hit.title + ((hit.uid && hit.uid != hit.title) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey; + var searchText = hit.name + ((hit.uid && hit.uid != hit.name) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey; var searchMarker = angular.merge({ type: type, opacity: 0, @@ -192,7 +203,7 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser className: type + ' ng-hide', iconSize: L.point(0, 0) }) - }, {title: searchText, issuer: hit.issuer, uid: hit.uid, name: hit.title}); + }, {title: searchText, pubkey: hit.pubkey, uid: hit.uid, name: hit.name, pending: hit.pending}); markersSearchLayer.addLayer(new L.Marker({ lat: hit.geoPoint.lat, lng: hit.geoPoint.lon diff --git a/www/plugins/map/js/services.js b/www/plugins/map/js/services.js index 02aec430c30330b0372f5f5479769c44041d0482..5e8cad2b4b4d9f97f239ba43ac83ba14dc8e50c0 100644 --- a/www/plugins/map/js/services.js +++ b/www/plugins/map/js/services.js @@ -2,7 +2,6 @@ angular.module('cesium.map.services', [ // Services 'cesium.map.wot.services', - 'cesium.map.network.services', 'cesium.map.utils.services' ]) ; diff --git a/www/plugins/map/js/services/network-services.js b/www/plugins/map/js/services/network-services.js deleted file mode 100644 index 5b48ba35a88b2e5a3de7dc16c664191d278c417d..0000000000000000000000000000000000000000 --- a/www/plugins/map/js/services/network-services.js +++ /dev/null @@ -1,60 +0,0 @@ - -angular.module('cesium.map.network.services', ['cesium.services']) - -.factory('mapNetwork', function(csHttp, esHttp, csNetwork) { - 'ngInject'; - - var - that = this, - constants = { - DEFAULT_LOAD_SIZE: 1000 - }, - fields = { - profile: ["issuer", "title", "description", "geoPoint"] - }; - - that.raw = { - - }; - - function load(options) { - - csNetwork.start() - var request = { - query: createFilterQuery(options), - from: options.from, - size: options.size, - _source: fields.profile - }; - - return that.raw.profile.postSearch(request) - .then(function(res) { - if (!res.hits || !res.hits.total) return []; - - var commaRegexp = new RegExp('[,]'); - - res = res.hits.hits.reduce(function(res, hit) { - var item = hit._source; - - if (!item.geoPoint || !item.geoPoint.lat || !item.geoPoint.lon) return res; - - // Convert lat/lon to float (if need) - if (item.geoPoint.lat && typeof item.geoPoint.lat === 'string') { - item.geoPoint.lat = parseFloat(item.geoPoint.lat.replace(commaRegexp, '.')); - } - if (item.geoPoint.lon && typeof item.geoPoint.lon === 'string') { - item.geoPoint.lon = parseFloat(item.geoPoint.lon.replace(commaRegexp, '.')); - } - - return res.concat(item); - }, []); - - return csWot.extendAll(res, 'issuer'); - }); - } - - return { - load: load - }; - -}); diff --git a/www/plugins/map/js/services/utils-services.js b/www/plugins/map/js/services/utils-services.js index 1e19a0c8b2756888faf2ef9f670e081317cf0e46..406a1ce1afa6d9290d823e9f6ead3aa7fece5559 100644 --- a/www/plugins/map/js/services/utils-services.js +++ b/www/plugins/map/js/services/utils-services.js @@ -1,10 +1,13 @@ angular.module('cesium.map.utils.services', ['cesium.services', 'ui-leaflet']) -.factory('MapUtils', function($timeout, $q, $translate, leafletData, csSettings, esGeo, UIUtils, leafletHelpers) { +.factory('MapUtils', function($timeout, $q, $translate, leafletData, csConfig, csSettings, esGeo, UIUtils, leafletHelpers) { 'ngInject'; - var constants = { + + var + googleApiKey = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.es.googleApiKey; + constants = { locations: { FRANCE: { lat: 46.5588603, lng: 4.229736328124999, zoom: 6 @@ -22,10 +25,25 @@ angular.module('cesium.map.utils.services', ['cesium.services', 'ui-leaflet']) }, layers: { baselayers: { - openStreetMap: { + osm: { name: 'OpenStreetMap', type: 'xyz', - url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' + url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + layerOptions: { + subdomains: ["a", "b", "c"], + attribution: "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>", + continuousWorld: true + } + }, + cycle: { + name: "Google map", + type: "xyz", + url: 'http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&key='+googleApiKey, + layerOptions: { + subdomains: ['mt0','mt1','mt2','mt3'], + attribution: "© <a href=\"http://google.com/copyright\">Google</a>", + continuousWorld: true + } } } }, diff --git a/www/plugins/map/js/services/wot-services.js b/www/plugins/map/js/services/wot-services.js index 264099f25eba85ede15d2af25368cbe333e61e66..1e97a6d753dcef9213fb43fd837e61568c3a2297 100644 --- a/www/plugins/map/js/services/wot-services.js +++ b/www/plugins/map/js/services/wot-services.js @@ -1,7 +1,7 @@ angular.module('cesium.map.wot.services', ['cesium.services']) -.factory('mapWot', function(csHttp, esHttp, csWot) { +.factory('mapWot', function($q, csHttp, esHttp, csWot, BMA) { 'ngInject'; var @@ -10,7 +10,7 @@ angular.module('cesium.map.wot.services', ['cesium.services']) DEFAULT_LOAD_SIZE: 1000 }, fields = { - profile: ["issuer", "title", "description", "geoPoint"] + profile: ["title", "geoPoint", "avatar._content_type"] }; that.raw = { @@ -43,15 +43,51 @@ angular.module('cesium.map.wot.services', ['cesium.services']) _source: fields.profile }; - return that.raw.profile.postSearch(request) + return $q.all([ + that.raw.profile.postSearch(request), + BMA.wot.member.uids(), + BMA.wot.member.pending() + .then(function(res) { + return (res.memberships && res.memberships.length) ? res.memberships : []; + }) + ]) .then(function(res) { + var uids = res[1]; + var memberships = res[2]; + var res = res[0]; if (!res.hits || !res.hits.total) return []; - var commaRegexp = new RegExp('[,]'); + // Transform pending MS into a map by pubkey + memberships = memberships.reduce(function(res, ms){ + if (ms.membership == 'IN' && !uids[ms.pubkey]) { + var idty = { + uid: ms.uid, + pubkey: ms.pubkey, + block: ms.blockNumber, + blockHash: ms.blockHash, + pending: true + }; + var otherIdtySamePubkey = res[ms.pubkey]; + if (otherIdtySamePubkey && idty.block > otherIdtySamePubkey.block) { + return res; // skip + } + res[idty.pubkey] = idty; + } + return res; + }, {}); + + // Transform profile hits + var commaRegexp = new RegExp('[,]'); res = res.hits.hits.reduce(function(res, hit) { - var item = hit._source; + var pubkey = hit._id; + + var uid = uids[pubkey]; + var item = uid && {uid: uid} || memberships[pubkey] || {}; + item.pubkey = pubkey; + // Set geo point + item.geoPoint = hit._source.geoPoint; if (!item.geoPoint || !item.geoPoint.lat || !item.geoPoint.lon) return res; // Convert lat/lon to float (if need) @@ -62,13 +98,25 @@ angular.module('cesium.map.wot.services', ['cesium.services']) item.geoPoint.lon = parseFloat(item.geoPoint.lon.replace(commaRegexp, '.')); } + // Avatar + item.avatar = esHttp.image.fromHit(hit, 'avatar'); + + // Name + item.name = hit._source.title; + // Avoid too long name (workaround for #308) + if (item.name && item.name.length > 30) { + item.name = item.name.substr(0, 27) + '...'; + } + console.log(item); + return res.concat(item); }, []); - return csWot.extendAll(res, 'issuer'); + return csWot.extendAll(res, 'pubkey'); }); } + return { load: load }; diff --git a/www/plugins/map/templates/wot/item_search_tooltip.html b/www/plugins/map/templates/wot/item_search_tooltip.html index 94800b3bd049d43fcca4a7fb6f236e0397b85c07..88e9dcf2fb158d9d832d525e710687f346558290 100644 --- a/www/plugins/map/templates/wot/item_search_tooltip.html +++ b/www/plugins/map/templates/wot/item_search_tooltip.html @@ -1,7 +1,8 @@ <a href="#" class="{{type}}"> + <i class="{{pending ? 'ion-clock': ''}}"></i> {{name != uid ? name +' ' : ''}} <span class="{{uid ? 'positive' : 'gray'}}"> - <i class="icon {{uid ? 'ion-person' : 'ion-key'}}"></i> - {{uid ? uid : (issuer|formatPubkey) }} + <i class="{{uid ? 'ion-person' : 'ion-key'}}"></i> + {{uid ? uid : (pubkey|formatPubkey) }} </span> </a> diff --git a/www/plugins/map/templates/wot/popup_marker.html b/www/plugins/map/templates/wot/popup_marker.html index 7e31eecb1861814fa30689a0b2f244ba0867f726..9145a95e47b26ab907fe652d3fc97bf732bb066b 100644 --- a/www/plugins/map/templates/wot/popup_marker.html +++ b/www/plugins/map/templates/wot/popup_marker.html @@ -1,10 +1,11 @@ -<div class="item no-border no-padding" ng-class="::{'item-avatar': hit.avatar}"> - <img ng-if="::hit.avatar" class="avatar" ng-src="{{::hit.avatar.src}}"> +<div class="item no-border no-padding item-avatar" ng-class="::{'item-avatar': hit.avatar}"> + <img ng-if="::hit.avatar" class="item-image avatar" ng-src="{{::hit.avatar.src}}"> + <i ng-if="::!hit.avatar" class="item-image icon " ng-class="::{'ion-person': hit.uid, 'ion-card': !hit.uid}"></i> <div class="item-content item-avatar-left-padding padding-top"> - <h2 class="dark"><a ui-sref="app.wot_identity({pubkey: hit.issuer, uid: hit.uid})">{{::hit.title}}</a></h2> + <h2 class="dark"><a ui-sref="app.wot_identity({pubkey: hit.pubkey, uid: hit.uid})">{{::hit.name}}</a></h2> <h4> <span ng-if="::hit.uid" class="positive"> - <i class="icon ion-person"></i> + <b class="ion-person"></b> {{::hit.uid}} </span> <span class="assertive" ng-if="!hit.uid"> @@ -12,7 +13,7 @@ </span> </h4> <h4> - <span class="gray" title="{{::hit.issuer}}"><i class="icon ion-key"></i> {{::hit.issuer|formatPubkey}}</span> + <span class="gray" title="{{::hit.pubkey}}"><b class="ion-key"></b> {{::hit.pubkey|formatPubkey}}</span> </h4> </div> </div>