Skip to content
This repository was archived by the owner on Feb 10, 2022. It is now read-only.

Commit 280155e

Browse files
authored
Merge pull request #10 from sendbird/feature/calls-1218
[CALLS-1218] User ID / Nickname design improvement
2 parents ca57268 + 75a04df commit 280155e

File tree

5 files changed

+139
-63
lines changed

5 files changed

+139
-63
lines changed

lib/components/Header.js

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import SendBirdCall from "sendbird-calls";
22
import BaseElement from "./BaseElement";
3-
import { createDiv } from "../utils/domUtil";
3+
import { createDiv, replaceClassName } from "../utils/domUtil";
44
import Menu from "../components/Menu";
55
import { sheet, classes } from "../css/styles";
66

@@ -32,48 +32,63 @@ export default class Header extends BaseElement {
3232
}
3333

3434
build() {
35-
const userDiv = createDiv({
36-
id: 'header_user_div',
37-
className: `${classes['userDiv']} ${classes['center']}`
38-
});
35+
let userDiv = createDiv({ className: `${classes['userDiv']}` });
3936

4037
let profileImg;
4138
if (this.args.user && this.args.user.profileUrl) {
4239
sheet.update({ profileUrl: this.args.user.profileUrl });
43-
profileImg = createDiv({ id: 'header_profile_img', className: classes['profileSmall'] });
40+
profileImg = createDiv({ className: classes['profileSmall'] });
4441
} else {
45-
profileImg = createDiv({ id: 'header_avatar', className: `${classes['avatar']}` });
42+
profileImg = createDiv({ className: `${classes['avatar']}` });
4643
}
4744

48-
const headerInfo = createDiv({ id: 'header_info', className: `${classes['headerInfo']}` });
49-
const userId = createDiv({
50-
id: 'header_user_id',
51-
className: `${classes['headerUserId']} ${classes['fontMidBig']} ${classes['fontDemi']}`,
52-
innerText: this.args.user.userId || ''
53-
});
45+
const headerInfo = createDiv({ className: `${classes['headerInfo']}` });
5446
const nickname = createDiv({
55-
id: 'header_nickname',
56-
className: `${classes['headerNickname']} ${classes['fontSmall']}`,
57-
innerText: this.args.user.nickname || 'no nickname'
47+
className: `${classes['headerNickname']} ${classes['fontMidBig']} ${classes['fontDemi']}`,
48+
innerText: this.args.user.nickname || '—'
49+
});
50+
const userId = createDiv({
51+
className: `${classes['headerUserId']} ${classes['fontSmall']}`,
52+
innerText: `User ID: ${this.args.user.userId || ''}`
5853
});
59-
headerInfo.appendChild(userId);
6054
headerInfo.appendChild(nickname);
55+
headerInfo.appendChild(userId);
6156

6257
userDiv.appendChild(profileImg);
6358
userDiv.appendChild(headerInfo);
6459

60+
let userDivMenu;
61+
if (!this.args.isWidget) {
62+
const userDetail = userDiv.cloneNode(true);
63+
replaceClassName(userDetail, classes['userDiv'], classes['userDetail']);
64+
65+
userDivMenu = new Menu({
66+
element: userDiv,
67+
items: [
68+
{
69+
element: userDetail
70+
},
71+
{
72+
label: 'Sign out',
73+
callback: () => {
74+
SendBirdCall.deauthenticate();
75+
this.sendToParent('deauthenticate');
76+
}
77+
}
78+
],
79+
divider: createDiv({ className: classes['menuDivider']})
80+
})
81+
}
82+
6583
const headerButtons = createDiv({
66-
id: 'header_buttons',
6784
className: `${classes['headerButtons']} ${classes['row']} ${classes['center']}`
6885
});
6986
const settingsButton = new Menu({
70-
id: 'settings_button',
7187
element: createDiv({ className: `${classes['settingsButton']}` }),
7288
items: this.settingItems
7389
});
7490

7591
const closeButton = createDiv({
76-
id: 'close_button',
7792
className: `${classes['closeButton']}`
7893
});
7994
closeButton.onclick = () => {
@@ -83,15 +98,18 @@ export default class Header extends BaseElement {
8398
headerButtons.appendChild(closeButton);
8499

85100
const divider = createDiv({
86-
id: 'header_divider',
87101
className: classes['headerDivider']
88102
});
89103

90-
this.element.appendChild(userDiv);
104+
if (userDivMenu) {
105+
userDivMenu.appendToBaseElement(this);
106+
} else {
107+
this.element.appendChild(userDiv);
108+
}
91109
this.element.appendChild(divider);
92110
this.element.appendChild(headerButtons);
93111

94-
if(!this.args.isWidget){
112+
if (!this.args.isWidget) {
95113
const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
96114
this.element.appendChild(headerLogo);
97115
}

lib/components/Menu.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import BaseElement from "./BaseElement";
2-
import {createButton, createDiv, createLabel} from "../utils/domUtil";
2+
import { createButton, createDiv, createLabel } from "../utils/domUtil";
33
import { classes } from "../css/styles";
44

55
export default class Menu extends BaseElement {
6-
constructor({ id, className, parent, element, items } = {}) {
6+
constructor({ id, className, divider, parent, element, items } = {}) {
77
super({ id, className, parent, element });
88

99
this.items = items;
10+
this.divider = divider;
1011
this.opened = false;
1112
}
1213

@@ -19,23 +20,32 @@ export default class Menu extends BaseElement {
1920
this.style.backgroundColor = '';
2021
});
2122

22-
this.menuItems = createDiv({ className: `${classes['menuItems']} ${classes['hidden']}` });
23+
this.menuItemsDiv = createDiv({ className: `${classes['menuItemsDiv']} ${classes['hidden']}` });
2324

24-
this.items.forEach((item) => {
25-
const { label, callback } = item;
26-
const labelElem = createLabel({
25+
this.items.forEach((item, idx) => {
26+
const { label, element, callback } = item;
27+
const labelElem = element || createLabel({
2728
className: `${classes['fontNormal']} ${classes['fontHeavy']}`,
2829
innerText: label
2930
});
3031
const itemElem = createButton({ className: `${classes['btn']} ${classes['menuItem']}` });
31-
itemElem.onclick = () => {
32-
callback();
33-
};
32+
33+
if (callback) {
34+
itemElem.onclick = () => {
35+
callback();
36+
};
37+
}
38+
3439
itemElem.appendChild(labelElem);
35-
this.menuItems.appendChild(itemElem);
40+
this.menuItemsDiv.appendChild(itemElem);
41+
42+
if (this.divider && idx < (this.items.length - 1)) {
43+
const divider = this.divider.cloneNode(true);
44+
this.menuItemsDiv.appendChild(divider);
45+
}
3646
});
3747

38-
this.element.appendChild(this.menuItems);
48+
this.element.appendChild(this.menuItemsDiv);
3949
this.element.onclick = (e) => {
4050
e.stopPropagation();
4151
if (this.opened) {
@@ -51,12 +61,12 @@ export default class Menu extends BaseElement {
5161
}
5262

5363
show() {
54-
this.menuItems.classList.remove(classes['hidden']);
64+
this.menuItemsDiv.classList.remove(classes['hidden']);
5565
this.opened = true;
5666
}
5767

5868
hide() {
59-
this.menuItems.classList.add(classes['hidden']);
69+
this.menuItemsDiv.classList.add(classes['hidden']);
6070
this.opened = false;
6171
}
62-
}
72+
}

lib/css/styles.js

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ const styles = {
183183
},
184184

185185
profileSmall: {
186+
flexShrink: '0',
186187
width: '40px',
187188
height: '40px',
188189
borderRadius: '50%',
@@ -1052,16 +1053,13 @@ const styles = {
10521053
}
10531054
},
10541055
'& $userDiv': {
1056+
cursor: 'auto',
10551057
flexDirection: 'row'
10561058
},
10571059
'& $avatar': {
10581060
width: '40px',
10591061
height: '40px'
10601062
},
1061-
'& $profileSmall': {
1062-
width: '40px',
1063-
height: '40px'
1064-
},
10651063
'& $headerDivider': {
10661064
display: 'none'
10671065
},
@@ -1076,7 +1074,7 @@ const styles = {
10761074
'& $closeButton': {
10771075
display: 'block'
10781076
},
1079-
'& $headerNickname': {
1077+
'& $headerUserId': {
10801078
display: 'block',
10811079
},
10821080
'& $formContainer': {
@@ -1132,6 +1130,7 @@ const styles = {
11321130

11331131
userDiv: {
11341132
display: 'flex',
1133+
cursor: 'pointer',
11351134
flexDirection: 'row-reverse'
11361135
},
11371136

@@ -1142,15 +1141,32 @@ const styles = {
11421141
},
11431142

11441143
headerUserId: {
1145-
color: colors.white
1144+
display: 'none',
1145+
wordBreak: 'break-all',
1146+
color: colors.purple50
11461147
},
11471148

11481149
headerNickname: {
1149-
display: 'none',
1150-
color: colors.purple50
1150+
wordBreak: 'break-all',
1151+
color: colors.white
1152+
},
1153+
1154+
userDetail: {
1155+
display: 'flex',
1156+
flexDirection: 'row',
1157+
'& $profileSmall': {
1158+
marginLeft: '0px'
1159+
},
1160+
'& $headerNickname': {
1161+
color: colors.navy900
1162+
},
1163+
'& $headerUserId': {
1164+
color: colors.navy600,
1165+
display: 'block'
1166+
},
11511167
},
11521168

1153-
menuItems: {
1169+
menuItemsDiv: {
11541170
position: 'absolute',
11551171
top: '40px',
11561172
right: '0',
@@ -1173,13 +1189,22 @@ const styles = {
11731189
paddingLeft: '16px',
11741190
paddingRight: '16px',
11751191
width: '100%',
1176-
height: '32px !important',
1192+
height: 'auto',
1193+
minHeight: '32px',
11771194
textAlign: 'left',
11781195
'&:hover': {
11791196
backgroundColor: colors.navy50
11801197
}
11811198
},
11821199

1200+
menuDivider: {
1201+
width: '100%',
1202+
height: '1px',
1203+
marginTop: '8px',
1204+
marginBottom: '8px',
1205+
backgroundColor: colors.navy100
1206+
},
1207+
11831208
headerDivider: {
11841209
width: '1px',
11851210
height: '20px',
@@ -1321,7 +1346,7 @@ const styles = {
13211346
flexDirection: 'row',
13221347
justifyContent: 'flex-start',
13231348
position: 'relative',
1324-
width: '376px',
1349+
width: '100%',
13251350
minHeight: '88px',
13261351
height: 'auto',
13271352
borderTop: 'solid 1px #dee2f2',
@@ -1408,7 +1433,15 @@ const styles = {
14081433
wordBreak: 'break-all',
14091434
},
14101435

1411-
callLogDuration: {
1436+
callLogDisplayId: {
1437+
display: 'inline-flex',
1438+
width: '140px',
1439+
height: 'auto',
1440+
marginLeft: '12px',
1441+
wordBreak: 'break-all',
1442+
},
1443+
1444+
callLogEndInfo: {
14121445
display: 'inline-flex',
14131446
width: '100%',
14141447
height: '16px',

lib/views/CallLogItem.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ export class CallLogItem {
1111
constructor({ callLogInfo, className }) {
1212
if(callLogInfo) {
1313
const wrapper = createListItem({ id: callLogInfo.callId, className: className });
14-
let callType = null;
15-
let callTypeAlt = '';
14+
let callType;
15+
let callTypeAlt;
1616
if(callLogInfo.isVideoCall){
1717
if(callLogInfo.userRole === 'dc_caller'){
1818
callType = outgoingVideo;
@@ -31,14 +31,17 @@ export class CallLogItem {
3131
}
3232
}
3333

34-
let profileImage = null;
35-
let displayName = "";
34+
let profileImage;
35+
let displayName;
36+
let displayId;
3637
if(callLogInfo.userRole === 'dc_caller'){
3738
profileImage = callLogInfo.callee.profileUrl;
38-
displayName = callLogInfo.callee.userId;
39+
displayName = callLogInfo.callee.nickname || '—';
40+
displayId = callLogInfo.callee.userId;
3941
} else {
4042
profileImage = callLogInfo.caller.profileUrl;
41-
displayName = callLogInfo.caller.userId;
43+
displayName = callLogInfo.caller.nickname || '—';
44+
displayId = callLogInfo.caller.userId;
4245
}
4346

4447
const icoCallType = createImg({ className: `${classes['callLogItemType']}`, src: callType, alt: callTypeAlt });
@@ -75,15 +78,24 @@ export class CallLogItem {
7578
callDurationTime = '0s';
7679
}
7780

78-
const displayNameLabel = createLabel({ className: `${classes['callLogDisplayName']} ${classes['fontNormal']} ${classes['fontHeavy']}`, innerText: displayName });
79-
const callDuration = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callDurationTime });
80-
const callEndReason = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callLogInfo.endResult });
81+
const displayNameLabel = createLabel({
82+
className: `${classes['callLogDisplayName']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
83+
innerText: displayName
84+
});
85+
const displayIdLabel = createLabel({
86+
className: `${classes['callLogDisplayId']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
87+
innerText: `User ID: ${displayId}`
88+
});
89+
const callEndInfo = createLabel({
90+
className: `${classes['callLogEndInfo']} ${classes['fontSmall']}`,
91+
innerText: `${callLogInfo.endResult} · ${callDurationTime}`
92+
});
8193

8294

8395
const callLogInfoDiv = createDiv({ className: `${classes['callLogInfoDiv']}` });
8496
callLogInfoDiv.appendChild(displayNameLabel);
85-
callLogInfoDiv.appendChild(callDuration);
86-
callLogInfoDiv.appendChild(callEndReason);
97+
callLogInfoDiv.appendChild(displayIdLabel);
98+
callLogInfoDiv.appendChild(callEndInfo);
8799

88100

89101
let callStartTime = new Date(callLogInfo.startedAt);

0 commit comments

Comments
 (0)