From dfc904f4f30e96479f41cd397a1524b971e2d14c Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 21 Jun 2016 21:29:44 -0400 Subject: [PATCH] (js) Never query Gravatar.com when disabled --- NEWS | 1 + UI/Templates/PreferencesUI/UIxPreferences.wox | 2 + .../img/ic_person_grey_24px.svg | 4 ++ UI/WebServerResources/js/Common/Common.app.js | 3 ++ .../js/Common/User.service.js | 7 ++-- .../js/Contacts/Card.service.js | 5 +-- .../js/Mailer/Message.service.js | 22 ++++------- .../js/Preferences/Preferences.service.js | 37 ++++++++++++++++--- .../js/Preferences/PreferencesController.js | 19 +++++++++- .../scss/components/chips/chips.scss | 3 +- 10 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 UI/WebServerResources/img/ic_person_grey_24px.svg diff --git a/NEWS b/NEWS index 08d66c4ae..c3667f995 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,7 @@ Bug fixes - [web] fixed handling of attendees when updating an event - [web] show tooltips over long calendar/ab names (#232) - [web] one-click option to give all permissions for user (#1637) + - [web] never query gravatar.com when disabled 3.1.2 (2016-06-06) ------------------ diff --git a/UI/Templates/PreferencesUI/UIxPreferences.wox b/UI/Templates/PreferencesUI/UIxPreferences.wox index e313289fd..9d1f51b16 100644 --- a/UI/Templates/PreferencesUI/UIxPreferences.wox +++ b/UI/Templates/PreferencesUI/UIxPreferences.wox @@ -445,12 +445,14 @@ diff --git a/UI/WebServerResources/img/ic_person_grey_24px.svg b/UI/WebServerResources/img/ic_person_grey_24px.svg new file mode 100644 index 000000000..ada722383 --- /dev/null +++ b/UI/WebServerResources/img/ic_person_grey_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/UI/WebServerResources/js/Common/Common.app.js b/UI/WebServerResources/js/Common/Common.app.js index 51054e169..9fdbbe742 100644 --- a/UI/WebServerResources/js/Common/Common.app.js +++ b/UI/WebServerResources/js/Common/Common.app.js @@ -9,6 +9,9 @@ baseURL: function() { return ApplicationBaseURL || null; }, + resourcesURL: function() { + return ResourcesURL || null; + }, activeUser: function(param) { var settings = { login: UserLogin || null, diff --git a/UI/WebServerResources/js/Common/User.service.js b/UI/WebServerResources/js/Common/User.service.js index 8d8597d2d..ac97426a0 100644 --- a/UI/WebServerResources/js/Common/User.service.js +++ b/UI/WebServerResources/js/Common/User.service.js @@ -17,12 +17,11 @@ * @desc The factory we'll use to register with Angular. * @return the User constructor */ - User.factory = ['$q', '$log', 'sgSettings', 'Resource', 'Gravatar', function($q, $log, Settings, Resource, Gravatar) { + User.factory = ['$q', '$log', 'sgSettings', 'Resource', function($q, $log, Settings, Resource) { angular.extend(User, { $q: $q, $log: $log, $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()), - $gravatar: Gravatar, $query: '', $users: [] }); @@ -114,7 +113,9 @@ if (!this.$$shortFormat) this.$$shortFormat = this.$shortFormat(); if (!this.$$image) - this.$$image = this.image || User.$gravatar(this.c_email, 32, User.$alternateAvatar, {no_404: true}); + this.$$image = this.image; + // NOTE: We can't assign a Gravatar at this stage since we would need the Preferences module + // which already depend on the User module. // An empty attribute to trick md-autocomplete when adding users from the ACLs editor this.empty = ' '; diff --git a/UI/WebServerResources/js/Contacts/Card.service.js b/UI/WebServerResources/js/Contacts/Card.service.js index ef88ce7b5..61b9bbf61 100644 --- a/UI/WebServerResources/js/Contacts/Card.service.js +++ b/UI/WebServerResources/js/Contacts/Card.service.js @@ -38,12 +38,11 @@ * @desc The factory we'll use to register with Angular. * @returns the Card constructor */ - Card.$factory = ['$timeout', 'sgSettings', 'sgCard_STATUS', 'Resource', 'Preferences', 'Gravatar', function($timeout, Settings, Card_STATUS, Resource, Preferences, Gravatar) { + Card.$factory = ['$timeout', 'sgSettings', 'sgCard_STATUS', 'Resource', 'Preferences', function($timeout, Settings, Card_STATUS, Resource, Preferences) { angular.extend(Card, { STATUS: Card_STATUS, $$resource: new Resource(Settings.activeUser('folderURL') + 'Contacts', Settings.activeUser()), $timeout: $timeout, - $gravatar: Gravatar, $Preferences: Preferences }); // Initialize categories from user's defaults @@ -146,7 +145,7 @@ if (!this.$$email) this.$$email = this.$preferredEmail(partial); if (!this.$$image) - this.$$image = this.image || Card.$gravatar(this.$preferredEmail(partial), 32, Card.$alternateAvatar, {no_404: true}); + this.$$image = this.image || Card.$Preferences.avatar(this.$$email, 32, {no_404: true}); if (this.isgroup) this.c_component = 'vlist'; this.$loaded = angular.isDefined(this.c_name)? Card.STATUS.LOADED : Card.STATUS.NOT_LOADED; diff --git a/UI/WebServerResources/js/Mailer/Message.service.js b/UI/WebServerResources/js/Mailer/Message.service.js index 2b578e48f..184aa8261 100644 --- a/UI/WebServerResources/js/Mailer/Message.service.js +++ b/UI/WebServerResources/js/Mailer/Message.service.js @@ -39,14 +39,14 @@ * @desc The factory we'll use to register with Angular * @returns the Message constructor */ - Message.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'sgMessage_STATUS', 'Gravatar', 'Resource', 'Preferences', function($q, $timeout, $log, Settings, Message_STATUS, Gravatar, Resource, Preferences) { + Message.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'sgMessage_STATUS', 'Resource', 'Preferences', function($q, $timeout, $log, Settings, Message_STATUS, Resource, Preferences) { angular.extend(Message, { STATUS: Message_STATUS, $q: $q, $timeout: $timeout, $log: $log, - $gravatar: Gravatar, - $$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()) + $$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()), + $avatar: angular.bind(Preferences, Preferences.avatar) }); // Initialize tags form user's defaults Preferences.ready().then(function() { @@ -172,7 +172,7 @@ * @function $formatFullAddresses * @memberof Message.prototype * @desc Format all sender and recipients addresses with a complete description (name ). - * This function also generates a gravatar for each email address, and a short name + * This function also generates the avatar URL for each email address and a short name */ Message.prototype.$formatFullAddresses = function() { var _this = this; @@ -188,16 +188,15 @@ // Name is already short data.shortname = data.name; else if (data.name.split(' ').length) - // If we have "Alice Foo" as name, we grab "Alice" - data.shortname = data.name.split(' ')[0].replace('\'',''); + // If we have "Alice Foo" or "Foo, Alice" as name, we grab "Alice" + data.shortname = _.first(_.last(data.name.split(/, */)).split(/ +/)).replace('\'',''); } else if (data.email) { data.full = '<' + data.email + '>'; data.shortname = data.email.split('@')[0]; } - // Generate the gravatar - data.image = Message.$gravatar(data.email, 32); + data.image = Message.$avatar(data.email, 32); // If the current user is the recepient, overwrite // the short name with 'me' @@ -342,13 +341,6 @@ part.type == 'UIxMailPartImageViewer' || part.type == 'UIxMailPartLinkViewer') { - // UIxMailPartICalViewer injects 'participants' - if (part.participants) { - _.forEach(part.participants, function(participant) { - participant.image = Message.$gravatar(participant.email, 32); - }); - } - if (part.type == 'UIxMailPartImageViewer') part.msgclass = 'msg-attachment-image'; else if (part.type == 'UIxMailPartLinkViewer') diff --git a/UI/WebServerResources/js/Preferences/Preferences.service.js b/UI/WebServerResources/js/Preferences/Preferences.service.js index 3fc00d05d..4a6f7e18b 100644 --- a/UI/WebServerResources/js/Preferences/Preferences.service.js +++ b/UI/WebServerResources/js/Preferences/Preferences.service.js @@ -116,11 +116,17 @@ this.settingsPromise = Preferences.$$resource.fetch("jsonSettings").then(function(data) { // We convert our PreventInvitationsWhitelist hash into a array of user if (data.Calendar) { - if (data.Calendar.PreventInvitationsWhitelist) + if (data.Calendar.PreventInvitationsWhitelist) { data.Calendar.PreventInvitationsWhitelist = _.map(data.Calendar.PreventInvitationsWhitelist, function(value, key) { - var match = /^(.+)\s<(\S+)>$/.exec(value); - return new Preferences.$User({uid: key, cn: match[1], c_email: match[2]}); + var match = /^(.+)\s<(\S+)>$/.exec(value), + user = new Preferences.$User({uid: key, cn: match[1], c_email: match[2]}); + if (!user.$$image) + _this.avatar(user.c_email, 32, {no_404: true}).then(function(url) { + user.$$image = url; + }); + return user; }); + } else data.Calendar.PreventInvitationsWhitelist = []; } @@ -136,14 +142,15 @@ * @desc The factory we'll use to register with Angular * @returns the Preferences constructor */ - Preferences.$factory = ['$q', '$timeout', '$log', '$mdDateLocale', 'sgSettings', 'Resource', 'User', function($q, $timeout, $log, $mdDateLocaleProvider, Settings, Resource, User) { + Preferences.$factory = ['$q', '$timeout', '$log', '$mdDateLocale', 'sgSettings', 'Gravatar', 'Resource', 'User', function($q, $timeout, $log, $mdDateLocaleProvider, Settings, Gravatar, Resource, User) { angular.extend(Preferences, { $q: $q, $timeout: $timeout, $log: $log, $mdDateLocaleProvider: $mdDateLocaleProvider, + $gravatar: Gravatar, $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()), - activeUser: Settings.activeUser(), + $resourcesURL: Settings.resourcesURL(), $User: User }); @@ -172,6 +179,26 @@ return Preferences.$q.all([this.defaultsPromise, this.settingsPromise]); }; + /** + * @function avatar + * @memberof Preferences.prototype + * @desc Get the avatar URL associated to an email address + * @return a combined promise + */ + Preferences.prototype.avatar = function(email, size, options) { + var _this = this; + return this.ready().then(function() { + var alternate_avatar = _this.defaults.SOGoAlternateAvatar, url; + if (_this.defaults.SOGoGravatarEnabled) + url = Preferences.$gravatar(email, size, alternate_avatar, options); + else + url = [Preferences.$resourcesURL, 'img', 'ic_person_grey_24px.svg'].join('/'); + if (options && options.dstObject && options.dstAttr) + options.dstObject[options.dstAttr] = url; + return url; + }); + }; + /** * @function $save * @memberof Preferences.prototype diff --git a/UI/WebServerResources/js/Preferences/PreferencesController.js b/UI/WebServerResources/js/Preferences/PreferencesController.js index 8b46a7792..4e98cc00c 100644 --- a/UI/WebServerResources/js/Preferences/PreferencesController.js +++ b/UI/WebServerResources/js/Preferences/PreferencesController.js @@ -29,7 +29,7 @@ vm.editMailFilter = editMailFilter; vm.removeMailFilter = removeMailFilter; vm.addDefaultEmailAddresses = addDefaultEmailAddresses; - vm.userFilter = User.$filter; + vm.userFilter = userFilter; vm.confirmChanges = confirmChanges; vm.save = save; vm.canChangePassword = canChangePassword; @@ -230,6 +230,23 @@ form.$setDirty(); } + function userFilter(search, excludedUsers) { + return User.$filter(search, excludedUsers).then(function(users) { + // Set users avatars + _.forEach(users, function(user) { + if (!user.$$image) { + if (user.image) + user.$$image = user.image; + else + vm.preferences.avatar(user.c_email, 32, {no_404: true}).then(function(url) { + user.$$image = url; + }); + } + }); + return users; + }); + } + function confirmChanges($event, form) { var target; diff --git a/UI/WebServerResources/scss/components/chips/chips.scss b/UI/WebServerResources/scss/components/chips/chips.scss index 1eabd79ff..8ec4d77b4 100644 --- a/UI/WebServerResources/scss/components/chips/chips.scss +++ b/UI/WebServerResources/scss/components/chips/chips.scss @@ -56,7 +56,8 @@ md-chips { } // Enlarge the default autocompletion menu -.sg-chips-autocomplete { +.sg-chips-autocomplete, +.sg-chips-autocomplete input { width: (3 * $contact-chip-name-width); @media (max-width: $layout-breakpoint-xs) { // Enlarge the autocompletion menu on small devices to fit the entire screen