(js) Fix sg-avatar-image with md-virtual-repeat

pull/186/head
Francis Lachapelle 2016-01-14 14:45:50 -05:00
parent 936f6cb073
commit 491f8b4f2a
6 changed files with 81 additions and 57 deletions

View File

@ -390,6 +390,7 @@
<sg-avatar-image class="md-avatar"
ng-if="addressbook.notSelectedComponent(currentCard, 'vcard')"
sg-email="currentCard.$preferredEmail(addressbook.selectedFolder.constructor.$query)"
sg-src="currentCard.photoURL"
size="40">
<!-- contact avatar -->
</sg-avatar-image>

View File

@ -226,7 +226,7 @@
ng-switch="currentMessage.selected">
<sg-avatar-image class="md-avatar"
ng-switch-when="false"
sg-email="::currentMessage.from[0].email"
sg-email="currentMessage.from[0].email"
size="40"><!-- avatar --></sg-avatar-image>
<div class="md-avatar sg-avatar-selected"
ng-switch-when="true"><!-- selected avatar --></div>

View File

@ -230,7 +230,7 @@
return {
response: function(response) {
// When expecting JSON but receiving HTML, assume session has expired and reload page
if (/^application\/json/.test(response.config.headers.Accept) &&
if (response && /^application\/json/.test(response.config.headers.Accept) &&
/^<!DOCTYPE html>/.test(response.data)) {
$window.location.reload(true);
return $q.reject();
@ -247,8 +247,10 @@
function ErrorInterceptor($rootScope, $q) {
return {
responseError: function(rejection) {
// Broadcast the response error
$rootScope.$broadcast('http:Error', rejection);
if (/^application\/json/.test(rejection.config.headers.Accept)) {
// Broadcast the response error
$rootScope.$broadcast('http:Error', rejection);
}
return $q.reject(rejection);
}
};

View File

@ -66,23 +66,26 @@
function onHttpError(event, response) {
var message;
if (response.data.message)
if (response.data && response.data.message)
message = response.data.message;
else
else if (response.status)
message = response.statusText;
$mdToast.show({
template: [
'<md-toast>',
' <div class="md-toast-content">',
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
' <span flex>' + l(message) + '</span>',
' </div>',
'</md-toast>'
].join(''),
hideDelay: 5000,
position: 'top right'
});
if (message)
$mdToast.show({
template: [
'<md-toast>',
' <div class="md-toast-content">',
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
' <span flex>' + l(message) + '</span>',
' </div>',
'</md-toast>'
].join(''),
hideDelay: 5000,
position: 'top right'
});
else
console.debug('untrap error');
}
// Listen to HTTP errors broadcasted from HTTP interceptor

View File

@ -6,7 +6,7 @@
/**
* sgAvatarImage - An avatar directive that returns un img element with either a local URL (if sg-src is specified)
* or a Gravatar URL built from the Gravatar factory.
* or a Gravatar URL built from the Gravatar factory (using sg-email).
* Based on http://blog.lingohub.com/2014/08/better-ux-with-angularjs-directives/.
* @memberof SOGo.Common
* @example:
@ -15,60 +15,54 @@
function sgAvatarImage() {
return {
restrict: 'AE',
scope: {
scope: {},
bindToController: {
size: '@',
email: '=sgEmail',
src: '=sgSrc'
},
template: '<img ng-src="{{vm.url}}"/>',
template: [
'<md-icon>person</md-icon>', // the generic icon
'<img class="ng-hide" ng-src="{{vm.url}}" />' // the gravatar or local image
].join(''),
link: link,
bindToController: true,
controller: 'sgAvatarImageController',
controllerAs: 'vm'
};
}
function link(scope, element, attrs, controller) {
var el = element[0],
className = el.className,
imgElement = element.find('img'),
img = imgElement[0];
var imgElement = element.find('img'),
mdIconElement = element.find('md-icon');
if (attrs.size) {
imgElement.attr('width', attrs.size);
imgElement.attr('height', attrs.size);
}
imgElement.bind('error', function() {
// Error while loading external link; insert a generic avatar
controller.insertGenericAvatar(img);
});
controller.img = imgElement;
controller.genericImg = mdIconElement;
}
/**
* @ngInject
*/
sgAvatarImageController.$inject = ['$scope', '$element', 'Preferences', 'Gravatar'];
function sgAvatarImageController($scope, $element, Preferences, Gravatar) {
var vm = this;
sgAvatarImageController.$inject = ['$scope', '$element', '$http', '$q', 'Preferences', 'Gravatar'];
function sgAvatarImageController($scope, $element, $http, $q, Preferences, Gravatar) {
var vm;
$scope.$watch('vm.email', function(email) {
vm = this;
Preferences.ready().then(function() {
var img = $element.find('img')[0];
if (!email && !vm.genericAvatar) {
// If no email is specified, insert a generic avatar
vm.insertGenericAvatar(img);
}
else if (email && !vm.url) {
if (vm.genericAvatar) {
// Remove generic avatar and restore visibility of image
vm.genericAvatar.parentNode.removeChild(vm.genericAvatar);
delete vm.genericAvatar;
img.classList.remove('ng-hide');
}
vm.url = Gravatar(email, vm.size, Preferences.defaults.SOGoAlternateAvatar);
// Wait on user's defaults
Preferences.ready().then(function() {
$scope.$watch('vm.email', function(email, old) {
if (email && vm.urlEmail != email) {
// Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat)
showGenericAvatar();
getGravatar(email);
}
else if (!email)
showGenericAvatar();
});
});
@ -76,21 +70,44 @@
if ('sg-src' in $element[0].attributes) {
$scope.$watch('vm.src', function(src) {
if (src) {
// Set image URL and save the associated email address
vm.url = src;
vm.urlEmail = '' + vm.email;
hideGenericAvatar();
}
});
}
vm.insertGenericAvatar = function(img) {
var avatar;
function getGravatar(email) {
var url = Gravatar(email, vm.size, Preferences.defaults.SOGoAlternateAvatar);
$http({
method: 'GET',
url: url,
cache: true,
headers: { Accept: 'image/*' }
}).then(function successCallback() {
if (!vm.url) {
// Set image URL and save the associated email address
vm.url = url;
vm.urlEmail = email;
hideGenericAvatar();
}
}, function errorCallback() {
showGenericAvatar();
});
}
if (!vm.genericAvatar) {
avatar = document.createElement('md-icon');
avatar.className = 'material-icons icon-person';
img.classList.add('ng-hide');
vm.genericAvatar = img.parentNode.insertBefore(avatar, img);
}
};
function showGenericAvatar() {
vm.url = null;
vm.urlEmail = null;
vm.img.addClass('ng-hide');
vm.genericImg.removeClass('ng-hide');
}
function hideGenericAvatar() {
vm.genericImg.addClass('ng-hide');
vm.img.removeClass('ng-hide');
}
}
angular

View File

@ -6,5 +6,6 @@ md-virtual-repeat-container {
// Fix weird scroll behavior when reaching bottom of list
// See https://github.com/angular/material/issues/4169
padding-top: 0;
padding-bottom: 0;
}
}