mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
(Re-)implement default avatar using user initials
We use a embedded svg to scale the initials text to its container size. The user is free to overwrite its initials in the profile form.
This commit is contained in:
parent
0b6c229b6c
commit
765b0168ea
6 changed files with 91 additions and 43 deletions
|
|
@ -218,22 +218,24 @@ $popupWidth = 300px
|
||||||
.pop-over-list
|
.pop-over-list
|
||||||
padding-top: 8px
|
padding-top: 8px
|
||||||
|
|
||||||
.mini-profile-info
|
.miniprofile-header
|
||||||
margin-top: 8px
|
margin-top: 8px
|
||||||
min-height: 56px
|
min-height: 56px
|
||||||
position: relative
|
position: relative
|
||||||
|
|
||||||
.member-large
|
.member
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 2px
|
top: 2px
|
||||||
left: 2px
|
left: 2px
|
||||||
|
height: 50px
|
||||||
|
width: @height
|
||||||
|
|
||||||
.info
|
.info
|
||||||
margin: 0 0 0 64px
|
margin: 0 0 0 64px
|
||||||
word-wrap: break-word
|
word-wrap: break-word
|
||||||
|
|
||||||
h3 a
|
h3 a
|
||||||
text-decoration: none
|
text-decoration: none
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration: underline
|
text-decoration: underline
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,15 @@ template(name="labelsWidget")
|
||||||
i.fa.fa-plus
|
i.fa.fa-plus
|
||||||
|
|
||||||
template(name="memberPopup")
|
template(name="memberPopup")
|
||||||
.board-member-menu: .mini-profile-info
|
.board-member-menu
|
||||||
+userAvatar(user=user)
|
.miniprofile-header
|
||||||
.info
|
+userAvatar(userId=user._id)
|
||||||
h3.bottom
|
.info
|
||||||
.js-profile
|
h3.bottom
|
||||||
= user.profile.name
|
.js-profile
|
||||||
p.quiet.bottom @#{user.username}
|
= user.profile.name
|
||||||
|
p.quiet.bottom @#{user.username}
|
||||||
|
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li
|
li
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
template(name="userAvatar")
|
template(name="userAvatar")
|
||||||
.member.js-member(title="{{userData.profile.fullname}} ({{userData.username}})")
|
a.member.js-member(title="{{userData.profile.fullname}} ({{userData.username}})")
|
||||||
if userData.profile.avatarUrl
|
if userData.profile.avatarUrl
|
||||||
img.avatar.avatar-image(src=userData.profile.avatarUrl)
|
img.avatar.avatar-image(src=userData.profile.avatarUrl)
|
||||||
|
else
|
||||||
|
+userAvatarInitials(userId=userData._id)
|
||||||
|
|
||||||
if showStatus
|
if showStatus
|
||||||
span.member-presence-status(class=presenceStatusClassName)
|
span.member-presence-status(class=presenceStatusClassName)
|
||||||
span.member-type(class=memberType)
|
span.member-type(class=memberType)
|
||||||
|
|
||||||
|
template(name="userAvatarInitials")
|
||||||
|
svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15")
|
||||||
|
text(x="0" y="13")= initials
|
||||||
|
|
||||||
template(name="userPopup")
|
template(name="userPopup")
|
||||||
.board-member-menu
|
.board-member-menu
|
||||||
.mini-profile-info
|
.mini-profile-info
|
||||||
+userAvatar(user=user)
|
+userAvatar(userId=user._id)
|
||||||
.info
|
.info
|
||||||
h3.bottom
|
h3.bottom
|
||||||
a.js-profile(href="{{pathFor route='Profile' username=user.username}}")= user.profile.name
|
a.js-profile(href="{{pathFor route='Profile' username=user.username}}")= user.profile.name
|
||||||
|
|
@ -25,8 +32,8 @@ template(name="changeAvatarPopup")
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
each uploadedAvatars
|
each uploadedAvatars
|
||||||
li: a.js-select-avatar
|
li: a.js-select-avatar
|
||||||
.member: .avatar
|
.member
|
||||||
img.avatar-image(src="{{url avatarUrlOptions}}")
|
img.avatar.avatar-image(src="{{url avatarUrlOptions}}")
|
||||||
| Uploaded avatar
|
| Uploaded avatar
|
||||||
if isSelected
|
if isSelected
|
||||||
i.fa.fa-check
|
i.fa.fa-check
|
||||||
|
|
@ -36,6 +43,13 @@ template(name="changeAvatarPopup")
|
||||||
| Delete
|
| Delete
|
||||||
| -
|
| -
|
||||||
= original.name
|
= original.name
|
||||||
|
li: a.js-select-initials
|
||||||
|
.member
|
||||||
|
+userAvatarInitials(userId=currentUser._id)
|
||||||
|
| Initials
|
||||||
|
if noAvatarUrl
|
||||||
|
i.fa.fa-check
|
||||||
|
p.sub-name Default avatar
|
||||||
input.hide.js-upload-avatar-input(accept="image/*;capture=camera" type="file")
|
input.hide.js-upload-avatar-input(accept="image/*;capture=camera" type="file")
|
||||||
button.full.js-upload-avatar
|
button.full.js-upload-avatar
|
||||||
i.fa.fa-upload
|
i.fa.fa-upload
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,18 @@ Template.userAvatar.helpers({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.userAvatarInitials.helpers({
|
||||||
|
initials: function() {
|
||||||
|
var user = Users.findOne(this.userId);
|
||||||
|
return user && user.getInitials();
|
||||||
|
},
|
||||||
|
|
||||||
|
viewPortWidth: function() {
|
||||||
|
var user = Users.findOne(this.userId);
|
||||||
|
return (user && user.getInitials().length || 1) * 12;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
template: function() {
|
template: function() {
|
||||||
return 'changeAvatarPopup';
|
return 'changeAvatarPopup';
|
||||||
|
|
@ -49,6 +61,12 @@ BlazeComponent.extendComponent({
|
||||||
return avatarUrl === currentAvatarUrl;
|
return avatarUrl === currentAvatarUrl;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
noAvatarUrl: function() {
|
||||||
|
var userProfile = Meteor.user().profile;
|
||||||
|
var avatarUrl = userProfile && userProfile.avatarUrl;
|
||||||
|
return ! avatarUrl;
|
||||||
|
},
|
||||||
|
|
||||||
setAvatar: function(avatarUrl) {
|
setAvatar: function(avatarUrl) {
|
||||||
Meteor.users.update(Meteor.userId(), {
|
Meteor.users.update(Meteor.userId(), {
|
||||||
$set: {
|
$set: {
|
||||||
|
|
@ -84,6 +102,9 @@ BlazeComponent.extendComponent({
|
||||||
var avatarUrl = this.currentData().url(this.avatarUrlOptions());
|
var avatarUrl = this.currentData().url(this.avatarUrlOptions());
|
||||||
this.setAvatar(avatarUrl);
|
this.setAvatar(avatarUrl);
|
||||||
},
|
},
|
||||||
|
'click .js-select-initials': function() {
|
||||||
|
this.setAvatar('');
|
||||||
|
},
|
||||||
'click .js-delete-avatar': function() {
|
'click .js-delete-avatar': function() {
|
||||||
Avatars.remove(this.currentData()._id);
|
Avatars.remove(this.currentData()._id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ avatar-radius = 50%
|
||||||
.member
|
.member
|
||||||
border-radius: 3px
|
border-radius: 3px
|
||||||
display: block
|
display: block
|
||||||
|
position: relative
|
||||||
float: left
|
float: left
|
||||||
height: 30px
|
height: 30px
|
||||||
width: @height
|
width: @height
|
||||||
margin: 0 4px 4px 0
|
margin: 0 4px 4px 0
|
||||||
position: relative
|
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
user-select: none
|
user-select: none
|
||||||
z-index: 1
|
z-index: 1
|
||||||
|
|
@ -17,26 +17,20 @@ avatar-radius = 50%
|
||||||
border-radius: avatar-radius
|
border-radius: avatar-radius
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
height: 100%
|
|
||||||
width: @height
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
border-radius: avatar-radius
|
border-radius: avatar-radius
|
||||||
|
|
||||||
.avatar-initials
|
&.avatar-initials
|
||||||
font-weight: bold
|
height: 70%
|
||||||
max-width: 100%
|
width: @height
|
||||||
max-height: 100%
|
padding: 15%
|
||||||
font-size: 14px
|
|
||||||
line-height: 200%
|
|
||||||
background-color: #dbdbdb
|
background-color: #dbdbdb
|
||||||
color: #444444
|
color: #444444
|
||||||
|
position: absolute
|
||||||
|
|
||||||
.avatar-image
|
&.avatar-image
|
||||||
max-width: 100%
|
height: 100%
|
||||||
max-height: 100%
|
width: @height
|
||||||
|
|
||||||
.member-presence-status
|
.member-presence-status
|
||||||
background-color: #b3b3b3
|
background-color: #b3b3b3
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,28 @@ Users.helpers({
|
||||||
return _.where(board.members, {userId: this._id})[0].isAdmin;
|
return _.where(board.members, {userId: this._id})[0].isAdmin;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getInitials: function() {
|
||||||
|
var profile = this.profile || {};
|
||||||
|
if (profile.initials)
|
||||||
|
return profile.initials;
|
||||||
|
|
||||||
|
else if (profile.fullname) {
|
||||||
|
return _.reduce(profile.fullname.split(/\s+/), function(memo, word) {
|
||||||
|
return memo + word[0];
|
||||||
|
}, '').toUpperCase();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return this.pseudo[0].toUpperCase();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
toggleBoardStar: function(boardId) {
|
toggleBoardStar: function(boardId) {
|
||||||
var queryType = Meteor.user().hasStarred(boardId) ? '$pull' : '$addToSet';
|
var queryType = this.hasStarred(boardId) ? '$pull' : '$addToSet';
|
||||||
var query = {};
|
var query = {};
|
||||||
query[queryType] = {
|
query[queryType] = {
|
||||||
'profile.starredBoards': boardId
|
'profile.starredBoards': boardId
|
||||||
};
|
};
|
||||||
Meteor.users.update(Meteor.userId(), query);
|
Meteor.users.update(this._id, query);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue