diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js index 32030a16e72afbf1496321986aed1b75ba89e035..d18a1c745cd043dbb1cd135562ecdb178a12d40f 100644 --- a/www/js/services/http-services.js +++ b/www/js/services/http-services.js @@ -34,7 +34,10 @@ angular.module('cesium.http.services', ['cesium.cache.services']) reject(data); } else { - if (status == 404) { + if (status == 403) { + reject({ucode: 403, message: 'Resource is forbidden' + (url ? ' ('+url+')' : '')}); + } + else if (status == 404) { reject({ucode: 404, message: 'Resource not found' + (url ? ' ('+url+')' : '')}); } else if (url) { diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json index 57bb466013dbd02c2ca4dfd74413ba42059b3c1b..5e7de547fead47beff1b17e04764ecef7fe821dd 100644 --- a/www/plugins/es/i18n/locale-fr-FR.json +++ b/www/plugins/es/i18n/locale-fr-FR.json @@ -394,12 +394,14 @@ "RESULT_HELP": "<b>Voici le résultat</b> tel que visible sur votre profil :" }, "CONFIRM": { - "DELETE": "Êtes-vous sûr de vouloir <b>supprimer votre profil Cesium+ ?</b><br/><br/>Cette opération est irréversible." + "DELETE": "Êtes-vous sûr de vouloir <b>supprimer votre profil Cesium+ ?</b><br/><br/>Cette opération est irréversible.", + "DELETE_BY_MODERATOR": "Êtes-vous sûr de vouloir <b>supprimer ce profil Cesium+ ?</b><br/><br/>Cette opération est irréversible." }, "ERROR": { "REMOVE_PROFILE_FAILED": "Erreur de suppression du profil", - "LOAD_PROFILE_FAILED": "Erreur de chargement du profil utilisateur", + "LOAD_PROFILE_FAILED": "Erreur de chargement du profil", "SAVE_PROFILE_FAILED": "Erreur lors de la sauvegarde", + "DELETE_PROFILE_FAILED": "Erreur lors de la suppression du profil", "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" }, diff --git a/www/plugins/es/js/controllers/invitation-controllers.js b/www/plugins/es/js/controllers/invitation-controllers.js index d892791ea0ab3fc8331c36c6db5d840970846710..a494604977f42318a9fafc1c972eda6cc457b36c 100644 --- a/www/plugins/es/js/controllers/invitation-controllers.js +++ b/www/plugins/es/js/controllers/invitation-controllers.js @@ -110,7 +110,7 @@ function InvitationsController($scope, $q, $ionicPopover, $state, $timeout, UIUt UIUtils.loading.hide(); }) .catch(function(err) { - if (err == 'CANCELLED') return $scope.cancel(); + if (err === 'CANCELLED') return $scope.cancel(); $scope.search.loading = false; if (!from) { $scope.search.results = []; diff --git a/www/plugins/es/js/controllers/wot-controllers.js b/www/plugins/es/js/controllers/wot-controllers.js index fe5ac90c9bf13a9ef8961bf04742e8dfc1975717..fe42edd9013f0a451fffe0dc6ee76d4cae5abed6 100644 --- a/www/plugins/es/js/controllers/wot-controllers.js +++ b/www/plugins/es/js/controllers/wot-controllers.js @@ -97,7 +97,7 @@ function ESWotLookupExtendController($scope, $controller, $state) { }; } -function ESWotIdentityViewController($scope, $ionicPopover, $q, $controller, UIUtils, Modals, csWallet, +function ESWotIdentityViewController($scope, $ionicPopover, $q, $controller, $timeout, UIUtils, Modals, csWallet, esHttp, esLike, esModals, esWallet, esProfile, esInvitation) { 'ngInject'; @@ -116,7 +116,7 @@ function ESWotIdentityViewController($scope, $ionicPopover, $q, $controller, UIU // Initialize the super class and extend it. angular.extend(this, $controller('ESExtensionCtrl', {$scope: $scope})); - $scope.canCertify = false; // disable certity on the popover (by default - override by the wot map controller) + $scope.canCertify = false; // disable certify on the popover (by default - override by the wot map controller) /* -- modals -- */ @@ -311,13 +311,46 @@ function ESWotIdentityViewController($scope, $ionicPopover, $q, $controller, UIU }); }; - /* -- likes -- */ + $scope.delete = function(confirm) { - // Load likes, when profile loaded + if (!confirm) { + $scope.hideActionsPopover(); + if (!$scope.formData.pubkey) return; // Skip + + return UIUtils.alert.confirm('PROFILE.CONFIRM.DELETE_BY_MODERATOR') + .then(function(confirm) { + if (confirm) return $scope.delete(confirm); // recursive call + }); + } + + return UIUtils.loading.show() + .then(function() { + return esProfile.remove($scope.formData.pubkey); + }) + .then(function() { + return $scope.doUpdate(); + }) + .then(function() { + return $timeout(function() { + UIUtils.toast.show('DOCUMENT.INFO.REMOVED'); // toast + }, 800); + }) + .catch(UIUtils.onError("PROFILE.ERROR.DELETE_PROFILE_FAILED")); + }; + + /* -- Load data -- */ + + // Watch when profile loaded $scope.$watch('formData.pubkey', function(pubkey) { if (pubkey) { + + // Load likes, $scope.loadLikes(pubkey); + + // Update moderator right + $scope.canDelete = $scope.formData.profile && csWallet.isLogin() && csWallet.data.moderator === true; } + }); /* -- Popover -- */ diff --git a/www/plugins/es/js/services/http-services.js b/www/plugins/es/js/services/http-services.js index 6c900d376dc67b3a7c3e498772ec19c5b5fb8f5e..8e652c6edaf0e5ee3951a04ad2d272f412ed0797 100644 --- a/www/plugins/es/js/services/http-services.js +++ b/www/plugins/es/js/services/http-services.js @@ -749,6 +749,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic getServer: csHttp.getServer, node: { summary: that.get('/node/summary'), + moderators: that.get('/node/moderators'), parseEndPoint: parseEndPoint, same: isSameNode, sameAsSettings: isSameNodeAsSettings, diff --git a/www/plugins/es/js/services/profile-services.js b/www/plugins/es/js/services/profile-services.js index 0addced2f8788f993ea60a588fd20f39e4dae0b6..c4e05f72d60ce5817e583bf80227d58e094bd120 100644 --- a/www/plugins/es/js/services/profile-services.js +++ b/www/plugins/es/js/services/profile-services.js @@ -319,6 +319,8 @@ angular.module('cesium.es.profile.services', ['cesium.services', 'cesium.es.http return deferred.promise; } + console.debug("[ES] [profile] Extending identity {{0}} ...".format(data.pubkey.substr(0,8))); + $q.all([ // Load full profile getProfile(data.pubkey) @@ -326,8 +328,13 @@ angular.module('cesium.es.profile.services', ['cesium.services', 'cesium.es.http if (profile) { data.name = profile.name; data.avatar = profile.avatar; - data.profile = profile.source; - data.profile.description = profile.description; + data.profile = data.profile || {}; + angular.merge(data.profile, profile.source, {descriptionHtml: profile.descriptionHtml}); + } + else { + data.name = null; + data.avatar = null; + data.profile = null; } deferred.resolve(data); }), @@ -383,8 +390,8 @@ angular.module('cesium.es.profile.services', ['cesium.services', 'cesium.es.http return { getAvatarAndName: getAvatarAndName, get: getProfile, - add: esHttp.record.post('/user/profile', {tagFields: ['title', 'description'], ignoreFields: ['enableGeoPoint', 'descriptionHtml']}), - update: esHttp.record.post('/user/profile/:id/_update', {tagFields: ['title', 'description'], ignoreFields: ['enableGeoPoint', 'descriptionHtml']}), + add: esHttp.record.post('/user/profile', {tagFields: ['title', 'description'], ignoreFields: ['enableGeoPoint', 'descriptionHtml', 'moderator']}), + update: esHttp.record.post('/user/profile/:id/_update', {tagFields: ['title', 'description'], ignoreFields: ['enableGeoPoint', 'descriptionHtml', 'moderator']}), remove: esHttp.record.remove("user","profile"), avatar: esHttp.get('/user/profile/:id?_source=avatar'), fillAvatars: fillAvatars, diff --git a/www/plugins/es/js/services/wallet-services.js b/www/plugins/es/js/services/wallet-services.js index d8ebc0e5c9a88856b5f00fa2304e6c997ec5805b..98dafc1862f9db8502cd751e1ae4c2bfe7a95116 100644 --- a/www/plugins/es/js/services/wallet-services.js +++ b/www/plugins/es/js/services/wallet-services.js @@ -1,6 +1,6 @@ angular.module('cesium.es.wallet.services', ['ngResource', 'cesium.platform', 'cesium.es.http.services', 'cesium.es.crypto.services']) - .factory('esWallet', function($q, $rootScope, $timeout, CryptoUtils, csPlatform, csWallet, esCrypto, esProfile, esHttp) { + .factory('esWallet', function($q, $rootScope, $timeout, CryptoUtils, csPlatform, csWallet, csSettings, esCrypto, esProfile, esHttp) { 'ngInject'; var @@ -8,9 +8,10 @@ angular.module('cesium.es.wallet.services', ['ngResource', 'cesium.platform', 'c that = this; function onWalletReset(data) { + data.name = null; data.avatar = null; data.profile = null; - data.name = null; + data.moderator = null; csWallet.events.cleanByContext('esWallet'); if (data.keypair) { delete data.keypair.boxSk; @@ -28,7 +29,8 @@ angular.module('cesium.es.wallet.services', ['ngResource', 'cesium.platform', 'c data.keypair.boxPk = res.boxPk; console.debug("[ES] [wallet] Box keypair successfully computed"); deferred.resolve(); - }); + }) + .catch(deferred.reject); return deferred.promise; } @@ -58,20 +60,40 @@ angular.module('cesium.es.wallet.services', ['ngResource', 'cesium.platform', 'c console.debug('[ES] [wallet] Loading user avatar+name...'); var now = Date.now(); - esProfile.getAvatarAndName(data.pubkey) - .then(function(profile) { - if (profile) { - data.name = profile.name; - data.avatarStyle = profile.avatarStyle; - data.avatar = profile.avatar; - console.debug('[ES] [wallet] Loaded user avatar+name in '+ (Date.now()-now) +'ms'); - } - else { - console.debug('[ES] [wallet] No user avatar+name found'); - } - deferred.resolve(data); - }) - .catch(deferred.reject); + var jobs = [ + esProfile.getAvatarAndName(data.pubkey) + .then(function(profile) { + if (profile) { + data.name = profile.name; + data.avatarStyle = profile.avatarStyle; + data.avatar = profile.avatar; + console.debug('[ES] [wallet] Loaded user avatar+name in '+ (Date.now()-now) +'ms'); + } + else { + console.debug('[ES] [wallet] No user avatar+name found'); + } + deferred.resolve(data); + }) + ]; + + // Check if user is a moderators (only if expert mode) + if (csSettings.data.expertMode) { + jobs.push(esHttp.node.moderators() + .then(function(res) { + data.moderator = _.contains(res && res.moderators, data.pubkey); + }) + .catch(function(err) { + console.error("[ES] [wallet] Cannot check is user is moderator: ", (err && err.message || err)); + // Continue + }) + ); + } + + $q.all(jobs) + .then(function() { + deferred.resolve(data); + }) + .catch(deferred.reject); return deferred.promise; } @@ -102,7 +124,7 @@ angular.module('cesium.es.wallet.services', ['ngResource', 'cesium.platform', 'c } deferred.resolve(data); }) - .catch(deferred.reject); + .catch(deferred.reject); return deferred.promise; } diff --git a/www/plugins/es/templates/user/edit_profile.html b/www/plugins/es/templates/user/edit_profile.html index 1c5e26ee52d9c69498bdcf422148a4b5c44dbdbc..3bc148378277044650880bee57607e6bdc058987 100644 --- a/www/plugins/es/templates/user/edit_profile.html +++ b/www/plugins/es/templates/user/edit_profile.html @@ -52,9 +52,10 @@ <div class="col"> <!-- Buttons bar--> - <div class="hidden-xs hidden-sm padding text-center" ng-if="existing && !saving"> + <div class="hidden-xs hidden-sm padding text-center animate-show-hide ng-hide" ng-show="existing"> <button class="button button-stable icon-right ink" + ng-disabled="saving" ng-click="showActionsPopover($event)"> <i class="icon ion-android-more-vertical"></i> {{'COMMON.BTN_OPTIONS' | translate}} diff --git a/www/plugins/es/templates/wot/view_popover_actions.html b/www/plugins/es/templates/wot/view_popover_actions.html index c3ba6ad5f683a8fba1423dc29d766c1fe35e1a12..b080a58c7a70e56f1705bf9d45b5af79ac045050 100644 --- a/www/plugins/es/templates/wot/view_popover_actions.html +++ b/www/plugins/es/templates/wot/view_popover_actions.html @@ -11,12 +11,12 @@ {{'COMMON.BTN_SHARE' | translate}} </a> - <!--<a class="item item-icon-left assertive ink " - ng-if="canEdit" + <a class="item item-icon-left assertive ink " + ng-if="canDelete" ng-click="delete()"> <i class="icon ion-trash-a"></i> {{'COMMON.BTN_DELETE' | translate}} - </a>--> + </a> <!-- Like --> <a class="item item-icon-left ink"