Re-factor the avatar system and support avatar uploads

The user is now able to upload an avatar, and pick one in a list.

This functionality should eventually be abstracted in a community
package but we still need to work on a great public API. We rely on
collectionFS to manage uploaded avatars. We also removed
bengott:avatar which was trying to solve the wrong problem (namely
displaying the avatar, which is as simple as displaying an image), and
not a avatar system as it should be.

Gravatar support is coming (back) soon. We may also want to have a
list of default fun avatars the user can choose instead of uploading
its own one.
This commit is contained in:
Maxime Quandalle 2015-06-08 11:47:06 +02:00
parent 98d7278d08
commit 46cc691534
22 changed files with 161 additions and 227 deletions

View file

@ -1,17 +1,22 @@
Meteor.subscribe('my-avatars');
Template.userAvatar.helpers({
userData: function() {
if (! this.user) {
this.user = Users.findOne(this.userId);
}
return this.user;
return Users.findOne(this.userId, {
fields: {
profile: 1,
username: 1
}
});
},
memberType: function() {
var userId = this.userId || this.user._id;
var user = Users.findOne(userId);
var user = Users.findOne(this.userId);
return user && user.isBoardAdmin() ? 'admin' : 'normal';
},
presenceStatusClassName: function() {
var userPresence = Presences.findOne({ userId: this.user._id });
var userPresence = Presences.findOne({ userId: this.userId });
if (! userPresence)
return 'disconnected';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
@ -20,3 +25,68 @@ Template.userAvatar.helpers({
return 'idle';
}
});
BlazeComponent.extendComponent({
template: function() {
return 'changeAvatarPopup';
},
avatarUrlOptions: function() {
return {
auth: false,
brokenIsFine: true
};
},
uploadedAvatars: function() {
return Avatars.find({userId: Meteor.userId()});
},
isSelected: function() {
var userProfile = Meteor.user().profile;
var avatarUrl = userProfile && userProfile.avatarUrl;
var currentAvatarUrl = this.currentData().url(this.avatarUrlOptions());
return avatarUrl === currentAvatarUrl;
},
setAvatar: function(avatarUrl) {
Meteor.users.update(Meteor.userId(), {
$set: {
'profile.avatarUrl': avatarUrl
}
});
},
events: function() {
return [{
'click .js-upload-avatar': function() {
this.$('.js-upload-avatar-input').click();
},
'change .js-upload-avatar-input': function(evt) {
var self = this;
var file, fileUrl;
FS.Utility.eachFile(evt, function(f) {
file = Avatars.insert(new FS.File(f));
fileUrl = file.url(self.avatarUrlOptions());
});
var fetchAvatarInterval = window.setInterval(function() {
$.ajax({
url: fileUrl,
success: function() {
self.setAvatar(file.url(self.avatarUrlOptions()));
window.clearInterval(fetchAvatarInterval);
}
});
}, 100);
},
'click .js-select-avatar': function() {
var avatarUrl = this.currentData().url(this.avatarUrlOptions());
this.setAvatar(avatarUrl);
},
'click .js-delete-avatar': function() {
Avatars.remove(this.currentData()._id);
}
}];
}
}).register('changeAvatarPopup');