This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit d7f90355d7e952058a11fbef1c552b67e620f0a3 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 18:56:56 2017 +0200 refs #28 utilisation des avatars un peu partout + verif de la taille et du type de fichier pour l'avatar --- .../pollen/rest/api/v1/PollenResourceApi.java | 6 ++- .../chorem/pollen/services/bean/CommentBean.java | 10 +++++ .../org/chorem/pollen/services/bean/VoteBean.java | 10 +++++ .../pollen/services/service/CommentService.java | 17 ++++++--- .../pollen/services/service/PollService.java | 16 ++++---- .../services/service/PollenResourceService.java | 16 ++++++-- .../pollen/services/service/VoteService.java | 18 +++++++-- pollen-ui-riot-js/src/main/web/i18n/en.json | 2 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 2 + .../src/main/web/js/ResourceService.js | 13 +++++-- .../src/main/web/tag/PollenHeader.tag.html | 8 +++- .../src/main/web/tag/UserProfile.tag.html | 44 ++++++++++++++++++---- .../src/main/web/tag/components/Avatar.tag.html | 25 +++++------- .../src/main/web/tag/poll/Comments.tag.html | 7 +++- .../src/main/web/tag/poll/PollCard.tag.html | 11 +++++- .../src/main/web/tag/poll/Votes.tag.html | 15 ++++++-- 16 files changed, 165 insertions(+), 55 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java index 7decb52b..4ce7e96c 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java @@ -39,6 +39,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -79,9 +80,10 @@ public class PollenResourceApi { @GET @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response getPreviewResource(@Context PollenResourceService pollenResourceService, - @PathParam("resourceId") PollenEntityId<PollenResource> resourceId) throws IOException { + @PathParam("resourceId") PollenEntityId<PollenResource> resourceId, + @QueryParam("maxDimension") boolean maxDimension) throws IOException { - ResourceStreamBean resource = pollenResourceService.getResourcePreview(resourceId.getEntityId()); + ResourceStreamBean resource = pollenResourceService.getResourcePreview(resourceId.getEntityId(), maxDimension); return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java index 17b88b86..887f3a7b 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java @@ -37,6 +37,8 @@ public class CommentBean extends PollenBean<Comment> { protected String authorName; + protected String authorAvatar; + protected String text; protected Date postDate; @@ -79,6 +81,14 @@ public class CommentBean extends PollenBean<Comment> { this.authorName = authorName; } + public String getAuthorAvatar() { + return authorAvatar; + } + + public void setAuthorAvatar(String authorAvatar) { + this.authorAvatar = authorAvatar; + } + public ReportResumeBean getReport() { return report; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java index 7b79f09a..481b02bf 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java @@ -45,6 +45,8 @@ public class VoteBean extends PollenBean<Vote> { protected String voterName; + protected String voterAvatar; + protected String permission; protected Boolean anonymous; @@ -69,6 +71,14 @@ public class VoteBean extends PollenBean<Vote> { this.voterName = voterName; } + public String getVoterAvatar() { + return voterAvatar; + } + + public void setVoterAvatar(String voterAvatar) { + this.voterAvatar = voterAvatar; + } + public PollenEntityId<PollenPrincipal> getVoterId() { if (voterId == null) { voterId = PollenEntityId.newId(PollenPrincipal.class); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java index d7dd28b3..4ff21786 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java @@ -50,24 +50,29 @@ public class CommentService extends PollenServiceSupport { CommentBean bean = new CommentBean(); bean.setEntityId(entity.getTopiaId()); - if (entity.getAuthor() == null - || entity.getAuthor().getPermission() == null - || isNotPermitted(PermissionVerb.editComment, entity.getTopiaId())) { + PollenPrincipal author = entity.getAuthor(); + if (author == null + || author.getPermission() == null + || isNotPermitted(PermissionVerb.editComment, entity.getTopiaId())) { bean.setPermission(null); } else { - bean.setPermission(entity.getAuthor().getPermission().getToken()); + bean.setPermission(author.getPermission().getToken()); } bean.setText(entity.getText()); bean.setPostDate(entity.getPostDate()); - if (entity.getAuthor() != null) { + if (author != null) { - bean.setAuthorName(entity.getAuthor().getName()); + bean.setAuthorName(author.getName()); + + if (author.getPollenUser() != null && author.getPollenUser().getAvatar() != null) { + bean.setAuthorAvatar(getPollenResourceService().getReduceIdByTopiaId(author.getPollenUser().getAvatar().getTopiaId())); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index 3c3f2a37..314f96b9 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -72,20 +72,22 @@ public class PollService extends PollenServiceSupport { bean.setEntityId(entity.getTopiaId()); - if (entity.getCreator() == null || entity.getCreator().getPermission() == null) { + PollenPrincipal creator = entity.getCreator(); + + if (creator == null || creator.getPermission() == null) { bean.setPermission(null); } else { - bean.setPermission(entity.getCreator().getPermission().getToken()); + bean.setPermission(creator.getPermission().getToken()); } - if (entity.getCreator() != null) { + if (creator != null) { - bean.setCreatorName(entity.getCreator().getName()); - bean.setCreatorEmail(entity.getCreator().getEmail()); + bean.setCreatorName(creator.getName()); + bean.setCreatorEmail(creator.getEmail()); } @@ -182,9 +184,9 @@ public class PollService extends PollenServiceSupport { bean.setGtuValidated(getGtuService().isGtuValidated(entity)); bean.setMaxVoters(getMaxVoters(entity)); - if (entity.getCreator().getPollenUser() != null && entity.getCreator().getPollenUser().getAvatar() != null) { + if (creator.getPollenUser() != null && creator.getPollenUser().getAvatar() != null) { bean.setCreatorAvatar(getPollenResourceService().getReduceIdByTopiaId( - entity.getCreator().getPollenUser().getAvatar().getTopiaId())); + creator.getPollenUser().getAvatar().getTopiaId())); } return bean; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java index f3d41c15..60a7571e 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java @@ -98,7 +98,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return toResourceMetaBean(resource); } - public ResourceStreamBean getResourcePreview(String resourceId) { + public ResourceStreamBean getResourcePreview(String resourceId, boolean maxDimension) { checkNotNull(resourceId); @@ -116,6 +116,8 @@ public class PollenResourceService extends PollenServiceSupport implements Polle } int width, height; + Integer previewWidth = null; + Integer previewHeight = null; int previewMax = getPollenServiceConfig().getResourcePreviewMax(); @@ -127,9 +129,17 @@ public class PollenResourceService extends PollenServiceSupport implements Polle width = height * source.getWidth() / source.getHeight(); } - BufferedImage destination = new BufferedImage(width, height, source.getType()); + if (maxDimension) { + previewWidth = previewMax; + previewHeight = previewMax; + } else { + previewWidth = width; + previewHeight = height; + } + + BufferedImage destination = new BufferedImage(previewWidth, previewHeight, source.getType()); Graphics2D g = destination.createGraphics(); - g.drawImage(source, 0, 0, width, height, null); + g.drawImage(source, (previewWidth - width) / 2, (previewHeight - height) / 2, width, height, null); g.dispose(); ByteArrayOutputStream output = new ByteArrayOutputStream(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index 12c244a3..23bcd143 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -68,19 +68,28 @@ public class VoteService extends PollenServiceSupport { bean.setEntityId(entity.getTopiaId()); - if (entity.getVoter() == null || entity.getVoter().getPermission() == null) { + PollenPrincipal voter = entity.getVoter(); + + if (voter == null || voter.getPermission() == null) { bean.setPermission(null); } else { - bean.setPermission(entity.getVoter().getPermission().getToken()); + bean.setPermission(voter.getPermission().getToken()); } bean.setAnonymous(entity.isAnonymous()); - bean.getVoterId().setEntityId(entity.getVoter().getTopiaId()); - bean.setVoterName(entity.getVoter().getName()); + + if (voter != null) { + bean.getVoterId().setEntityId(voter.getTopiaId()); + bean.setVoterName(voter.getName()); + if (voter.getPollenUser() != null && voter.getPollenUser().getAvatar() != null) { + bean.setVoterAvatar(getPollenResourceService().getReduceIdByTopiaId(voter.getPollenUser().getAvatar().getTopiaId())); + } + } + bean.setWeight(entity.getWeight()); entity.getVoteToChoice().stream() @@ -99,6 +108,7 @@ public class VoteService extends PollenServiceSupport { bean.setPermission(null); if (entity.isAnonymous()) { bean.setVoterName(null); + bean.setVoterAvatar(null); } int maxVoters = getPollService().getMaxVoters(entity.getPoll()); diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index a4a4eafc..f3eebcad 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -418,6 +418,8 @@ "userProfile_unlinkProviderMessage": "Unlink this external account? You will not be able to connect to your Pollen account with this external account.", "userProfile_avatar": "Avatar", "userProfile_deleteAvatarMessage": "Remove your avatar?", + "userProfile_fileSizeMax_message": "File \"{0}\" for size {1} can't be over {2}.", + "userProfile_fileNotImage_message": "The file \"{0}\" is not an image.", "choice_description_placeholder": "You can enter a description for this choice", "date-picker_today": "Today", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 89435e5a..0ef51024 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -420,6 +420,8 @@ "userProfile_deleteAvatarMessage": "Supprimer votre avatar ?", "userProfile_uploadAvatar": "Téléverser un fichier", "userProfile_getProviderAvatar": "ou utiliser votre avatar d'un service tiers", + "userProfile_fileSizeMax_message": "Le fichier « {0} » de taille de {1} ne doit pas dépasser {2}.", + "userProfile_fileNotImage_message": "Le fichier « {0} » n'est pas une image.", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/js/ResourceService.js b/pollen-ui-riot-js/src/main/web/js/ResourceService.js index 7de1ccc0..34417a67 100644 --- a/pollen-ui-riot-js/src/main/web/js/ResourceService.js +++ b/pollen-ui-riot-js/src/main/web/js/ResourceService.js @@ -47,13 +47,20 @@ class ResourceService extends FetchService { return this.get(url); } - getPreview(resourceId) { + getPreview(resourceId, maxDimension) { let url = this._getUrlPrefix(resourceId) + "/preview"; + if (maxDimension) { + url += "?maxDimension=true"; + } return this.get(url); } - getPreviewUrl(resourceId) { - return this.endPoint + this._getUrlPrefix(resourceId) + "/preview"; + getPreviewUrl(resourceId, maxDimension) { + let url = this.endPoint + this._getUrlPrefix(resourceId) + "/preview"; + if (maxDimension) { + url += "?maxDimension=true"; + } + return url; } getMeta(resourceId) { diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index 05a0c123..7b98efef 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -47,7 +47,7 @@ require("./components/Avatar.tag.html"); <div class="dropdown" if={user}> <a class="header-link"> - <Avatar avatar={user.avatar} name={user.name} rounded="true"/> + <Avatar avatar={user.avatar} class="user-avatar" name={user.name} rounded="true"/> <span class="user-name action-label"> {user && user.name}</span> </a> <div class="dropdown-content right"> @@ -166,6 +166,12 @@ require("./components/Avatar.tag.html"); color: var(--header-link); } + pollenheader .user-avatar { + width: 45px; + height: 45px; + font-size: 1.5em; + } + @media (max-width: 640px) { .user-name { display: none; diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 0fe89cfe..a1e2950f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -172,16 +172,17 @@ require("./components/LetterAvatar.tag.html"); <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> <div class="avatar-container"> <div class="avatar-column" if="{user.avatar}"> - <img src="{resourceService.getPreviewUrl(user.avatar)}"/> + <img class="user-avatar" src="{resourceService.getPreviewUrl(user.avatar, true)}"/> <button onclick="{deleteAvatar}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> </div> - <LetterAvatar class="avatar-column" name={user && user.name || ""} if="{!user.avatar}"/> + <LetterAvatar class="avatar-column user-avatar" name={user && user.name || ""} if="{!user.avatar}" rounded="true"/> <div class="form-column"> <div class="o-form-element"> <label class="c-label" for="avatar">{__.uploadAvatar}</label> <span class="c-input-group"> - <input type="file" class="c-field" ref="avatar" required/> - <button class="c-button" onclick="{uploadAvatar}"><i class="fa fa-upload"></i></button> + <input type="file" accept="image/*" class="c-field" ref="avatar" + onchange={onAvatarChange} /> + <button class="c-button" onclick="{uploadAvatar}" disabled="{!avatarFile}"><i class="fa fa-upload"></i></button> </span> </div> <div class="align-center" if="{loginProviders.length > 0}"> @@ -214,6 +215,7 @@ require("./components/LetterAvatar.tag.html"); let Message = require("../js/Message"); this.loginProviders = []; + this.avatarFile = null; this.authService.getActiveLoginProviders().then((result) => { this.loginProviders = result; this.update(); @@ -313,19 +315,40 @@ require("./components/LetterAvatar.tag.html"); return userService.deleteAvatar(); }).then(result => { this.user.avatar = null; + this.session.updateUser(); this.update(); }); }; -//TODO check size and all this.uploadAvatar = e => { userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { - console.log(result); this.user.avatar = result.id; + this.refs.avatar.value = null; + this.avatarFile = null; this.session.updateUser(); this.update(); }); - } + }; + + this.onAvatarChange = () => { + this.avatarFile = this.refs.avatar.files[0]; + if (this.avatarFile) { + this.checkSize(this.avatarFile).then(ok => { + if (!this.avatarFile.type.startsWith("image/")) { + this.info( + this.__.fileNotImage_title, + this._l("fileNotImage_message", this.avatarFile.name), + undefined, + "error"); + ok = false; + } + if (!ok) { + this.avatarFile = null; + this.update(); + } + }); + } + }; this.listen("user", this.onUserChange); @@ -395,9 +418,16 @@ require("./components/LetterAvatar.tag.html"); margin: 20px 20px 0 0; } + .user-avatar { + width: 100px; + height: 100px; + font-size: 3em; + } + .form-column { display: flex; flex-direction: column; + flex-grow: 1; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html index b5e875da..e6a37903 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html @@ -1,34 +1,27 @@ require("./LetterAvatar.tag.html"); <Avatar> - <LetterAvatar name={opts.name} rounded={opts.rounded} if={!opts.avatar} /> + <LetterAvatar class="avatar-letter" name={opts.name} rounded={opts.rounded} if={!opts.avatar} /> - <div class="avatar {rounded: opts.rounded}" - style="background-image: url('{resourceService.getPreviewUrl(opts.avatar)}');" + <img class="avatar-avatar {rounded: opts.rounded}" + src="{resourceService.getPreviewUrl(opts.avatar, true)}" show={opts.avatar}> - </div> + </img> <script> this.session = require("../../js/Session"); this.installBundle(this.session, "avatar"); this.resourceService = require("../../js/ResourceService"); this.avatarLoaded = false; - - this.onAvatarLoaded = e => { - this.avatarLoaded = true; - this.update(); - }; </script> <style> - .avatar { - width: 50px; - height:50px; - background-size: 50px 50px; - background-position: center; - background-repeat: no-repeat; + .avatar-avatar { + width: 100%; + height: 100%; } - .avatar.rounded { + + .avatar-avatar.rounded { border-radius: 100%; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html index 8e2c28a5..6d082351 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html @@ -112,7 +112,7 @@ require("./Report.tag.html"); <div class="separator-bottom"> <div if={parent.parent.commentEditing !== element} class="comment"> <div class="comment-user"> - <LetterAvatar name={element.authorName} rounded="true"/> + <Avatar class="comment-avatar" avatar={element.authorAvatar} name={element.authorName} rounded="true"/> <div class="user"> {element.authorName} <Report target={element}/> @@ -427,6 +427,11 @@ require("./Report.tag.html"); padding-top: 10px; } + .comment-user .comment-avatar { + width: 30px; + height: 30px; + } + .comment .comment-user { padding: 0 3px 0 0; display: flex; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html index 1cb3bb78..cd99a48f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html @@ -49,7 +49,7 @@ require("../components/Avatar.tag.html"); </div> <div class="poll-creator" title={opts.poll.creatorName}> - <Avatar avatar={opts.poll.creatorAvatar} name={opts.poll.creatorName} rounded="true"/> + <Avatar class="creator-avatar" avatar={opts.poll.creatorAvatar} name={opts.poll.creatorName} rounded="true"/> <div class="creator-name"> {opts.poll.creatorName} <div class="creation-date"> @@ -150,10 +150,17 @@ require("../components/Avatar.tag.html"); } .poll-creator { - margin-left: 20px; + margin-left: 10px; display: flex; } + .poll-creator .creator-avatar { + width: 42px; + height: 42px; + font-size: 1.5em; + margin-right: 10px; + } + .poll-creator .creator-name { margin-left: 5px; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index 182bc16b..5d25d051 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -23,6 +23,7 @@ require("./ChoiceView.tag.html"); require("./Podium.tag.html"); require("../components/HumanInput.tag.html"); require("../components/LazyLoad.tag.html"); +require("../components/Avatar.tag.html"); <Votes> <div class="container" show="{loaded}"> @@ -87,7 +88,7 @@ require("../components/LazyLoad.tag.html"); </span> </div> </div> - <div class="footer separator-top" if="{loaded && poll.canVote}"> + <div class="footer separator-top" if="{loaded && (poll.canVote || voteInEdition)}"> <div class="current-voter-actions separator-right"> <div class="current-voter-buttons"> <button if={!voteInEdition} @@ -174,8 +175,8 @@ require("../components/LazyLoad.tag.html"); <yield to="element"> <div class="row separator-bottom separator-right"> <div class="name separator-left"> - <div class="voter-name" onmouseenter="{parent.parent.showTooltip(element)}" onclick="{parent.parent.showTooltip(vote)}" onmouseleave="{parent.parent.hideTooltip}"> - <i class="fa fa-user-circle c-icon"></i> + <Avatar class="voter-avatar" avatar={element.voterAvatar} name={element.voterName} rounded="true"/> + <div class="voter-name" onmouseenter="{parent.parent.showTooltip(element)}" onclick="{parent.parent.showTooltip(vote)}" onmouseleave="{parent.parent.hideTooltip}"> <span if="{!element.anonymous || element.permission}">{element.voterName}</span> <span if="{element.anonymous && !element.permission}" class="anonymous-voter">{parent.parent.__.anonymousVoter}</span> </div> @@ -698,6 +699,14 @@ require("../components/LazyLoad.tag.html"); text-overflow:ellipsis; } + .voters .voter-avatar { + width: 24px; + min-width: 24px; + height: 24px; + margin: 2px 0; + font-size: 0.85em; + } + .voters .row:hover .name { background-color: var(--vote-hover); border-bottom-color: var(--brand); -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.