-
-
Notifications
You must be signed in to change notification settings - Fork 829
/
UserCard.js
142 lines (119 loc) · 4.03 KB
/
UserCard.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import app from '../../forum/app';
import Component from '../../common/Component';
import humanTime from '../../common/utils/humanTime';
import ItemList from '../../common/utils/ItemList';
import UserControls from '../utils/UserControls';
import username from '../../common/helpers/username';
import Dropdown from '../../common/components/Dropdown';
import Link from '../../common/components/Link';
import AvatarEditor from './AvatarEditor';
import listItems from '../../common/helpers/listItems';
import classList from '../../common/utils/classList';
import Icon from '../../common/components/Icon';
import Avatar from '../../common/components/Avatar';
/**
* The `UserCard` component displays a user's profile card. This is used both on
* the `UserPage` (in the hero) and in discussions, shown when hovering over a
* post author.
*
* ### Attrs
*
* - `user`
* - `className`
* - `editable`
* - `controlsButtonClassName`
*/
export default class UserCard extends Component {
view() {
const user = this.attrs.user;
const color = user.color();
return (
<div className={classList('UserCard', this.attrs.className)} style={color && { '--usercard-bg': color }}>
<div className="darkenBackground">
<div className="container">
<div className="UserCard-profile">{this.profileItems().toArray()}</div>
<div className="UserCard-controls">{this.controlsItems().toArray()}</div>
</div>
</div>
</div>
);
}
profileItems() {
const items = new ItemList();
items.add('avatar', this.avatar(), 100);
items.add('content', this.content(), 10);
return items;
}
avatar() {
const user = this.attrs.user;
return this.attrs.editable ? (
<AvatarEditor user={user} className="UserCard-avatar" />
) : (
<Link href={app.route.user(user)}>
<div className="UserCard-avatar">
<Avatar user={user} loading="eager" />
</div>
</Link>
);
}
content() {
return <div className="UserCard-content">{this.contentItems().toArray()}</div>;
}
contentItems() {
const items = new ItemList();
const user = this.attrs.user;
const badges = user.badges().toArray();
items.add('identity', <h1 className="UserCard-identity">{username(user)}</h1>, 100);
if (badges.length) {
items.add('badges', <ul className="UserCard-badges badges">{listItems(badges)}</ul>, 90);
}
items.add('info', <ul className="UserCard-info">{listItems(this.infoItems().toArray())}</ul>, 80);
return items;
}
/**
* Build an item list of tidbits of info to show on this user's profile.
*
* @return {ItemList<import('mithril').Children>}
*/
infoItems() {
const items = new ItemList();
const user = this.attrs.user;
const lastSeenAt = user.lastSeenAt();
if (lastSeenAt) {
const online = user.isOnline();
items.add(
'lastSeen',
<span className={classList('UserCard-lastSeen', { online })}>
{online
? [<Icon name={'fas fa-circle'} />, ' ', app.translator.trans('core.forum.user.online_text')]
: [<Icon name={'far fa-clock'} />, ' ', humanTime(lastSeenAt)]}
</span>,
100
);
}
items.add('joined', app.translator.trans('core.forum.user.joined_date_text', { ago: humanTime(user.joinTime()) }), 90);
return items;
}
controlsItems() {
const items = new ItemList();
const user = this.attrs.user;
const controls = UserControls.controls(user, this).toArray();
if (controls.length) {
items.add(
'controls',
<Dropdown
className="App-primaryControl"
menuClassName="Dropdown-menu--right"
buttonClassName={this.attrs.controlsButtonClassName}
label={app.translator.trans('core.forum.user_controls.button')}
accessibleToggleLabel={app.translator.trans('core.forum.user_controls.toggle_dropdown_accessible_label')}
icon="fas fa-ellipsis-v"
>
{controls}
</Dropdown>,
100
);
}
return items;
}
}