UX: Make user info rendering more consistent
This commit is contained in:
parent
476a5fd43c
commit
db15772ab1
|
@ -0,0 +1,23 @@
|
|||
import { url } from 'discourse/lib/computed';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
function normalize(name) {
|
||||
return name.replace(/[\-\_ \.]/g, '').toLowerCase();
|
||||
}
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [':user-info', 'size'],
|
||||
size: 'small',
|
||||
userPath: url('user.username', '/users/%@'),
|
||||
|
||||
// TODO: In later ember releases `hasBlock` works without this
|
||||
hasBlock: Ember.computed.alias('template'),
|
||||
|
||||
@computed('user.name', 'user.username')
|
||||
name(name, username) {
|
||||
if (name && normalize(username) !== normalize(name)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
import { url } from 'discourse/lib/computed';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['user-small'],
|
||||
|
||||
userPath: url('user.username', '/users/%@'),
|
||||
|
||||
name: function() {
|
||||
const name = this.get('user.name');
|
||||
if (name && this.get('user.username') !== name) {
|
||||
return name;
|
||||
}
|
||||
}.property('user.name')
|
||||
|
||||
});
|
|
@ -6,7 +6,7 @@ export default Ember.Controller.extend({
|
|||
userBadges: null,
|
||||
needs: ["application"],
|
||||
|
||||
user: function(){
|
||||
user: function() {
|
||||
if (this.get("username")) {
|
||||
return this.get('userBadges')[0].get('user');
|
||||
}
|
||||
|
@ -37,16 +37,6 @@ export default Ember.Controller.extend({
|
|||
}
|
||||
},
|
||||
|
||||
layoutClass: function(){
|
||||
var user = this.get("user") ? " single-user" : "";
|
||||
var ub = this.get("userBadges");
|
||||
if(ub && ub[0] && ub[0].post_id){
|
||||
return "user-badge-with-posts" + user;
|
||||
} else {
|
||||
return "user-badge-no-posts" + user;
|
||||
}
|
||||
}.property("userBadges"),
|
||||
|
||||
canLoadMore: function() {
|
||||
if (this.get('noMoreBadges')) { return false; }
|
||||
|
||||
|
|
|
@ -25,3 +25,5 @@ registerUnbound('format-date', function(val, params) {
|
|||
return new Handlebars.SafeString(autoUpdatingRelativeAge(date, {format: format, title: title, leaveAgo: leaveAgo}));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { relativeAge } from 'discourse/lib/formatter';
|
||||
|
||||
export default function(dt, params) {
|
||||
dt = params.data.view.getStream(dt).value();
|
||||
return relativeAge(new Date(dt));
|
||||
}
|
|
@ -6,13 +6,8 @@ const UserBadge = Discourse.Model.extend({
|
|||
return "/t/-/" + this.get('topic_id') + "/" + this.get('post_number');
|
||||
}
|
||||
}.property(), // avoid the extra bindings for now
|
||||
/**
|
||||
Revoke this badge.
|
||||
|
||||
@method revoke
|
||||
@returns {Promise} a promise that resolves when the badge has been revoked.
|
||||
**/
|
||||
revoke: function() {
|
||||
revoke() {
|
||||
return Discourse.ajax("/user_badges/" + this.get('id'), {
|
||||
type: "DELETE"
|
||||
});
|
||||
|
|
|
@ -15,10 +15,7 @@ export default Discourse.Route.extend({
|
|||
},
|
||||
|
||||
serialize(model) {
|
||||
return {
|
||||
id: model.get("id"),
|
||||
slug: model.get("slug")
|
||||
};
|
||||
return model.getProperties('id', 'slug');
|
||||
},
|
||||
|
||||
model(params) {
|
||||
|
@ -29,13 +26,12 @@ export default Discourse.Route.extend({
|
|||
}
|
||||
},
|
||||
|
||||
afterModel(model,transition) {
|
||||
afterModel(model, transition) {
|
||||
const username = transition.queryParams && transition.queryParams.username;
|
||||
|
||||
return UserBadge.findByBadgeId(model.get("id"), {username}).then(userBadges => {
|
||||
this.userBadges = userBadges;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
titleToken() {
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
<section class='about admins'>
|
||||
<h3>{{i18n 'about.our_admins'}}</h3>
|
||||
|
||||
{{#each a in model.admins}}
|
||||
{{user-small user=a}}
|
||||
{{#each model.admins as |a|}}
|
||||
{{user-info user=a}}
|
||||
{{/each}}
|
||||
<div class='clearfix'></div>
|
||||
|
||||
|
@ -35,8 +35,8 @@
|
|||
<h3>{{i18n 'about.our_moderators'}}</h3>
|
||||
|
||||
<div class='users'>
|
||||
{{#each m in model.moderators}}
|
||||
{{user-small user=m}}
|
||||
{{#each model.moderators as |m|}}
|
||||
{{user-info user=m}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class='clearfix'></div>
|
||||
|
|
|
@ -14,57 +14,38 @@
|
|||
<div class='badges-listing'>
|
||||
<div class='row'>
|
||||
{{#unless user}}
|
||||
<div class='grant-count'>{{i18n 'badges.granted' count=grantCount}}</div>
|
||||
<div class='grant-count'>{{i18n 'badges.granted' count=grantCount}}</div>
|
||||
{{/unless}}
|
||||
<div class='info'>{{i18n 'badges.allow_title'}} {{{view.allowTitle}}}<br>{{i18n 'badges.multiple_grant'}} {{{view.multipleGrant}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{{#if user}}
|
||||
<div class='badge-user-info'>
|
||||
{{#link-to 'user' user}}
|
||||
{{avatar user imageSize="extra_large"}}
|
||||
<div class="details clearfix">
|
||||
<div class='username'>{{user.username}}</div>
|
||||
</div>
|
||||
{{/link-to}}
|
||||
<div class='earned'>
|
||||
{{i18n 'badges.earned_n_times' count=grantCount}}
|
||||
{{i18n 'badges.earned_n_times' count=grantCount}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if userBadges}}
|
||||
<div class={{unbound layoutClass}}>
|
||||
{{#each ub in userBadges}}
|
||||
<div class="badge-user">
|
||||
{{#if user}}
|
||||
{{format-date ub.granted_at}}
|
||||
{{else}}
|
||||
{{#link-to 'user' ub.user classNames="badge-info"}}
|
||||
{{avatar ub.user imageSize="large"}}
|
||||
<div class="details">
|
||||
<span class="username">{{ub.user.username}}</span>
|
||||
{{format-date ub.granted_at}}
|
||||
</div>
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
|
||||
<div class="user-badges">
|
||||
{{#each userBadges as |ub|}}
|
||||
{{#user-info user=ub.user size="medium" class="badge-info" date=ub.granted_at}}
|
||||
<div class="granted-on">{{i18n 'badges.granted_on' date=(inline-date ub.granted_at)}}</div>
|
||||
{{#if ub.post_number}}
|
||||
<a class="post-link" href="{{unbound ub.topic.url}}/{{unbound ub.post_number}}">{{{ub.topic.fancyTitle}}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/user-info}}
|
||||
{{/each}}
|
||||
|
||||
{{#unless canLoadMore}}
|
||||
{{#if user}}
|
||||
<a class='load-more' href='{{model.url}}'>{{i18n 'badges.more_with_badge'}}</a>
|
||||
{{log model}}
|
||||
<a class='btn' href='{{model.url}}'>{{i18n 'badges.others_count' count=model.grant_count}}</a>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
|
||||
</div>
|
||||
|
||||
{{conditional-loading-spinner condition=canLoadMore}}
|
||||
|
|
|
@ -8,4 +8,11 @@
|
|||
<span class="name">{{unbound name}}</span>
|
||||
</div>
|
||||
<div class="title">{{unbound user.title}}</div>
|
||||
|
||||
{{#if hasBlock}}
|
||||
<div class='details'>
|
||||
{{yield}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
|
@ -18,7 +18,7 @@
|
|||
{{#each model.members as |m|}}
|
||||
<tr>
|
||||
<td class='avatar'>
|
||||
{{user-small user=m}}
|
||||
{{user-info user=m}}
|
||||
{{#if m.owner}}<span class='is-owner'>{{i18n "groups.owner"}}</span>{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{{#each ic in model itemController="directory-item"}}
|
||||
<div class="user {{if ic.me 'me'}}">
|
||||
{{#with ic.model as |it|}}
|
||||
{{user-small user=it.user}}
|
||||
{{user-info user=it.user}}
|
||||
{{user-stat value=it.likes_received label="directory.likes_received" icon="heart"}}
|
||||
{{user-stat value=it.likes_given label="directory.likes_given" icon="heart"}}
|
||||
{{user-stat value=it.topic_count label="directory.topic_count"}}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
{{#each ic in model itemController="directory-item"}}
|
||||
<tr class="{{if ic.me 'me'}}">
|
||||
{{#with ic.model as |it|}}
|
||||
<td>{{user-small user=it.user}}</td>
|
||||
<td>{{user-info user=it.user}}</td>
|
||||
<td>{{number it.likes_received}}</td>
|
||||
<td>{{number it.likes_given}}</td>
|
||||
<td>{{number it.topic_count}}</td>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
.directory {
|
||||
margin-bottom: 100px;
|
||||
|
||||
.user-info {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.period-chooser {
|
||||
float: left;
|
||||
}
|
||||
|
|
|
@ -135,66 +135,23 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.user-info.medium.badge-info {
|
||||
min-height: 80px;
|
||||
|
||||
|
||||
/* /badges/:id/:slug page styling. */
|
||||
.show-badge {
|
||||
.badge-user {
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
.details {
|
||||
margin: 0 10px;
|
||||
padding-top: 3px;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.username {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.date {
|
||||
display: block;
|
||||
color: lighten($primary, 40%);
|
||||
font-size: 0.714em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show-badge .user-badge-with-posts .badge-user {
|
||||
width: 45%;
|
||||
padding: 0 0 0 4%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.badge-info {
|
||||
width: 100px;
|
||||
display: block;
|
||||
float: left;
|
||||
.granted-on {
|
||||
color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
|
||||
}
|
||||
|
||||
.post-link {
|
||||
width: 250px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-left: 18px;
|
||||
text-align: left;
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.show-badge .badge-user-info {
|
||||
margin-left: 2%;
|
||||
.earned {
|
||||
margin-top: 15px;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.username {
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
color: dark-light-choose(scale-color($primary, $lightness: 30%), scale-color($secondary, $lightness: 70%));
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,10 +92,10 @@
|
|||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.user-small {
|
||||
.user-info {
|
||||
display: inline-block;
|
||||
width: 333px;
|
||||
clear: both;
|
||||
margin-bottom: 1em;
|
||||
|
||||
.user-image {
|
||||
float: left;
|
||||
|
@ -128,7 +128,30 @@
|
|||
margin-top: 3px;
|
||||
color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-info.small {
|
||||
width: 333px;
|
||||
}
|
||||
|
||||
.user-info.medium {
|
||||
width: 550px;
|
||||
min-height: 60px;
|
||||
|
||||
.user-image {
|
||||
width: 55px;
|
||||
}
|
||||
.user-detail {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.username, .name {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
color: $primary;
|
||||
}
|
||||
}
|
||||
.user-small {
|
||||
.user-info {
|
||||
width: 245px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2855,7 +2855,8 @@ en:
|
|||
earned_n_times:
|
||||
one: "Earned this badge 1 time"
|
||||
other: "Earned this badge %{count} times"
|
||||
more_with_badge: "Others with this badge"
|
||||
granted_on: "Granted %{date}"
|
||||
others_count: "Others with this badge (%{count})"
|
||||
title: Badges
|
||||
allow_title: "can be used as a title"
|
||||
multiple_grant: "can be awarded multiple times"
|
||||
|
|
|
@ -4,8 +4,8 @@ acceptance("About");
|
|||
test("viewing", () => {
|
||||
visit("/about");
|
||||
andThen(() => {
|
||||
ok(exists('.about.admins .user-small'), 'has admins');
|
||||
ok(exists('.about.moderators .user-small'), 'has moderators');
|
||||
ok(exists('.about.admins .user-info'), 'has admins');
|
||||
ok(exists('.about.moderators .user-info'), 'has moderators');
|
||||
ok(exists('.about.stats tr td'), 'has stats');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue