From b2a8f5026780e04732c289e65ca29ed74c6fa76a Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Tue, 12 May 2020 10:46:19 +0900
Subject: [PATCH 01/47] Appling call-log UI design on a quickstart-calls
sample.
1. Add CallLogView Component.
2. Add CallLogItem Component.
3. Add Header Component.
4. Add TabToolBar Component.
5. Add design Images.
6. Call-Log UI Desing apply.
7. when scroll reached to the bottom, get next call log query
---
.gitignore | 1 +
css/main.css | 15 ++
js/main.js | 4 +-
js/widget.js | 4 +-
lib/assets/ic-call-filled-active.svg | 3 +
lib/assets/ic-call-filled-deactive.svg | 3 +
lib/assets/ic-call-filled.svg | 3 +
lib/assets/ic-layout-default-active.svg | 3 +
lib/assets/ic-layout-default-deactive.svg | 3 +
lib/assets/ic-logo-horizontal-inverse-01.svg | 3 +
lib/assets/ic-video-thumbnail-filled.svg | 3 +
.../icon-call-video-incoming-filled.svg | 6 +
.../icon-call-video-outgoing-filled.svg | 6 +
.../icon-call-voice-incoming-filled.svg | 6 +
.../icon-call-voice-outgoing-filled.svg | 6 +
lib/components/App.js | 11 +-
lib/components/Header.js | 91 +++++++
lib/components/MainApp.js | 26 +-
lib/components/TabToolBar.js | 53 ++++
lib/css/styles.js | 252 +++++++++++++++++-
lib/utils/domUtil.js | 19 ++
lib/views/CallLogItem.js | 132 +++++++++
lib/views/CallLogView.js | 54 ++++
lib/views/DialView.js | 102 +------
package-lock.json | 90 +++----
25 files changed, 746 insertions(+), 153 deletions(-)
create mode 100644 lib/assets/ic-call-filled-active.svg
create mode 100644 lib/assets/ic-call-filled-deactive.svg
create mode 100644 lib/assets/ic-call-filled.svg
create mode 100644 lib/assets/ic-layout-default-active.svg
create mode 100644 lib/assets/ic-layout-default-deactive.svg
create mode 100644 lib/assets/ic-logo-horizontal-inverse-01.svg
create mode 100644 lib/assets/ic-video-thumbnail-filled.svg
create mode 100644 lib/assets/icon-call-video-incoming-filled.svg
create mode 100644 lib/assets/icon-call-video-outgoing-filled.svg
create mode 100644 lib/assets/icon-call-voice-incoming-filled.svg
create mode 100644 lib/assets/icon-call-voice-outgoing-filled.svg
create mode 100644 lib/components/Header.js
create mode 100644 lib/components/TabToolBar.js
create mode 100644 lib/views/CallLogItem.js
create mode 100644 lib/views/CallLogView.js
diff --git a/.gitignore b/.gitignore
index 6704566..a6b984d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,3 +102,4 @@ dist
# TernJS port file
.tern-port
+.DS_Store
diff --git a/css/main.css b/css/main.css
index ab66b10..e0a1723 100644
--- a/css/main.css
+++ b/css/main.css
@@ -150,6 +150,7 @@ body {
display: flex;
width: 100vw;
height: 100vh;
+ overflow: hidden;
}
.container {
@@ -253,3 +254,17 @@ button label {
right: 16px;
bottom: 16px;
}
+
+::-webkit-scrollbar {
+ width: 5px; /* 세로축 스크롤바 길이 */
+ }
+ ::-webkit-scrollbar-track {
+ background-color: transparent;
+ }
+ ::-webkit-scrollbar-track-piece {
+ background-color: transparent;
+ }
+ ::-webkit-scrollbar-thumb {
+ border-radius: 8px;
+ background-color: gray;
+ }
diff --git a/js/main.js b/js/main.js
index b4e8c80..1394175 100644
--- a/js/main.js
+++ b/js/main.js
@@ -3,6 +3,7 @@ import MainApp from "../lib/components/MainApp";
import DialView from "../lib/views/DialView";
import CallView from "../lib/views/CallView";
import LoginView from "../lib/views/LoginView";
+import CallLogView from "../lib/views/CallLogView";
import { ACCESS_TOKEN, IS_ACCESS_TOKEN_NEEDED, TEST_APP_ID, USER_ID } from "../envs";
function onLoadedHandler() {
@@ -12,7 +13,8 @@ function onLoadedHandler() {
'index': LoginView,
'login_view': LoginView,
'dial_view': DialView,
- 'call_view': CallView
+ 'call_view': CallView,
+ 'calllog_view': CallLogView
},
styles: {},
args: {
diff --git a/js/widget.js b/js/widget.js
index fcfc1c7..3773281 100644
--- a/js/widget.js
+++ b/js/widget.js
@@ -2,6 +2,7 @@ import "../css/main.css";
import LoginView from "../lib/views/LoginView";
import CallView from "../lib/views/CallView";
import DialView from "../lib/views/DialView";
+import CallLogView from "../lib/views/CallLogView";
import { TEST_APP_ID, USER_ID, ACCESS_TOKEN, IS_ACCESS_TOKEN_NEEDED } from "../envs.js";
import WidgetApp from "../lib/components/WidgetApp";
@@ -13,7 +14,8 @@ function onLoadedHandler() {
'index': LoginView,
'login_view': LoginView,
'dial_view': DialView,
- 'call_view': CallView
+ 'call_view': CallView,
+ 'calllog_view': CallLogView
},
styles: {
},
diff --git a/lib/assets/ic-call-filled-active.svg b/lib/assets/ic-call-filled-active.svg
new file mode 100644
index 0000000..e875484
--- /dev/null
+++ b/lib/assets/ic-call-filled-active.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-call-filled-deactive.svg b/lib/assets/ic-call-filled-deactive.svg
new file mode 100644
index 0000000..115f2a7
--- /dev/null
+++ b/lib/assets/ic-call-filled-deactive.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-call-filled.svg b/lib/assets/ic-call-filled.svg
new file mode 100644
index 0000000..e875484
--- /dev/null
+++ b/lib/assets/ic-call-filled.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-layout-default-active.svg b/lib/assets/ic-layout-default-active.svg
new file mode 100644
index 0000000..78a47c9
--- /dev/null
+++ b/lib/assets/ic-layout-default-active.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-layout-default-deactive.svg b/lib/assets/ic-layout-default-deactive.svg
new file mode 100644
index 0000000..5f4b5bd
--- /dev/null
+++ b/lib/assets/ic-layout-default-deactive.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-logo-horizontal-inverse-01.svg b/lib/assets/ic-logo-horizontal-inverse-01.svg
new file mode 100644
index 0000000..f574caf
--- /dev/null
+++ b/lib/assets/ic-logo-horizontal-inverse-01.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-video-thumbnail-filled.svg b/lib/assets/ic-video-thumbnail-filled.svg
new file mode 100644
index 0000000..677fc23
--- /dev/null
+++ b/lib/assets/ic-video-thumbnail-filled.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/icon-call-video-incoming-filled.svg b/lib/assets/icon-call-video-incoming-filled.svg
new file mode 100644
index 0000000..a408dd3
--- /dev/null
+++ b/lib/assets/icon-call-video-incoming-filled.svg
@@ -0,0 +1,6 @@
+
diff --git a/lib/assets/icon-call-video-outgoing-filled.svg b/lib/assets/icon-call-video-outgoing-filled.svg
new file mode 100644
index 0000000..380a106
--- /dev/null
+++ b/lib/assets/icon-call-video-outgoing-filled.svg
@@ -0,0 +1,6 @@
+
diff --git a/lib/assets/icon-call-voice-incoming-filled.svg b/lib/assets/icon-call-voice-incoming-filled.svg
new file mode 100644
index 0000000..f0cd9cc
--- /dev/null
+++ b/lib/assets/icon-call-voice-incoming-filled.svg
@@ -0,0 +1,6 @@
+
diff --git a/lib/assets/icon-call-voice-outgoing-filled.svg b/lib/assets/icon-call-voice-outgoing-filled.svg
new file mode 100644
index 0000000..9bb0429
--- /dev/null
+++ b/lib/assets/icon-call-voice-outgoing-filled.svg
@@ -0,0 +1,6 @@
+
diff --git a/lib/components/App.js b/lib/components/App.js
index b05beac..b76eff8 100644
--- a/lib/components/App.js
+++ b/lib/components/App.js
@@ -1,5 +1,5 @@
import BaseElement from "./BaseElement";
-import { jss, sheet } from "../css/styles.js";
+import { jss, sheet, classes } from "../css/styles.js";
export default class App extends BaseElement {
constructor({ id, className, pages, styles, args }) {
@@ -30,7 +30,14 @@ export default class App extends BaseElement {
route(pageName, opt = {}) {
for (let i = this.children.length - 1 ; i >= 0 ; i--) {
const child = this.children[i];
- child.remove();
+ if( child.element.id === 'header' || child.element.id === 'tabtoolbar') {
+ if( opt.isRemoveHeader === true ) {
+ child.remove();
+ }
+ }
+ else{
+ child.remove();
+ }
}
const _pageName = this.pages[pageName] ? pageName : 'index';
diff --git a/lib/components/Header.js b/lib/components/Header.js
new file mode 100644
index 0000000..3f35542
--- /dev/null
+++ b/lib/components/Header.js
@@ -0,0 +1,91 @@
+import SendBirdCall from "sendbird-calls";
+import BaseElement from "./BaseElement";
+import { createDiv } from "../utils/domUtil";
+import Menu from "../components/Menu";
+import { sheet, classes } from "../css/styles";
+
+export default class Header extends BaseElement {
+ constructor({ id, className, parent, element, args } = {}) {
+ super({ id, className, parent, element, args });
+ this.element = element;
+ this.parent = parent;
+
+ this.settingItems = [
+ {
+ 'label': 'Device settings',
+ 'callback': () => { this.sendToParent('show_settings') }
+ },
+ {
+ 'label': 'Sign out',
+ 'callback': () => {
+ SendBirdCall.deauthenticate();
+ this.sendToParent('deauthenticate');
+ }
+ }
+ ];
+ }
+
+ build() {
+ const userDiv = createDiv({
+ id: 'header_user_div',
+ className: `${classes['userDiv']} ${classes['center']}`
+ });
+
+ let profileImg;
+ if (this.args.user && this.args.user.profileUrl) {
+ sheet.update({ profileUrl: this.args.user.profileUrl });
+ profileImg = createDiv({ id: 'header_profile_img', className: classes['profileSmall'] });
+ } else {
+ profileImg = createDiv({ id: 'header_avatar', className: `${classes['avatar']}` });
+ }
+
+ const headerInfo = createDiv({ id: 'header_info', className: `${classes['headerInfo']}` });
+ const userId = createDiv({
+ id: 'header_user_id',
+ className: `${classes['headerUserId']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
+ innerText: this.args.user.userId || ''
+ });
+ const nickname = createDiv({
+ id: 'header_nickname',
+ className: `${classes['headerNickname']} ${classes['fontSmall']}`,
+ innerText: this.args.user.nickname || 'no nickname'
+ });
+ headerInfo.appendChild(userId);
+ headerInfo.appendChild(nickname);
+
+ userDiv.appendChild(profileImg);
+ userDiv.appendChild(headerInfo);
+
+ const headerButtons = createDiv({
+ id: 'header_buttons',
+ className: `${classes['headerButtons']} ${classes['row']} ${classes['center']}`
+ });
+ const settingsButton = new Menu({
+ id: 'settings_button',
+ element: createDiv({ className: `${classes['settingsButton']}` }),
+ items: this.settingItems
+ });
+
+ const closeButton = createDiv({
+ id: 'close_button',
+ className: `${classes['closeButton']}`
+ });
+ closeButton.onclick = () => {
+ this.element.sendToParent('widgetclose');
+ };
+ settingsButton.appendToHTML(headerButtons);
+ headerButtons.appendChild(closeButton);
+
+ const divider = createDiv({
+ id: 'header_divider',
+ className: classes['headerDivider']
+ });
+
+ const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
+
+ this.element.appendChild(userDiv);
+ this.element.appendChild(divider);
+ this.element.appendChild(headerButtons);
+ this.element.appendChild(headerLogo);
+ }
+}
\ No newline at end of file
diff --git a/lib/components/MainApp.js b/lib/components/MainApp.js
index cc31ae0..e0b119f 100644
--- a/lib/components/MainApp.js
+++ b/lib/components/MainApp.js
@@ -6,6 +6,10 @@ import { getCallOption } from "../utils/util";
import { Toast } from "./Toast";
import Settings from "../views/Settings";
+import Header from "../components/Header";
+import TabToolBar from "../components/TabToolBar";
+import { createDiv } from "../utils/domUtil";
+
export default class MainApp extends App {
constructor({ id, className, pages, styles, args }) {
const _className = `${classes['mainApp']} ${classes['container']} ${classes['center']} ${className || ''}`;
@@ -97,6 +101,9 @@ export default class MainApp extends App {
this.args.user = user;
if (this.onLoginSuccess) this.onLoginSuccess();
+
+ this.createHeaderNTab();
+
this.route('dial_view', {});
} catch (e) {
if (this.onLoginFailure) this.onLoginFailure(e);
@@ -137,7 +144,7 @@ export default class MainApp extends App {
return undefined;
}
- this.route('call_view', { call: call, state: state });
+ this.route('call_view', { call: call, state: state, isRemoveHeader: true });
}
isBusy() {
@@ -173,6 +180,12 @@ export default class MainApp extends App {
case 'close':
this.recvClose(value);
break;
+ case 'show_calllog':
+ this.route('calllog_view', {});
+ break;
+ case 'show_dial':
+ this.route('dial_view', {});
+ break;
default:
break;
}
@@ -190,7 +203,7 @@ export default class MainApp extends App {
this.args.user = undefined;
this.args.userId = undefined;
this.args.accessToken = undefined;
- this.route('login_view', {});
+ this.route('login_view', { isRemoveHeader: true });
}
recvShowSettings() {
@@ -202,6 +215,15 @@ export default class MainApp extends App {
}
recvClose() {
+ this.createHeaderNTab();
this.route('dial_view', {});
}
+
+ createHeaderNTab() {
+ const HeaderItem = new Header({element: createDiv({ id: 'header', className: `${classes['widgetHeader']}`})});
+ const tabToolBar = new TabToolBar({element: createDiv({id: 'tabtoolbar', className: `${classes['tabToolBar']}`})});
+
+ HeaderItem.appendToBaseElement(this);
+ tabToolBar.appendToBaseElement(this);
+ }
}
\ No newline at end of file
diff --git a/lib/components/TabToolBar.js b/lib/components/TabToolBar.js
new file mode 100644
index 0000000..8367ac7
--- /dev/null
+++ b/lib/components/TabToolBar.js
@@ -0,0 +1,53 @@
+import BaseElement from "./BaseElement";
+import { createDiv, createParagraph, replaceClassName, hasClassName } from "../utils/domUtil";
+import { classes } from "../css/styles";
+
+export default class TabToolBar extends BaseElement {
+ constructor({ id, className, parent, element } = {}) {
+ super({ id, className, parent, element });
+ this.element = element;
+ }
+
+ build() {
+ // dial tab
+ const btnDial = createDiv({id: 'btn_tab_dial', className: `${classes['btnTab']}`});
+ const icoTabDial = createDiv({id: 'ico_tab_dial', className: `${classes['tabIco']} ${classes['dialActive']}`});
+ const btnDialCaption = createParagraph({id: 'btn_dial_caption', innerText: 'dial', className: `${classes['fontNormal']} ${classes['fontHeavy']} ${classes['btnTabCaption']} ${classes['btnTabActive']}`});
+
+ btnDial.appendChild(icoTabDial);
+ btnDial.appendChild(btnDialCaption);
+
+ btnDial.onclick = (ev) => {
+ if(!hasClassName(icoTabDial, classes['dialActive'])) {
+ replaceClassName(icoTabDial, classes['dialDeactive'], classes['dialActive']);
+ replaceClassName(btnDialCaption, classes['btnTabDeactive'], classes['btnTabActive']);
+
+ replaceClassName(icoCallLog, classes['callLogActive'], classes['callLogDeactive']);
+ replaceClassName(btnCalllogCaption, classes['btnTabActive'], classes['btnTabDeactive']);
+ this.sendToParent('show_dial');
+ }
+ };
+
+ const btnCallLog = createDiv({id: 'btn_tab_calllog', className: `${classes['btnTab']}`});
+ const icoCallLog = createDiv({id: 'ico_tab_callog', className: `${classes['tabIco']} ${classes['callLogDeactive']}`});
+ const btnCalllogCaption = createParagraph({id: 'btn_calllog_caption', innerText: 'History', className: `${classes['fontNormal']} ${classes['fontHeavy']} ${classes['btnTabCaption']} ${classes['btnTabDeactive']}`});
+
+ btnCallLog.appendChild(icoCallLog);
+ btnCallLog.appendChild(btnCalllogCaption);
+
+ btnCallLog.onclick = (ev) => {
+ if(!hasClassName(icoCallLog, classes['callLogActive'])) {
+ replaceClassName(icoCallLog, classes['callLogDeactive'], classes['callLogActive']);
+ replaceClassName(btnCalllogCaption, classes['btnTabDeactive'], classes['btnTabActive']);
+
+ replaceClassName(icoTabDial, classes['dialActive'], classes['dialDeactive']);
+ replaceClassName(btnDialCaption, classes['btnTabActive'], classes['btnTabDeactive']);
+
+ this.sendToParent('show_calllog');
+ }
+ };
+
+ this.element.appendChild(btnDial);
+ this.element.appendChild(btnCallLog);
+ }
+}
\ No newline at end of file
diff --git a/lib/css/styles.js b/lib/css/styles.js
index 63ad272..a9d1b48 100644
--- a/lib/css/styles.js
+++ b/lib/css/styles.js
@@ -24,6 +24,15 @@ import settingsCloseIcon from '../assets/ic-close-black-20.svg';
import widgetCloseIcon from '../assets/ic-close-24.svg';
import arrowDownIcon from '../assets/ic-input-arrow-down.svg';
import avatarIcon from '../assets/icon-avatar.svg';
+import dialIconActive from '../assets/ic-call-filled-active.svg';
+import dialIconDeactive from '../assets/ic-call-filled-deactive.svg';
+import callhistoryIconDeactive from '../assets/ic-layout-default-deactive.svg';
+import callhistoryIconActive from '../assets/ic-layout-default-active.svg';
+import headerLogo from '../assets/ic-logo-horizontal-inverse-01.svg';
+import thumbnailVideo from '../assets/ic-video-thumbnail-filled.svg';
+import thumbnailVoice from '../assets/ic-call-filled.svg';
+
+
const option = Object.assign(
{},
@@ -39,9 +48,12 @@ jss.setup(option);
const colors = {
navy50: '#f6f8fc',
+ navy80: '#eef2fa',
navy100: '#dee2f2',
navy200: '#c9d0e6',
navy300: '#b6bdd7',
+ navy400: '#8a92ba',
+ navy600: '#595e8a',
navy800: '#353761',
navy900: '#212242',
white: '#ffffff',
@@ -137,10 +149,13 @@ const styles = {
display: 'flex',
width: '100%',
height: '100%',
+ flexDirection: 'column',
+ justifyContent: 'flex-start',
+ alignItems: 'flex-start',
},
hidden: {
- display: 'none'
+ display: 'none !important'
},
invisible: {
@@ -190,11 +205,21 @@ const styles = {
marginBottom: '24px'
},
+ headerLogo: {
+ display: 'block',
+ width: '100%',
+ height: '24px',
+ backgroundImage: `url(${headerLogo})`,
+ backgroundRepeat: 'no-repeat',
+ marginLeft: '16px'
+ },
+
/*** views ***/
view: {
boxSizing: 'border-box',
- width: '100vw',
+ // width: '100vw',
+ width: '100%',
height: '100%',
padding: '24px',
display: 'relative'
@@ -339,6 +364,71 @@ const styles = {
fontWeight: 600
},
+ /*** tab ***/
+ tabToolBar: {
+ position: 'relative',
+ display: 'inline-flex',
+ justifyContent: 'center',
+ width: '100%',
+ height: '55px',
+ backgroundColor: colors.white,
+ textAlign: 'center',
+ borderBottom: 'solid 1px #dee2f2'
+ },
+
+ btnTab: {
+ display: 'inline-block',
+ width: '100px',
+ height: '55px',
+ cursor: 'pointer'
+ },
+
+ tabIco: {
+ width: '100%',
+ height: '32px',
+ backgroundRepeat: 'no-repeat',
+ backgroundPosition: 'center'
+ },
+
+ dialActive: {
+ backgroundImage: `url(${dialIconActive})`
+ },
+
+ dialDeactive: {
+ backgroundImage: `url(${dialIconDeactive})`
+ },
+
+ btnTabCaption: {
+ width: '100%',
+ height: '12px',
+ margin: 0,
+ lineHeight: 1,
+ textAlign: 'center'
+ },
+
+ icoTabCallLog: {
+ width: '100%',
+ height: '32px',
+ backgroundRepeat: 'no-repeat',
+ backgroundPosition: 'center',
+ },
+
+ callLogActive: {
+ backgroundImage: `url(${callhistoryIconActive})`,
+ },
+
+ callLogDeactive: {
+ backgroundImage: `url(${callhistoryIconDeactive})`,
+ },
+
+ btnTabActive: {
+ color: colors.purple300
+ },
+
+ btnTabDeactive: {
+ color: colors.navy600
+ },
+
/*** components ***/
formContainer: {
@@ -379,6 +469,9 @@ const styles = {
}
},
+ dialTitle: {
+ marginBottom: '16px'
+ },
/*** buttons ***/
loginButton: {
@@ -818,7 +911,10 @@ const styles = {
borderRadius: '8px',
boxShadow: '0 9px 15px -7px rgba(33, 34, 66, 0.04), 0 9px 46px 8px rgba(33, 34, 66, 0.08), 0 24px 38px 3px rgba(33, 34, 66, 0.12)',
backgroundColor: colors.white,
- overflow: 'hidden'
+ overflow: 'hidden',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center'
},
widgetIcon: {
@@ -833,14 +929,13 @@ const styles = {
},
widgetHeader: {
- position: 'absolute',
- top: '0',
- display: 'flex',
+ display: 'inline-flex',
+ position: 'relative',
flexDirection: 'row-reverse',
alignItems: 'center',
width: '100%',
height: '48px',
- backgroundColor: colors.navy800,
+ backgroundColor: colors.purple300,
},
userDiv: {
@@ -916,7 +1011,8 @@ const styles = {
backgroundPosition: 'center',
'&:hover': {
backgroundColor: colors.navy900
- }
+ },
+ zIndex: 10,
},
closeButton: {
@@ -942,6 +1038,10 @@ const styles = {
},
dialDesc: {
+ width: '312px',
+ height: '40px',
+ textAlign: 'center',
+ color: colors.navy400,
marginBottom: '32px'
},
@@ -959,6 +1059,142 @@ const styles = {
backgroundColor: colors.purple300
},
+ /* call Log View */
+ callLogListContainer: {
+ display: 'inline-block',
+ position: 'relative',
+ width: '382px',
+ height: 'calc(100% - 103px)',
+ overflowY: 'auto',
+ listStyle: 'none',
+ margin: '0',
+ padding: '0',
+ },
+
+ /* call Log item */
+ callLogItemWrap: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'flex-start',
+ position: 'relative',
+ width: '376px',
+ minHeight: '88px',
+ height: 'auto',
+ borderRight: 'solid 1px #dee2f2',
+ paddingBottom: '5px',
+ },
+
+ callLogTypeDiv: {
+ display: 'inline-flex',
+ width: '44px',
+ height: '100%'
+ },
+
+ callLogProfileDiv: {
+ display: 'inline-flex',
+ width: '40px',
+ height: '100%'
+ },
+
+ callLogInfoDiv: {
+ display: 'inline-flex',
+ flexDirection: 'column',
+ justifyContent: 'flex-start',
+ width: '156px',
+ height: '100%'
+ },
+
+ callLogActionDiv: {
+ display: 'inline-flex',
+ flexDirection: 'column',
+ justifyContent: 'flex-start',
+ alignItems: 'right',
+ width: '136px',
+ height: '100%'
+ },
+
+ callLogItemWarpBorder: {
+ borderTop: 'solid 1px #dee2f2'
+ },
+
+ callLogItemType: {
+ display: 'block',
+ width: '20px',
+ height: '20px',
+ marginLeft: '18px',
+ marginTop: '26px',
+ },
+
+ callLogProfileImg: {
+ display: 'block',
+ width: '40px',
+ height: '40px',
+ marginTop: '16px',
+ borderRadius: '50%'
+ },
+
+ callLogDisplayName: {
+ display: 'inline-flex',
+ width: '140px',
+ height: 'auto',
+ marginTop: '16px',
+ marginLeft: '12px',
+ wordBreak: 'break-all',
+ },
+
+ callLogDuration: {
+ display: 'inline-flex',
+ width: '100%',
+ height: '16px',
+ marginLeft: '12px',
+ marginTop: '4px',
+ color: colors.navy600
+ },
+
+ callLogStartTime: {
+ display: 'block',
+ width: '120px',
+ height: '16px',
+ textAlign: 'right',
+ marginTop: '16px',
+ marginRight: '16px',
+ color: colors.navy600
+ },
+
+ callLogActionBtnWrap: {
+ display: 'inline-flex',
+ flexDirection: 'row',
+ justifyContent: 'flex-end',
+ width: '136px',
+ height: '56px'
+ },
+
+ callLogVideoActionBtn: {
+ width: '32px',
+ height: '32px',
+ borderRadius: '50%',
+ backgroundImage: `url(${thumbnailVideo})`,
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat',
+ marginRight: '12px',
+ marginTop: '12px',
+ backgroundColor: colors.navy80,
+ cursor: 'pointer'
+ },
+
+ callLogVoiceActionBtn: {
+ width: '32px',
+ height: '32px',
+ borderRadius: '50%',
+ backgroundImage: `url(${thumbnailVoice})`,
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat',
+ marginTop: '12px',
+ marginRight: '16px',
+ backgroundColor: colors.navy80,
+ cursor: 'pointer'
+ },
+
welcomeDiv: {}
};
diff --git a/lib/utils/domUtil.js b/lib/utils/domUtil.js
index 509bb37..0fc9480 100644
--- a/lib/utils/domUtil.js
+++ b/lib/utils/domUtil.js
@@ -124,6 +124,25 @@ export function createImg({ id, className, src, onerror } = {}) {
return element;
}
+export function createParagraph({ id, className, innerText } = {}) {
+ return _createElement({ tagName: 'p', id: id, className: className, innerText: innerText });
+}
+
+export function createList({ id, className } = {}) {
+ return _createElement({ tagName: 'ul', id: id, className: className });
+}
+
+export function createListItem({ id, className } = {}) {
+ return _createElement({ tagName: 'li', id: id, className: className });
+}
+
export function replaceClassName(element, searchValue, newValue) {
element.classList.replace(searchValue, newValue);
+}
+
+export function hasClassName(element, searchValue) {
+ if(element.classList.value.indexOf(searchValue) === -1) {
+ return false;
+ }
+ return true;
}
\ No newline at end of file
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
new file mode 100644
index 0000000..9f61036
--- /dev/null
+++ b/lib/views/CallLogItem.js
@@ -0,0 +1,132 @@
+import SendBirdCall from 'sendbird-calls';
+import outgoingVideo from '../assets/icon-call-video-outgoing-filled.svg';
+import incomingVideo from '../assets/icon-call-video-incoming-filled.svg';
+import outgoingVoice from '../assets/icon-call-voice-outgoing-filled.svg';
+import incomingVoice from '../assets/icon-call-voice-incoming-filled.svg';
+
+import { createListItem, createDiv, createImg, createLabel } from "../utils/domUtil";
+import { sheet, classes } from "../css/styles";
+
+export class CallLogItem {
+ constructor({ callLogInfo, className }) {
+ const wrapper = createListItem({ id: callLogInfo.callId, className: className });
+ let callType = null;
+ if(callLogInfo.isVideoCall){
+ if(callLogInfo.userRole === 'dc_caller'){
+ callType = outgoingVideo;
+ }
+ else{
+ callType = incomingVideo;
+ }
+ }
+ else{
+ if(callLogInfo.userRole === 'dc_caller'){
+ callType = outgoingVoice;
+ }
+ else{
+ callType = incomingVoice;
+ }
+ }
+
+ let profileImage = null;
+ let displayName = "";
+ if(callLogInfo.userRole === 'dc_caller'){
+ profileImage = callLogInfo.callee.profileUrl;
+ displayName = callLogInfo.callee.userId;
+ }
+ else{
+ profileImage = callLogInfo.caller.profileUrl;
+ displayName = callLogInfo.caller.userId;
+ }
+
+ const icoCallType = createImg({ className: `${classes['callLogItemType']}`, src: callType });
+ const callTypeDiv = createDiv({ className: `${classes['callLogTypeDiv']}` });
+ callTypeDiv.appendChild(icoCallType);
+
+ const profileImg = createImg({ className: `${classes['callLogProfileImg']}`, src: profileImage });
+ const profileDiv = createDiv({ className: `${classes['callLogProfileDiv']}` });
+ profileDiv.appendChild(profileImg);
+
+ //duration
+ let callDurationTime = '';
+ callLogInfo.duration = 3603;
+ if(callLogInfo.duration > 0){
+ let hour = parseInt(callLogInfo.duration / 3600);
+ let min = parseInt((callLogInfo.duration - (hour * 3600)) / 60);
+ let sec = callLogInfo.duration - (hour * 3600) - (min * 60);
+ if( hour > 0 ){
+ callDurationTime = hour + 'h ';
+ }
+ if( min > 0 ){
+ callDurationTime += (min + 'm ');
+ }
+ callDurationTime += (sec + 's');
+ }
+ else {
+ callDurationTime = '0s';
+ }
+
+ const displayNameLabel = createLabel({ className: `${classes['callLogDisplayName']} ${classes['fontNormal']} ${classes['fontHeavy']}`, innerText: displayName });
+ const callDuration = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callDurationTime });
+ const callEndReason = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callLogInfo.endResult });
+
+
+ const callLogInfoDiv = createDiv({ className: `${classes['callLogInfoDiv']}` });
+ callLogInfoDiv.appendChild(displayNameLabel);
+ callLogInfoDiv.appendChild(callDuration);
+ callLogInfoDiv.appendChild(callEndReason);
+
+
+ let callStartTime = new Date(callLogInfo.startedAt);
+ let callStartTimeLabel = callStartTime.getFullYear() + '/' +
+ callStartTime.toLocaleString(['en-US'], {month: '2-digit'}) + '/' +
+ callStartTime.toLocaleString(['en-US'], {day: '2-digit'}) + ' ' +
+ this.formatAMPM(callStartTime);
+
+ const callLogStartTime = createLabel({ className: `${classes['callLogStartTime']} ${classes['fontSmall']}`, innerText: callStartTimeLabel});
+ const callActionBtnWrap = createDiv({ className: `${classes['callLogActionBtnWrap']}` });
+ const btnCallVideo = createDiv({ className: `${classes['callLogVideoActionBtn']}`});
+ const btnCallVoice = createDiv({ className: `${classes['callLogVoiceActionBtn']}`});
+ callActionBtnWrap.appendChild(btnCallVoice);
+ callActionBtnWrap.appendChild(btnCallVideo);
+
+
+ const callLogActionDiv = createDiv({ className: `${classes['callLogActionDiv']}` });
+ callLogActionDiv.appendChild(callLogStartTime);
+ callLogActionDiv.appendChild(callActionBtnWrap);
+
+
+ wrapper.appendChild(callTypeDiv);
+ wrapper.appendChild(profileDiv);
+ wrapper.appendChild(callLogInfoDiv);
+ wrapper.appendChild(callLogActionDiv);
+
+ this.element = wrapper;
+ this.btnCallVideo = btnCallVideo;
+ this.btnCallVoice = btnCallVoice;
+ this.destPeerID = displayName;
+ }
+
+ formatAMPM(date) {
+ let hours = date.getHours();
+ let minutes = date.getMinutes();
+ let ampm = hours >= 12 ? 'pm' : 'am';
+ hours = hours % 12;
+ hours = hours ? hours : 12; // the hour '0' should be '12'
+ minutes = minutes < 10 ? '0'+minutes : minutes;
+ let strTime = hours + ':' + minutes + ampm;
+ return strTime;
+ }
+
+ /**
+ * @param {(event: any, args: any) => void} eventhandler
+ */
+ set onclick(eventhandler) {
+ this.btnCallVideo.onclick = (event) => {
+ eventhandler(event, {peerId: this.destPeerID, isVideoCall: true, callOption: null});
+ };
+ this.btnCallVoice.onclick = (event) => {
+ eventhandler(event, {peerId: this.destPeerID, isVideoCall: true, callOption: null});
+ };
+ }
+}
\ No newline at end of file
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
new file mode 100644
index 0000000..500294f
--- /dev/null
+++ b/lib/views/CallLogView.js
@@ -0,0 +1,54 @@
+import SendBirdCall from "sendbird-calls";
+import BaseElement from "../components/BaseElement";
+import { classes } from "../css/styles.js";
+import { createList } from "../utils/domUtil";
+import { CallLogItem } from "./CallLogItem";
+
+export default class CallLogView extends BaseElement{
+ constructor({ args }) {
+ super({
+ id: 'calllog_view',
+ className: `${classes['container']} ${classes['center']} ${classes['viewDial']}`,
+ args
+ });
+ this.callLogQuery = null;
+ this.callLogQueryData = [];
+ }
+
+ build() {
+ const callLogList = createList({ id: 'call_log_list', className: `${classes['callLogListContainer']}` });
+ this.callLogQuery = SendBirdCall.createDirectCallLogListQuery({limit: 30});
+ this.getCallLogs(callLogList);
+ callLogList.onscroll = (e) => {
+ let scrollposition = e.target.scrollHeight - e.target.clientHeight;
+
+ if( scrollposition === e.target.scrollTop ) {
+ this.getCallLogs(callLogList);
+ }
+ };
+ this.element.appendChild(callLogList);
+ }
+
+ getCallLogs(element){
+ if(this.callLogQuery.hasNext && !this.callLogQuery.isLoading) {
+ this.callLogQuery.next((directCallLog) => {
+ if(directCallLog){
+ for(let i = 0; i < directCallLog.length; i++){
+ let callItem = null;
+ if( i === 0 ){
+ callItem = new CallLogItem({callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}`});
+ }
+ else {
+ callItem = new CallLogItem({callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}`});
+ }
+ callItem.onclick = (event, args) => {
+ this.sendToParent('dial', args);
+ };
+
+ element.appendChild(callItem.element);
+ }
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/views/DialView.js b/lib/views/DialView.js
index da4bb2d..1966445 100644
--- a/lib/views/DialView.js
+++ b/lib/views/DialView.js
@@ -1,9 +1,9 @@
import SendBirdCall from "sendbird-calls";
import BaseElement from "../components/BaseElement";
-import { sheet, classes } from "../css/styles.js";
+import { classes } from "../css/styles.js";
import { createButton, createDiv, createInput, createLabel } from "../utils/domUtil";
-import Menu from "../components/Menu";
+
import pack from "../../package";
export default class DialView extends BaseElement {
@@ -13,108 +13,32 @@ export default class DialView extends BaseElement {
className: `${classes['container']} ${classes['column']} ${classes['center']} ${classes['view']} ${classes['viewDial']}`,
args
});
-
- this.settingItems = [
- {
- 'label': 'Device settings',
- 'callback': () => { this.sendToParent('show_settings') }
- },
- {
- 'label': 'Sign out',
- 'callback': () => { this.deauthenticate(); }
- }
- ];
}
onLoaded() {
}
build() {
- const header = createDiv({ id: 'header', className: classes['widgetHeader'] });
-
const content = createDiv({
id: 'content',
className: `${classes['content']} ${classes['column']} ${classes['center']}`
});
-
- const userDiv = createDiv({
- id: 'header_user_div',
- className: `${classes['userDiv']} ${classes['center']}`
- });
-
- let profileImg;
- if (this.args.user && this.args.user.profileUrl) {
- sheet.update({ profileUrl: this.args.user.profileUrl });
- profileImg = createDiv({ id: 'header_profile_img', className: classes['profileSmall'] });
- } else {
- profileImg = createDiv({ id: 'header_avatar', className: `${classes['avatar']}` });
- }
-
- const headerInfo = createDiv({ id: 'header_info', className: `${classes['headerInfo']}` });
- const userId = createDiv({
- id: 'header_user_id',
- className: `${classes['headerUserId']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
- innerText: this.args.user.userId || ''
- });
- const nickname = createDiv({
- id: 'header_nickname',
- className: `${classes['headerNickname']} ${classes['fontSmall']}`,
- innerText: this.args.user.nickname || 'no nickname'
- });
- headerInfo.appendChild(userId);
- headerInfo.appendChild(nickname);
-
- userDiv.appendChild(profileImg);
- userDiv.appendChild(headerInfo);
-
- const headerButtons = createDiv({
- id: 'header_buttons',
- className: `${classes['headerButtons']} ${classes['row']} ${classes['center']}`
- });
- const settingsButton = new Menu({
- id: 'settings_button',
- element: createDiv({ className: `${classes['settingsButton']}` }),
- items: this.settingItems
- });
-
- const closeButton = createDiv({
- id: 'close_button',
- className: `${classes['closeButton']}`
- });
- closeButton.onclick = () => {
- this.sendToParent('widgetclose');
- };
- settingsButton.appendToHTML(headerButtons);
- headerButtons.appendChild(closeButton);
-
- const divider = createDiv({
- id: 'header_divider',
- className: classes['headerDivider']
- });
-
- header.appendChild(userDiv);
- header.appendChild(divider);
- header.appendChild(headerButtons);
-
+
const formContainer = createDiv({
className: `${classes['formContainer']} ${classes['column']} ${classes['center']}`
});
- const logoMid = createDiv({ id: 'logo_oval', className: `${classes['logoMidBlack']}` });
- const welcomeDiv = createDiv({
- id: 'welcome_div',
- className: `${classes['fontBig']} ${classes['fontHeavy']}`,
- innerText: 'SendBird Calls'
- });
- const descDiv = createDiv({
- id: 'desc_div',
- className: `${classes['dialDesc']} ${classes['fontNormal']}`,
- innerText: 'Make a call'
+ const dialTitleDiv = createDiv({ id: 'title', className: `${classes['fontBig']} ${classes['fontDemi']} ${classes['dialTitle']}`, innerText: 'Make a call'});
+ const descDiv = createDiv({id: 'desc_div',
+ innerText: 'Enter the user ID of the user you wish to call, then press one of the video or voice call buttons',
+ className: `${classes['fontNormal']} ${classes['fontHeavy']} ${classes['dialDesc']}`
});
+
const peerId = createInput({
id: 'peer_id',
className: `${classes['field']} ${classes['fontNormal']}`,
- placeholder: 'User ID'
+ placeholder: 'Enter user ID'
});
+
const btns = createDiv({ id: 'buttons', className: `${classes['row']} ${classes['center']} ${classes['btns']}` });
const btnVideo = createButton({
@@ -129,8 +53,7 @@ export default class DialView extends BaseElement {
btns.appendChild(btnVideo);
btns.appendChild(btnAudio);
- formContainer.appendChild(logoMid);
- formContainer.appendChild(welcomeDiv);
+ formContainer.appendChild(dialTitleDiv);
formContainer.appendChild(descDiv);
formContainer.appendChild(peerId);
formContainer.appendChild(btns);
@@ -156,7 +79,6 @@ export default class DialView extends BaseElement {
versionInfo.appendChild(sampleVersionLabel);
versionInfo.appendChild(sdkVersionLabel);
- this.element.appendChild(header);
this.element.appendChild(content);
this.element.appendChild(versionInfo);
@@ -181,4 +103,4 @@ export default class DialView extends BaseElement {
SendBirdCall.deauthenticate();
this.sendToParent('deauthenticate');
}
-}
\ No newline at end of file
+}
diff --git a/package-lock.json b/package-lock.json
index 6e347f8..60bdf4c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1158,9 +1158,9 @@
}
},
"acorn": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz",
- "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==",
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+ "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
"dev": true
},
"ajv": {
@@ -1688,9 +1688,9 @@
"dev": true
},
"cacache": {
- "version": "12.0.3",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
- "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
+ "version": "12.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+ "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
"dev": true,
"requires": {
"bluebird": "^3.5.5",
@@ -1781,9 +1781,9 @@
}
},
"chownr": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
- "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true
},
"chrome-trace-event": {
@@ -2869,9 +2869,9 @@
}
},
"figgy-pudding": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
- "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==",
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+ "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
"dev": true
},
"file-loader": {
@@ -4592,9 +4592,9 @@
"dev": true
},
"kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"dev": true
},
"lcid": {
@@ -4856,9 +4856,9 @@
}
},
"minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"mississippi": {
@@ -4901,20 +4901,12 @@
}
},
"mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
- "minimist": "0.0.8"
- },
- "dependencies": {
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- }
+ "minimist": "^1.2.5"
}
},
"move-concurrently": {
@@ -5472,9 +5464,9 @@
}
},
"portfinder": {
- "version": "1.0.25",
- "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
- "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
+ "version": "1.0.26",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
+ "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==",
"dev": true,
"requires": {
"async": "^2.6.2",
@@ -6460,9 +6452,9 @@
}
},
"source-map-support": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
- "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
@@ -6633,9 +6625,9 @@
}
},
"stream-shift": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
- "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
"dev": true
},
"strict-uri-encode": {
@@ -6742,9 +6734,9 @@
"dev": true
},
"terser": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz",
- "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==",
+ "version": "4.6.13",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz",
+ "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@@ -6767,16 +6759,16 @@
}
},
"terser-webpack-plugin": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz",
- "integrity": "sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
+ "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
"dev": true,
"requires": {
"cacache": "^12.0.2",
"find-cache-dir": "^2.1.0",
"is-wsl": "^1.1.0",
"schema-utils": "^1.0.0",
- "serialize-javascript": "^2.1.1",
+ "serialize-javascript": "^2.1.2",
"source-map": "^0.6.1",
"terser": "^4.1.2",
"webpack-sources": "^1.4.0",
@@ -7665,9 +7657,9 @@
}
},
"yargs-parser": {
- "version": "13.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
- "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
From 61d7724e38d85991ac9db233ded78db30c562ab2 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Wed, 13 May 2020 16:21:26 +0900
Subject: [PATCH 02/47] [CALLS-700]Call history design implementation
1. add call-log view in widget mode
---
lib/assets/ic-layout-default.svg | 3 +
lib/assets/ic-logo-horizontal.svg | 3 +
lib/components/App.js | 2 +-
lib/components/Header.js | 13 ++-
lib/components/MainApp.js | 6 +-
lib/components/TabToolBar.js | 18 ++-
lib/components/WidgetApp.js | 1 +
lib/css/styles.js | 130 +++++++++++++++++++++-
lib/views/CallLogItem.js | 179 ++++++++++++++++--------------
lib/views/CallLogView.js | 62 +++++++----
lib/views/DialView.js | 4 +-
11 files changed, 300 insertions(+), 121 deletions(-)
create mode 100644 lib/assets/ic-layout-default.svg
create mode 100644 lib/assets/ic-logo-horizontal.svg
diff --git a/lib/assets/ic-layout-default.svg b/lib/assets/ic-layout-default.svg
new file mode 100644
index 0000000..da2789d
--- /dev/null
+++ b/lib/assets/ic-layout-default.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/assets/ic-logo-horizontal.svg b/lib/assets/ic-logo-horizontal.svg
new file mode 100644
index 0000000..1c3c7d4
--- /dev/null
+++ b/lib/assets/ic-logo-horizontal.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/components/App.js b/lib/components/App.js
index b76eff8..87c7342 100644
--- a/lib/components/App.js
+++ b/lib/components/App.js
@@ -45,7 +45,7 @@ export default class App extends BaseElement {
const pageClass = this.pages[_pageName];
const view = new pageClass(opt);
view.appendToBaseElement(this);
-
+
if (this.onPageChange) this.onPageChange(_pageName);
}
}
\ No newline at end of file
diff --git a/lib/components/Header.js b/lib/components/Header.js
index 3f35542..c737d7b 100644
--- a/lib/components/Header.js
+++ b/lib/components/Header.js
@@ -23,6 +23,9 @@ export default class Header extends BaseElement {
}
}
];
+
+ this.args = args;
+ this.parent = parent;
}
build() {
@@ -71,7 +74,7 @@ export default class Header extends BaseElement {
className: `${classes['closeButton']}`
});
closeButton.onclick = () => {
- this.element.sendToParent('widgetclose');
+ this.parent.sendToParent('widgetclose');
};
settingsButton.appendToHTML(headerButtons);
headerButtons.appendChild(closeButton);
@@ -81,11 +84,13 @@ export default class Header extends BaseElement {
className: classes['headerDivider']
});
- const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
-
this.element.appendChild(userDiv);
this.element.appendChild(divider);
this.element.appendChild(headerButtons);
- this.element.appendChild(headerLogo);
+
+ if( !this.args.isWidget ){
+ const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
+ this.element.appendChild(headerLogo);
+ }
}
}
\ No newline at end of file
diff --git a/lib/components/MainApp.js b/lib/components/MainApp.js
index e0b119f..56cd421 100644
--- a/lib/components/MainApp.js
+++ b/lib/components/MainApp.js
@@ -181,7 +181,7 @@ export default class MainApp extends App {
this.recvClose(value);
break;
case 'show_calllog':
- this.route('calllog_view', {});
+ this.route('calllog_view', {args: this.args});
break;
case 'show_dial':
this.route('dial_view', {});
@@ -220,8 +220,8 @@ export default class MainApp extends App {
}
createHeaderNTab() {
- const HeaderItem = new Header({element: createDiv({ id: 'header', className: `${classes['widgetHeader']}`})});
- const tabToolBar = new TabToolBar({element: createDiv({id: 'tabtoolbar', className: `${classes['tabToolBar']}`})});
+ const HeaderItem = new Header({parent: this, element: createDiv({ id: 'header', className: `${classes['widgetHeader']}`})});
+ const tabToolBar = new TabToolBar({ parent: this, element: createDiv({id: 'tabtoolbar', className: `${classes['tabToolBar']}`}), args: this.args });
HeaderItem.appendToBaseElement(this);
tabToolBar.appendToBaseElement(this);
diff --git a/lib/components/TabToolBar.js b/lib/components/TabToolBar.js
index 8367ac7..6e011e0 100644
--- a/lib/components/TabToolBar.js
+++ b/lib/components/TabToolBar.js
@@ -3,14 +3,18 @@ import { createDiv, createParagraph, replaceClassName, hasClassName } from "../u
import { classes } from "../css/styles";
export default class TabToolBar extends BaseElement {
- constructor({ id, className, parent, element } = {}) {
+ constructor({ id, className, parent, element, args } = {}) {
super({ id, className, parent, element });
this.element = element;
+ this.args = args;
}
build() {
- // dial tab
- const btnDial = createDiv({id: 'btn_tab_dial', className: `${classes['btnTab']}`});
+ // dial tab
+ if( this.args.isWidget ) {
+ this.element.classList.add(classes['tabToolBarWidget']);
+ }
+ const btnDial = createDiv({ id: 'btn_tab_dial', className: `${classes['btnTab']}` });
const icoTabDial = createDiv({id: 'ico_tab_dial', className: `${classes['tabIco']} ${classes['dialActive']}`});
const btnDialCaption = createParagraph({id: 'btn_dial_caption', innerText: 'dial', className: `${classes['fontNormal']} ${classes['fontHeavy']} ${classes['btnTabCaption']} ${classes['btnTabActive']}`});
@@ -28,6 +32,10 @@ export default class TabToolBar extends BaseElement {
}
};
+ if( this.args.isWidget ) {
+ btnDial.classList.add(classes['btnTabWidget']);
+ }
+
const btnCallLog = createDiv({id: 'btn_tab_calllog', className: `${classes['btnTab']}`});
const icoCallLog = createDiv({id: 'ico_tab_callog', className: `${classes['tabIco']} ${classes['callLogDeactive']}`});
const btnCalllogCaption = createParagraph({id: 'btn_calllog_caption', innerText: 'History', className: `${classes['fontNormal']} ${classes['fontHeavy']} ${classes['btnTabCaption']} ${classes['btnTabDeactive']}`});
@@ -47,6 +55,10 @@ export default class TabToolBar extends BaseElement {
}
};
+ if( this.args.isWidget ) {
+ btnCallLog.classList.add(classes['btnTabWidget']);
+ }
+
this.element.appendChild(btnDial);
this.element.appendChild(btnCallLog);
}
diff --git a/lib/components/WidgetApp.js b/lib/components/WidgetApp.js
index 97b15ee..12070b0 100644
--- a/lib/components/WidgetApp.js
+++ b/lib/components/WidgetApp.js
@@ -63,6 +63,7 @@ export default class WidgetApp extends BaseElement {
build() {
if (!this.widgetIcon) this.widgetIcon = createDiv({ id: 'widget_icon', className: classes['widgetIcon'] });
+ this.args.isWidget = true;
this.mainApp = new MainApp({
className: `${classes['widgetDiv']} ${classes['hidden']}`,
pages: this.pages,
diff --git a/lib/css/styles.js b/lib/css/styles.js
index a9d1b48..29f78c2 100644
--- a/lib/css/styles.js
+++ b/lib/css/styles.js
@@ -31,6 +31,8 @@ import callhistoryIconActive from '../assets/ic-layout-default-active.svg';
import headerLogo from '../assets/ic-logo-horizontal-inverse-01.svg';
import thumbnailVideo from '../assets/ic-video-thumbnail-filled.svg';
import thumbnailVoice from '../assets/ic-call-filled.svg';
+import callLogEmpty from '../assets/ic-layout-default.svg';
+import logoHorizon from '../assets/ic-logo-horizontal.svg';
@@ -250,6 +252,8 @@ const styles = {
viewSettings: {
position: 'absolute',
+ left: '0px',
+ top: '0px',
width: '100%',
height: '100%',
zIndex: '100',
@@ -330,6 +334,19 @@ const styles = {
'-moz-osx-font-smoothing': 'grayscale'
},
+ font16: {
+ fontFamily: 'Avenir Next',
+ fontSize: '16px',
+ fontWeight: 'normal',
+ fontStretch: 'normal',
+ fontStyle: 'normal',
+ lineHeight: '1.25',
+ letterSpacing: '-0.15px',
+ textRendering: 'optimizelegibility',
+ '-webkit-font-smoothing': 'antialiased',
+ '-moz-osx-font-smoothing': 'grayscale'
+ },
+
font20: {
fontFamily: 'Avenir Next',
fontSize: '20px',
@@ -342,6 +359,19 @@ const styles = {
'-moz-osx-font-smoothing': 'grayscale'
},
+ font24: {
+ fontFamily: 'Avenir Next',
+ fontSize: '24px',
+ fontWeight: 'normal',
+ fontStretch: 'normal',
+ fontStyle: 'normal',
+ lineHeight: '1.33',
+ letterSpacing: '-0.25px',
+ textRendering: 'optimizelegibility',
+ '-webkit-font-smoothing': 'antialiased',
+ '-moz-osx-font-smoothing': 'grayscale'
+ },
+
fontBig: {
fontFamily: 'Avenir Next',
height: '32px',
@@ -373,9 +403,19 @@ const styles = {
height: '55px',
backgroundColor: colors.white,
textAlign: 'center',
+ borderTop: 'solid 1px #dee2f2',
borderBottom: 'solid 1px #dee2f2'
},
+ tabToolBarWidget: {
+ position: 'absolute',
+ display: 'inline-block',
+ bottom: '0px',
+ left: '0px',
+ borderBottomLeftRadius: '8px',
+ borderBottomRightRadius: '8px'
+ },
+
btnTab: {
display: 'inline-block',
width: '100px',
@@ -383,6 +423,10 @@ const styles = {
cursor: 'pointer'
},
+ btnTabWidget: {
+ width: '156px',
+ },
+
tabIco: {
width: '100%',
height: '32px',
@@ -841,11 +885,14 @@ const styles = {
}
},
'& $viewDial': {
+ height: 'calc(100% - 136px)',
'& $content': {
- marginTop: '144px'
+ // marginTop: '144px'
+ margin: 'auto'
},
'& $versionInfo': {
- display: 'flex'
+ // display: 'flex'
+ display: 'none'
}
},
'& $widgetHeader': {
@@ -912,9 +959,7 @@ const styles = {
boxShadow: '0 9px 15px -7px rgba(33, 34, 66, 0.04), 0 9px 46px 8px rgba(33, 34, 66, 0.08), 0 24px 38px 3px rgba(33, 34, 66, 0.12)',
backgroundColor: colors.white,
overflow: 'hidden',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center'
+ display: 'block'
},
widgetIcon: {
@@ -1063,14 +1108,61 @@ const styles = {
callLogListContainer: {
display: 'inline-block',
position: 'relative',
- width: '382px',
height: 'calc(100% - 103px)',
+ height: '100%',
overflowY: 'auto',
listStyle: 'none',
margin: '0',
padding: '0',
},
+ callLogListDesc: {
+ display: 'inline-flex',
+ position: 'absolute',
+ width: 'calc(100% - 382px)',
+ height: 'calc(100% - 103px)',
+ margin: '0',
+ padding: '0',
+ right: '0px',
+ justifyContent: 'center',
+ alignItems: 'center',
+ flexDirection: 'column'
+ },
+
+ callLogDescLogo: {
+ display: 'block',
+ position: 'relative',
+ width: '100%',
+ height: '40px',
+ backgroundImage: `url(${logoHorizon})`,
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat'
+ },
+
+ callLogDescTitle: {
+ position: 'relative',
+ width: '100%',
+ height: '32px',
+ textAlign: 'center',
+ marginTop: '24px',
+ color: colors.navy900
+ },
+
+ callLogDescLabel: {
+ position: 'relative',
+ width: '275px',
+ height: '40px',
+ textAlign: 'center',
+ marginTop: '16px',
+ color: colors.navy600
+ },
+
+ widgetCallLog: {
+ height: '100%',
+ width: '100%',
+ overflowX: 'hidden',
+ },
+
/* call Log item */
callLogItemWrap: {
display: 'flex',
@@ -1084,6 +1176,32 @@ const styles = {
paddingBottom: '5px',
},
+ callLogEmptyWrap: {
+ position: 'relative',
+ width: '312px',
+ height: '116px',
+ marginTop: '158px',
+ marginLeft: '32px',
+ },
+
+ icoCallLogEmpty: {
+ display: 'inline-block',
+ width: '100%',
+ height: '64px',
+ backgroundImage: `url(${callLogEmpty})`,
+ backgroundPosition: 'center',
+ backgroundRepeat: 'no-repeat'
+ },
+
+ labelCallLogEmpty: {
+ display: 'inline-block',
+ width: '100%',
+ height: '20px',
+ marginTop: '12px',
+ textAlign: 'center',
+ color: colors.navy600
+ },
+
callLogTypeDiv: {
display: 'inline-flex',
width: '44px',
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
index 9f61036..e6eb6e8 100644
--- a/lib/views/CallLogItem.js
+++ b/lib/views/CallLogItem.js
@@ -9,102 +9,113 @@ import { sheet, classes } from "../css/styles";
export class CallLogItem {
constructor({ callLogInfo, className }) {
- const wrapper = createListItem({ id: callLogInfo.callId, className: className });
- let callType = null;
- if(callLogInfo.isVideoCall){
- if(callLogInfo.userRole === 'dc_caller'){
- callType = outgoingVideo;
+ if(callLogInfo) {
+ const wrapper = createListItem({ id: callLogInfo.callId, className: className });
+ let callType = null;
+ if(callLogInfo.isVideoCall){
+ if(callLogInfo.userRole === 'dc_caller'){
+ callType = outgoingVideo;
+ }
+ else{
+ callType = incomingVideo;
+ }
}
else{
- callType = incomingVideo;
+ if(callLogInfo.userRole === 'dc_caller'){
+ callType = outgoingVoice;
+ }
+ else{
+ callType = incomingVoice;
+ }
}
- }
- else{
+
+ let profileImage = null;
+ let displayName = "";
if(callLogInfo.userRole === 'dc_caller'){
- callType = outgoingVoice;
+ profileImage = callLogInfo.callee.profileUrl;
+ displayName = callLogInfo.callee.userId;
}
else{
- callType = incomingVoice;
+ profileImage = callLogInfo.caller.profileUrl;
+ displayName = callLogInfo.caller.userId;
}
- }
- let profileImage = null;
- let displayName = "";
- if(callLogInfo.userRole === 'dc_caller'){
- profileImage = callLogInfo.callee.profileUrl;
- displayName = callLogInfo.callee.userId;
- }
- else{
- profileImage = callLogInfo.caller.profileUrl;
- displayName = callLogInfo.caller.userId;
- }
-
- const icoCallType = createImg({ className: `${classes['callLogItemType']}`, src: callType });
- const callTypeDiv = createDiv({ className: `${classes['callLogTypeDiv']}` });
- callTypeDiv.appendChild(icoCallType);
-
- const profileImg = createImg({ className: `${classes['callLogProfileImg']}`, src: profileImage });
- const profileDiv = createDiv({ className: `${classes['callLogProfileDiv']}` });
- profileDiv.appendChild(profileImg);
-
- //duration
- let callDurationTime = '';
- callLogInfo.duration = 3603;
- if(callLogInfo.duration > 0){
- let hour = parseInt(callLogInfo.duration / 3600);
- let min = parseInt((callLogInfo.duration - (hour * 3600)) / 60);
- let sec = callLogInfo.duration - (hour * 3600) - (min * 60);
- if( hour > 0 ){
- callDurationTime = hour + 'h ';
+ const icoCallType = createImg({ className: `${classes['callLogItemType']}`, src: callType });
+ const callTypeDiv = createDiv({ className: `${classes['callLogTypeDiv']}` });
+ callTypeDiv.appendChild(icoCallType);
+
+ const profileImg = createImg({ className: `${classes['callLogProfileImg']}`, src: profileImage });
+ const profileDiv = createDiv({ className: `${classes['callLogProfileDiv']}` });
+ profileDiv.appendChild(profileImg);
+
+ //duration
+ let callDurationTime = '';
+ callLogInfo.duration = 3603;
+ if(callLogInfo.duration > 0){
+ let hour = parseInt(callLogInfo.duration / 3600);
+ let min = parseInt((callLogInfo.duration - (hour * 3600)) / 60);
+ let sec = callLogInfo.duration - (hour * 3600) - (min * 60);
+ if( hour > 0 ){
+ callDurationTime = hour + 'h ';
+ }
+ if( min > 0 ){
+ callDurationTime += (min + 'm ');
+ }
+ callDurationTime += (sec + 's');
}
- if( min > 0 ){
- callDurationTime += (min + 'm ');
+ else {
+ callDurationTime = '0s';
}
- callDurationTime += (sec + 's');
- }
- else {
- callDurationTime = '0s';
+
+ const displayNameLabel = createLabel({ className: `${classes['callLogDisplayName']} ${classes['fontNormal']} ${classes['fontHeavy']}`, innerText: displayName });
+ const callDuration = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callDurationTime });
+ const callEndReason = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callLogInfo.endResult });
+
+
+ const callLogInfoDiv = createDiv({ className: `${classes['callLogInfoDiv']}` });
+ callLogInfoDiv.appendChild(displayNameLabel);
+ callLogInfoDiv.appendChild(callDuration);
+ callLogInfoDiv.appendChild(callEndReason);
+
+
+ let callStartTime = new Date(callLogInfo.startedAt);
+ let callStartTimeLabel = callStartTime.getFullYear() + '/' +
+ callStartTime.toLocaleString(['en-US'], {month: '2-digit'}) + '/' +
+ callStartTime.toLocaleString(['en-US'], {day: '2-digit'}) + ' ' +
+ this.formatAMPM(callStartTime);
+
+ const callLogStartTime = createLabel({ className: `${classes['callLogStartTime']} ${classes['fontSmall']}`, innerText: callStartTimeLabel});
+ const callActionBtnWrap = createDiv({ className: `${classes['callLogActionBtnWrap']}` });
+ const btnCallVideo = createDiv({ className: `${classes['callLogVideoActionBtn']}`});
+ const btnCallVoice = createDiv({ className: `${classes['callLogVoiceActionBtn']}`});
+ callActionBtnWrap.appendChild(btnCallVoice);
+ callActionBtnWrap.appendChild(btnCallVideo);
+
+
+ const callLogActionDiv = createDiv({ className: `${classes['callLogActionDiv']}` });
+ callLogActionDiv.appendChild(callLogStartTime);
+ callLogActionDiv.appendChild(callActionBtnWrap);
+
+
+ wrapper.appendChild(callTypeDiv);
+ wrapper.appendChild(profileDiv);
+ wrapper.appendChild(callLogInfoDiv);
+ wrapper.appendChild(callLogActionDiv);
+
+ this.element = wrapper;
+ this.btnCallVideo = btnCallVideo;
+ this.btnCallVoice = btnCallVoice;
+ this.destPeerID = displayName;
}
+ else{
+ const wrapper = createDiv({ id: 'empty_calllog', className: className });
+ const icoCallLogEmpty = createDiv({ className: `${classes['icoCallLogEmpty']}` });
+ const labelCallLogEmpty = createDiv({ innerText: 'No call history', className: `${classes['labelCallLogEmpty']} ${classes['font16']} ${classes['fontHeavy']}` });
+ wrapper.appendChild(icoCallLogEmpty);
+ wrapper.appendChild(labelCallLogEmpty);
- const displayNameLabel = createLabel({ className: `${classes['callLogDisplayName']} ${classes['fontNormal']} ${classes['fontHeavy']}`, innerText: displayName });
- const callDuration = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callDurationTime });
- const callEndReason = createLabel({ className: `${classes['callLogDuration']} ${classes['fontSmall']}`, innerText: callLogInfo.endResult });
-
-
- const callLogInfoDiv = createDiv({ className: `${classes['callLogInfoDiv']}` });
- callLogInfoDiv.appendChild(displayNameLabel);
- callLogInfoDiv.appendChild(callDuration);
- callLogInfoDiv.appendChild(callEndReason);
-
-
- let callStartTime = new Date(callLogInfo.startedAt);
- let callStartTimeLabel = callStartTime.getFullYear() + '/' +
- callStartTime.toLocaleString(['en-US'], {month: '2-digit'}) + '/' +
- callStartTime.toLocaleString(['en-US'], {day: '2-digit'}) + ' ' +
- this.formatAMPM(callStartTime);
-
- const callLogStartTime = createLabel({ className: `${classes['callLogStartTime']} ${classes['fontSmall']}`, innerText: callStartTimeLabel});
- const callActionBtnWrap = createDiv({ className: `${classes['callLogActionBtnWrap']}` });
- const btnCallVideo = createDiv({ className: `${classes['callLogVideoActionBtn']}`});
- const btnCallVoice = createDiv({ className: `${classes['callLogVoiceActionBtn']}`});
- callActionBtnWrap.appendChild(btnCallVoice);
- callActionBtnWrap.appendChild(btnCallVideo);
-
-
- const callLogActionDiv = createDiv({ className: `${classes['callLogActionDiv']}` });
- callLogActionDiv.appendChild(callLogStartTime);
- callLogActionDiv.appendChild(callActionBtnWrap);
-
-
- wrapper.appendChild(callTypeDiv);
- wrapper.appendChild(profileDiv);
- wrapper.appendChild(callLogInfoDiv);
- wrapper.appendChild(callLogActionDiv);
-
- this.element = wrapper;
- this.btnCallVideo = btnCallVideo;
- this.btnCallVoice = btnCallVoice;
- this.destPeerID = displayName;
+ this.element = wrapper;
+ }
}
formatAMPM(date) {
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
index 500294f..2e9a3ca 100644
--- a/lib/views/CallLogView.js
+++ b/lib/views/CallLogView.js
@@ -1,7 +1,7 @@
import SendBirdCall from "sendbird-calls";
import BaseElement from "../components/BaseElement";
import { classes } from "../css/styles.js";
-import { createList } from "../utils/domUtil";
+import { createList, createDiv } from "../utils/domUtil";
import { CallLogItem } from "./CallLogItem";
export default class CallLogView extends BaseElement{
@@ -11,43 +11,67 @@ export default class CallLogView extends BaseElement{
className: `${classes['container']} ${classes['center']} ${classes['viewDial']}`,
args
});
+
this.callLogQuery = null;
this.callLogQueryData = [];
+ this.args = args;
}
build() {
const callLogList = createList({ id: 'call_log_list', className: `${classes['callLogListContainer']}` });
- this.callLogQuery = SendBirdCall.createDirectCallLogListQuery({limit: 30});
+ this.callLogQuery = SendBirdCall.createDirectCallLogListQuery({ limit: 30 });
this.getCallLogs(callLogList);
callLogList.onscroll = (e) => {
let scrollposition = e.target.scrollHeight - e.target.clientHeight;
-
if( scrollposition === e.target.scrollTop ) {
this.getCallLogs(callLogList);
}
};
- this.element.appendChild(callLogList);
+
+ if( this.args.isWidget ) {
+ callLogList.classList.add(classes['widgetCallLog']);
+ this.element.appendChild(callLogList);
+ }
+ else{
+ const callLogDescription = createDiv({ id: 'call_log_desc', className: `${classes['callLogListDesc']}` });
+ const callLogDescLogo = createDiv({ className: `${classes['callLogDescLogo']}` });
+ const callLogDescTitle = createDiv({ innerText: 'Sendbird Calls Quickstart', className: `${classes['callLogDescTitle']} ${classes['font24']} ${classes['fontDemi']}` });
+ const callLogDescLabel = createDiv({ innerText: 'This is the Sendbird Calls Quickstart page. Lorem ipsum', className: `${classes['callLogDescLabel']} ${classes['fontNormal']} ${classes['fontHeavy']}` });
+ callLogDescription.appendChild(callLogDescLogo);
+ callLogDescription.appendChild(callLogDescTitle);
+ callLogDescription.appendChild(callLogDescLabel);
+
+ this.element.appendChild(callLogList);
+ this.element.appendChild(callLogDescription);
+ }
}
getCallLogs(element){
- if(this.callLogQuery.hasNext && !this.callLogQuery.isLoading) {
+ if( this.callLogQuery.hasNext && !this.callLogQuery.isLoading ) {
this.callLogQuery.next((directCallLog) => {
- if(directCallLog){
- for(let i = 0; i < directCallLog.length; i++){
- let callItem = null;
- if( i === 0 ){
- callItem = new CallLogItem({callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}`});
- }
- else {
- callItem = new CallLogItem({callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}`});
+ if( directCallLog ){
+ if( directCallLog.length > 0 ) {
+ for( let i = 0; i < directCallLog.length; i++ ){
+ let callItem = null;
+ if( i === 0 ){
+ callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}` });
+ }
+ else {
+ callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}` });
+ }
+ callItem.onclick = (event, args) => {
+ this.sendToParent('dial', args);
+ };
+
+ element.appendChild(callItem.element);
}
- callItem.onclick = (event, args) => {
- this.sendToParent('dial', args);
- };
-
- element.appendChild(callItem.element);
}
- }
+ else{
+ // empty call log
+ const emptyCallLog = new CallLogItem({ className: `${classes['callLogEmptyWrap']}` });
+ element.appendChild(emptyCallLog.element);
+ }
+ }
});
}
}
diff --git a/lib/views/DialView.js b/lib/views/DialView.js
index 1966445..6222f6d 100644
--- a/lib/views/DialView.js
+++ b/lib/views/DialView.js
@@ -60,6 +60,8 @@ export default class DialView extends BaseElement {
content.appendChild(formContainer);
+ this.element.appendChild(content);
+
const sampleVersion = pack.version;
const sdkVersion = SendBirdCall.sdkVersion;
const versionInfo = createDiv({
@@ -79,7 +81,7 @@ export default class DialView extends BaseElement {
versionInfo.appendChild(sampleVersionLabel);
versionInfo.appendChild(sdkVersionLabel);
- this.element.appendChild(content);
+
this.element.appendChild(versionInfo);
btnVideo.onclick = () => {
From 97f0b93393e2dec7ccffd4196f45b7e151c1d214 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Wed, 13 May 2020 17:06:17 +0900
Subject: [PATCH 03/47] [CALLS-700]Call history design implementation
1. add profile image loading error exception.
---
lib/assets/icon-avatar.jpg | Bin 0 -> 1720 bytes
lib/views/CallLogItem.js | 9 ++++++---
2 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 lib/assets/icon-avatar.jpg
diff --git a/lib/assets/icon-avatar.jpg b/lib/assets/icon-avatar.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f30ff57f88435da4814b975cb064916ca1202c73
GIT binary patch
literal 1720
zcmbV~cTf{q9LHa>DI|)JP!vXr1QhXf=ta43^rDD}Q9%$P(!tO}i8SRzL>X*|r-LYn
zs0W8s%h8*Zqf3(uML^UbMM40Ry$#;r%>Cuuci+DK&inoL_xAJl2lvAxK-|W{+5(_Z
z09YXxfJear^9UbL0Bmi68UR29pf30T4C0U!AdB1pK=)7pLY^q$+CB7oRP`S8-3t?8
z4$wd3%?M?LcryYOwf3k3eG_Y2jIbJ_HLtQ}#e3vZ22#N@%yb;#)+e4x3|s|BB0v?W
zLMSDGCZQk_3a$eR$evi#n$})JCKMXNU~za60&xS9P$CY{Ce~R|=BUj8DrFp_mj_OC9cl(#7Pf*RJ2VnSLwd_WcLh
zIS+FmJF$Lu1qH=C1CZ-Zy>y1B0Vu63gux5BP-vzQoP@z{)4-99?eT6w5=xr!B9bO)S%uXE
ziq_#-Dfi$`qO`L1sLGrWZH?^5z!Lr!**e&Ft|4HGG?q|kWI$*%@~a?37z67ZytF_ZtFL7$Uqq%#
zYN6rA!(qR@Ii;!YkR4Oabc-Q+UY*9bbqMc>ma6D9%9vsV@R_Hl77DT}Bm{3NWn&~y
zn*FqBt>a>#{yRN}qkRJJ-6A(fH}qHZlEDO>ybA*&of`&&^Dq!d;<;A}VL-6U;2Lq9
z&ADP_<9ye&RJ~^Q{F&jGOoO2|mi^=DGAG@a3s3nEtALh`zHL$kxoGRBw5D|MiGkGbKNY$QZTDaT}
zf1>2G)Z9pzI8c4m^v-xQiyAdTx+CHGB6GG}APs|#sCI!sZ1(X)MeRgIBiz9^_Vjdb
z@0kzz=)$fo0KBC!g`{pPUKm}6^Oe#rZ%?F%82{a+apadx2A+_N*MFbU;|ztRdEqHwD$C}RmQ3l+bg5YE0b%q
zuX&;HuTT7$putLAsuB<1SSe;`v0_`KU3HgN2)Lkr}F3#ZYmGEmyzMETXcTUt)-_+_~E;!%lOb&|kTXGOc!k`8Q
zD=0@8unPrJ*)C~*J#eRBlxoC+X45&)NITEs)h`WQ^Zmu8o97<+?9QRcZPKgzN}wp?
zfjF&KE>^5!M@&oXR;nc1R{CXDTeOF~Bjd}W-*2Ag;HD>yEiO~Na6{90s9dyhMW=wm
zTZDmfNL}pWI~a6bzgx10IMXWdQNgjP5d&rUGa8F+XGLdIxz4=Cx#St?j^aH3;sKNA
zJ&d%G()oU}tgc7vKm-2z7U*)laa#ob5|z`}0RuHbN~K5YvYsnGwqH|W!lBiBIy*lA
vX+O%SLOfN}j>vO6@T|!!op}aa9dkZaM8AI}DQ?s<*qZ(+)c)wHc6i_)Dn`%3
literal 0
HcmV?d00001
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
index e6eb6e8..27b90e5 100644
--- a/lib/views/CallLogItem.js
+++ b/lib/views/CallLogItem.js
@@ -1,11 +1,11 @@
-import SendBirdCall from 'sendbird-calls';
import outgoingVideo from '../assets/icon-call-video-outgoing-filled.svg';
import incomingVideo from '../assets/icon-call-video-incoming-filled.svg';
import outgoingVoice from '../assets/icon-call-voice-outgoing-filled.svg';
import incomingVoice from '../assets/icon-call-voice-incoming-filled.svg';
+import avatarIcon from '../assets/icon-avatar.svg';
import { createListItem, createDiv, createImg, createLabel } from "../utils/domUtil";
-import { sheet, classes } from "../css/styles";
+import { classes } from "../css/styles";
export class CallLogItem {
constructor({ callLogInfo, className }) {
@@ -44,7 +44,10 @@ export class CallLogItem {
const callTypeDiv = createDiv({ className: `${classes['callLogTypeDiv']}` });
callTypeDiv.appendChild(icoCallType);
- const profileImg = createImg({ className: `${classes['callLogProfileImg']}`, src: profileImage });
+ const profileImg = createImg({ className: `${classes['callLogProfileImg']}`, src: profileImage, onerror: (error) => {
+ error.currentTarget.src = avatarIcon;
+ } });
+
const profileDiv = createDiv({ className: `${classes['callLogProfileDiv']}` });
profileDiv.appendChild(profileImg);
From 4905a7df157182886a2ed82e33b26981786a8c25 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Wed, 13 May 2020 18:41:33 +0900
Subject: [PATCH 04/47] call duration time bug fixed
1. body tag css is modified
2. dial_view height value is modified.
---
css/main.css | 1 +
lib/css/styles.js | 1 +
lib/views/CallLogItem.js | 8 ++++----
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/css/main.css b/css/main.css
index e0a1723..105941d 100644
--- a/css/main.css
+++ b/css/main.css
@@ -14,6 +14,7 @@
body {
margin: 0 auto;
+ overflow: hidden;
}
.center {
diff --git a/lib/css/styles.js b/lib/css/styles.js
index 29f78c2..f0e6a87 100644
--- a/lib/css/styles.js
+++ b/lib/css/styles.js
@@ -228,6 +228,7 @@ const styles = {
},
viewDial: {
+ height: 'calc(100% - 110px)',
color: colors.navy900,
'& $content': {
marginTop: 'auto'
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
index 27b90e5..efdb626 100644
--- a/lib/views/CallLogItem.js
+++ b/lib/views/CallLogItem.js
@@ -53,11 +53,11 @@ export class CallLogItem {
//duration
let callDurationTime = '';
- callLogInfo.duration = 3603;
if(callLogInfo.duration > 0){
- let hour = parseInt(callLogInfo.duration / 3600);
- let min = parseInt((callLogInfo.duration - (hour * 3600)) / 60);
- let sec = callLogInfo.duration - (hour * 3600) - (min * 60);
+ let tempDuration = Math.ceil(callLogInfo.duration / 1000);
+ let hour = parseInt(tempDuration / 3600);
+ let min = parseInt((tempDuration - (hour * 3600)) / 60);
+ let sec = tempDuration - (hour * 3600) - (min * 60);
if( hour > 0 ){
callDurationTime = hour + 'h ';
}
From 79509241a4c9bc6a0f34a3def45a89191aa35365 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Thu, 14 May 2020 10:49:37 +0900
Subject: [PATCH 05/47] [CALLS-700]Call history design implementation
1. intentation size change.
2. voice call bug fix in the call log
---
lib/components/App.js | 2 +-
lib/components/Header.js | 152 +++++++++++++++++++--------------------
lib/views/CallLogItem.js | 2 +-
lib/views/CallLogView.js | 122 +++++++++++++++----------------
4 files changed, 139 insertions(+), 139 deletions(-)
diff --git a/lib/components/App.js b/lib/components/App.js
index 87c7342..bbed294 100644
--- a/lib/components/App.js
+++ b/lib/components/App.js
@@ -1,5 +1,5 @@
import BaseElement from "./BaseElement";
-import { jss, sheet, classes } from "../css/styles.js";
+import { jss, sheet } from "../css/styles.js";
export default class App extends BaseElement {
constructor({ id, className, pages, styles, args }) {
diff --git a/lib/components/Header.js b/lib/components/Header.js
index c737d7b..4c0d1b1 100644
--- a/lib/components/Header.js
+++ b/lib/components/Header.js
@@ -5,92 +5,92 @@ import Menu from "../components/Menu";
import { sheet, classes } from "../css/styles";
export default class Header extends BaseElement {
- constructor({ id, className, parent, element, args } = {}) {
- super({ id, className, parent, element, args });
- this.element = element;
- this.parent = parent;
+ constructor({ id, className, parent, element, args } = {}) {
+ super({ id, className, parent, element, args });
+ this.element = element;
+ this.parent = parent;
- this.settingItems = [
- {
- 'label': 'Device settings',
- 'callback': () => { this.sendToParent('show_settings') }
- },
- {
- 'label': 'Sign out',
- 'callback': () => {
- SendBirdCall.deauthenticate();
- this.sendToParent('deauthenticate');
- }
- }
- ];
+ this.settingItems = [
+ {
+ 'label': 'Device settings',
+ 'callback': () => { this.sendToParent('show_settings') }
+ },
+ {
+ 'label': 'Sign out',
+ 'callback': () => {
+ SendBirdCall.deauthenticate();
+ this.sendToParent('deauthenticate');
+ }
+ }
+ ];
- this.args = args;
- this.parent = parent;
- }
+ this.args = args;
+ this.parent = parent;
+ }
- build() {
- const userDiv = createDiv({
- id: 'header_user_div',
- className: `${classes['userDiv']} ${classes['center']}`
- });
+ build() {
+ const userDiv = createDiv({
+ id: 'header_user_div',
+ className: `${classes['userDiv']} ${classes['center']}`
+ });
- let profileImg;
- if (this.args.user && this.args.user.profileUrl) {
- sheet.update({ profileUrl: this.args.user.profileUrl });
- profileImg = createDiv({ id: 'header_profile_img', className: classes['profileSmall'] });
- } else {
- profileImg = createDiv({ id: 'header_avatar', className: `${classes['avatar']}` });
- }
+ let profileImg;
+ if (this.args.user && this.args.user.profileUrl) {
+ sheet.update({ profileUrl: this.args.user.profileUrl });
+ profileImg = createDiv({ id: 'header_profile_img', className: classes['profileSmall'] });
+ } else {
+ profileImg = createDiv({ id: 'header_avatar', className: `${classes['avatar']}` });
+ }
- const headerInfo = createDiv({ id: 'header_info', className: `${classes['headerInfo']}` });
- const userId = createDiv({
- id: 'header_user_id',
- className: `${classes['headerUserId']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
- innerText: this.args.user.userId || ''
- });
- const nickname = createDiv({
- id: 'header_nickname',
- className: `${classes['headerNickname']} ${classes['fontSmall']}`,
- innerText: this.args.user.nickname || 'no nickname'
- });
- headerInfo.appendChild(userId);
- headerInfo.appendChild(nickname);
+ const headerInfo = createDiv({ id: 'header_info', className: `${classes['headerInfo']}` });
+ const userId = createDiv({
+ id: 'header_user_id',
+ className: `${classes['headerUserId']} ${classes['fontNormal']} ${classes['fontHeavy']}`,
+ innerText: this.args.user.userId || ''
+ });
+ const nickname = createDiv({
+ id: 'header_nickname',
+ className: `${classes['headerNickname']} ${classes['fontSmall']}`,
+ innerText: this.args.user.nickname || 'no nickname'
+ });
+ headerInfo.appendChild(userId);
+ headerInfo.appendChild(nickname);
- userDiv.appendChild(profileImg);
- userDiv.appendChild(headerInfo);
+ userDiv.appendChild(profileImg);
+ userDiv.appendChild(headerInfo);
- const headerButtons = createDiv({
- id: 'header_buttons',
- className: `${classes['headerButtons']} ${classes['row']} ${classes['center']}`
- });
- const settingsButton = new Menu({
- id: 'settings_button',
- element: createDiv({ className: `${classes['settingsButton']}` }),
- items: this.settingItems
- });
+ const headerButtons = createDiv({
+ id: 'header_buttons',
+ className: `${classes['headerButtons']} ${classes['row']} ${classes['center']}`
+ });
+ const settingsButton = new Menu({
+ id: 'settings_button',
+ element: createDiv({ className: `${classes['settingsButton']}` }),
+ items: this.settingItems
+ });
- const closeButton = createDiv({
- id: 'close_button',
- className: `${classes['closeButton']}`
- });
- closeButton.onclick = () => {
- this.parent.sendToParent('widgetclose');
- };
- settingsButton.appendToHTML(headerButtons);
- headerButtons.appendChild(closeButton);
+ const closeButton = createDiv({
+ id: 'close_button',
+ className: `${classes['closeButton']}`
+ });
+ closeButton.onclick = () => {
+ this.parent.sendToParent('widgetclose');
+ };
+ settingsButton.appendToHTML(headerButtons);
+ headerButtons.appendChild(closeButton);
- const divider = createDiv({
- id: 'header_divider',
- className: classes['headerDivider']
- });
+ const divider = createDiv({
+ id: 'header_divider',
+ className: classes['headerDivider']
+ });
- this.element.appendChild(userDiv);
- this.element.appendChild(divider);
- this.element.appendChild(headerButtons);
+ this.element.appendChild(userDiv);
+ this.element.appendChild(divider);
+ this.element.appendChild(headerButtons);
- if( !this.args.isWidget ){
- const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
- this.element.appendChild(headerLogo);
- }
+ if( !this.args.isWidget ){
+ const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
+ this.element.appendChild(headerLogo);
}
+ }
}
\ No newline at end of file
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
index efdb626..4a689ab 100644
--- a/lib/views/CallLogItem.js
+++ b/lib/views/CallLogItem.js
@@ -140,7 +140,7 @@ export class CallLogItem {
eventhandler(event, {peerId: this.destPeerID, isVideoCall: true, callOption: null});
};
this.btnCallVoice.onclick = (event) => {
- eventhandler(event, {peerId: this.destPeerID, isVideoCall: true, callOption: null});
+ eventhandler(event, {peerId: this.destPeerID, isVideoCall: false, callOption: null});
};
}
}
\ No newline at end of file
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
index 2e9a3ca..eecc113 100644
--- a/lib/views/CallLogView.js
+++ b/lib/views/CallLogView.js
@@ -5,74 +5,74 @@ import { createList, createDiv } from "../utils/domUtil";
import { CallLogItem } from "./CallLogItem";
export default class CallLogView extends BaseElement{
- constructor({ args }) {
- super({
- id: 'calllog_view',
- className: `${classes['container']} ${classes['center']} ${classes['viewDial']}`,
- args
- });
+ constructor({ args }) {
+ super({
+ id: 'calllog_view',
+ className: `${classes['container']} ${classes['center']} ${classes['viewDial']}`,
+ args
+ });
- this.callLogQuery = null;
- this.callLogQueryData = [];
- this.args = args;
- }
+ this.callLogQuery = null;
+ this.callLogQueryData = [];
+ this.args = args;
+ }
- build() {
- const callLogList = createList({ id: 'call_log_list', className: `${classes['callLogListContainer']}` });
- this.callLogQuery = SendBirdCall.createDirectCallLogListQuery({ limit: 30 });
+ build() {
+ const callLogList = createList({ id: 'call_log_list', className: `${classes['callLogListContainer']}` });
+ this.callLogQuery = SendBirdCall.createDirectCallLogListQuery({ limit: 30 });
+ this.getCallLogs(callLogList);
+ callLogList.onscroll = (e) => {
+ let scrollposition = e.target.scrollHeight - e.target.clientHeight;
+ if( scrollposition === e.target.scrollTop ) {
this.getCallLogs(callLogList);
- callLogList.onscroll = (e) => {
- let scrollposition = e.target.scrollHeight - e.target.clientHeight;
- if( scrollposition === e.target.scrollTop ) {
- this.getCallLogs(callLogList);
- }
- };
+ }
+ };
- if( this.args.isWidget ) {
- callLogList.classList.add(classes['widgetCallLog']);
- this.element.appendChild(callLogList);
- }
- else{
- const callLogDescription = createDiv({ id: 'call_log_desc', className: `${classes['callLogListDesc']}` });
- const callLogDescLogo = createDiv({ className: `${classes['callLogDescLogo']}` });
- const callLogDescTitle = createDiv({ innerText: 'Sendbird Calls Quickstart', className: `${classes['callLogDescTitle']} ${classes['font24']} ${classes['fontDemi']}` });
- const callLogDescLabel = createDiv({ innerText: 'This is the Sendbird Calls Quickstart page. Lorem ipsum', className: `${classes['callLogDescLabel']} ${classes['fontNormal']} ${classes['fontHeavy']}` });
- callLogDescription.appendChild(callLogDescLogo);
- callLogDescription.appendChild(callLogDescTitle);
- callLogDescription.appendChild(callLogDescLabel);
+ if( this.args.isWidget ) {
+ callLogList.classList.add(classes['widgetCallLog']);
+ this.element.appendChild(callLogList);
+ }
+ else{
+ const callLogDescription = createDiv({ id: 'call_log_desc', className: `${classes['callLogListDesc']}` });
+ const callLogDescLogo = createDiv({ className: `${classes['callLogDescLogo']}` });
+ const callLogDescTitle = createDiv({ innerText: 'Sendbird Calls Quickstart', className: `${classes['callLogDescTitle']} ${classes['font24']} ${classes['fontDemi']}` });
+ const callLogDescLabel = createDiv({ innerText: 'This is the Sendbird Calls Quickstart page. Lorem ipsum', className: `${classes['callLogDescLabel']} ${classes['fontNormal']} ${classes['fontHeavy']}` });
+ callLogDescription.appendChild(callLogDescLogo);
+ callLogDescription.appendChild(callLogDescTitle);
+ callLogDescription.appendChild(callLogDescLabel);
- this.element.appendChild(callLogList);
- this.element.appendChild(callLogDescription);
- }
+ this.element.appendChild(callLogList);
+ this.element.appendChild(callLogDescription);
}
+ }
+
+ getCallLogs(element){
+ if( this.callLogQuery.hasNext && !this.callLogQuery.isLoading ) {
+ this.callLogQuery.next((directCallLog) => {
+ if( directCallLog ){
+ if( directCallLog.length > 0 ) {
+ for( let i = 0; i < directCallLog.length; i++ ){
+ let callItem = null;
+ if( i === 0 ){
+ callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}` });
+ }
+ else {
+ callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}` });
+ }
+ callItem.onclick = (event, args) => {
+ this.sendToParent('dial', args);
+ };
- getCallLogs(element){
- if( this.callLogQuery.hasNext && !this.callLogQuery.isLoading ) {
- this.callLogQuery.next((directCallLog) => {
- if( directCallLog ){
- if( directCallLog.length > 0 ) {
- for( let i = 0; i < directCallLog.length; i++ ){
- let callItem = null;
- if( i === 0 ){
- callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}` });
- }
- else {
- callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}` });
- }
- callItem.onclick = (event, args) => {
- this.sendToParent('dial', args);
- };
-
- element.appendChild(callItem.element);
- }
- }
- else{
- // empty call log
- const emptyCallLog = new CallLogItem({ className: `${classes['callLogEmptyWrap']}` });
- element.appendChild(emptyCallLog.element);
- }
- }
- });
+ element.appendChild(callItem.element);
+ }
+ }
+ else{
+ // empty call log
+ const emptyCallLog = new CallLogItem({ className: `${classes['callLogEmptyWrap']}` });
+ element.appendChild(emptyCallLog.element);
+ }
}
+ });
}
+ }
}
\ No newline at end of file
From 099236104383e24c5366341a2eb7b2c87cbd63f5 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Thu, 14 May 2020 17:04:14 +0900
Subject: [PATCH 06/47] Update lib/views/CallLogView.js
Co-authored-by: Dongjin Jung
---
lib/views/CallLogView.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
index eecc113..8b15fd2 100644
--- a/lib/views/CallLogView.js
+++ b/lib/views/CallLogView.js
@@ -47,7 +47,7 @@ export default class CallLogView extends BaseElement{
}
getCallLogs(element){
- if( this.callLogQuery.hasNext && !this.callLogQuery.isLoading ) {
+ if (!this.callLogQuery.hasNext || this.callLogQuery.isLoading) return;
this.callLogQuery.next((directCallLog) => {
if( directCallLog ){
if( directCallLog.length > 0 ) {
@@ -75,4 +75,4 @@ export default class CallLogView extends BaseElement{
});
}
}
-}
\ No newline at end of file
+}
From d935e8e18ddc3e6ce399b75fb1e35a5291094b13 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Thu, 14 May 2020 17:10:04 +0900
Subject: [PATCH 07/47] Update lib/utils/domUtil.js
Co-authored-by: Dongjin Jung
---
lib/utils/domUtil.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/utils/domUtil.js b/lib/utils/domUtil.js
index 0fc9480..ea71674 100644
--- a/lib/utils/domUtil.js
+++ b/lib/utils/domUtil.js
@@ -141,8 +141,8 @@ export function replaceClassName(element, searchValue, newValue) {
}
export function hasClassName(element, searchValue) {
- if(element.classList.value.indexOf(searchValue) === -1) {
+ return (element.classList.value.indexOf(searchValue) !== -1);
return false;
}
return true;
-}
\ No newline at end of file
+}
From 31efa8a40c3cffe06d60be9e425ad15c6a382e23 Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Thu, 14 May 2020 17:19:16 +0900
Subject: [PATCH 08/47] Update lib/views/CallLogView.js
Co-authored-by: Dongjin Jung
---
lib/views/CallLogView.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
index 8b15fd2..762bb33 100644
--- a/lib/views/CallLogView.js
+++ b/lib/views/CallLogView.js
@@ -49,7 +49,7 @@ export default class CallLogView extends BaseElement{
getCallLogs(element){
if (!this.callLogQuery.hasNext || this.callLogQuery.isLoading) return;
this.callLogQuery.next((directCallLog) => {
- if( directCallLog ){
+ if (!directCallLog) return;
if( directCallLog.length > 0 ) {
for( let i = 0; i < directCallLog.length; i++ ){
let callItem = null;
From 1f00f8f327b221753a5d2e9f4b0327b8cc994b6b Mon Sep 17 00:00:00 2001
From: danney-chun <63285271+danney-chun@users.noreply.github.com>
Date: Thu, 14 May 2020 17:34:44 +0900
Subject: [PATCH 09/47] [CALLS-700]Call history design implementation
review apply
---
lib/components/App.js | 4 ++--
lib/components/Header.js | 2 +-
lib/components/TabToolBar.js | 6 +++---
lib/css/styles.js | 1 -
lib/views/CallLogItem.js | 7 +++----
lib/views/CallLogView.js | 15 +++++++--------
6 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/lib/components/App.js b/lib/components/App.js
index bbed294..3448407 100644
--- a/lib/components/App.js
+++ b/lib/components/App.js
@@ -30,8 +30,8 @@ export default class App extends BaseElement {
route(pageName, opt = {}) {
for (let i = this.children.length - 1 ; i >= 0 ; i--) {
const child = this.children[i];
- if( child.element.id === 'header' || child.element.id === 'tabtoolbar') {
- if( opt.isRemoveHeader === true ) {
+ if(child.element.id === 'header' || child.element.id === 'tabtoolbar') {
+ if(opt.isRemoveHeader === true) {
child.remove();
}
}
diff --git a/lib/components/Header.js b/lib/components/Header.js
index 4c0d1b1..a2096b1 100644
--- a/lib/components/Header.js
+++ b/lib/components/Header.js
@@ -88,7 +88,7 @@ export default class Header extends BaseElement {
this.element.appendChild(divider);
this.element.appendChild(headerButtons);
- if( !this.args.isWidget ){
+ if(!this.args.isWidget){
const headerLogo = createDiv({ id: 'header_logo', className: `${classes['headerLogo']}`});
this.element.appendChild(headerLogo);
}
diff --git a/lib/components/TabToolBar.js b/lib/components/TabToolBar.js
index 6e011e0..364f419 100644
--- a/lib/components/TabToolBar.js
+++ b/lib/components/TabToolBar.js
@@ -11,7 +11,7 @@ export default class TabToolBar extends BaseElement {
build() {
// dial tab
- if( this.args.isWidget ) {
+ if(this.args.isWidget) {
this.element.classList.add(classes['tabToolBarWidget']);
}
const btnDial = createDiv({ id: 'btn_tab_dial', className: `${classes['btnTab']}` });
@@ -32,7 +32,7 @@ export default class TabToolBar extends BaseElement {
}
};
- if( this.args.isWidget ) {
+ if(this.args.isWidget) {
btnDial.classList.add(classes['btnTabWidget']);
}
@@ -55,7 +55,7 @@ export default class TabToolBar extends BaseElement {
}
};
- if( this.args.isWidget ) {
+ if(this.args.isWidget) {
btnCallLog.classList.add(classes['btnTabWidget']);
}
diff --git a/lib/css/styles.js b/lib/css/styles.js
index f0e6a87..c294e7d 100644
--- a/lib/css/styles.js
+++ b/lib/css/styles.js
@@ -1109,7 +1109,6 @@ const styles = {
callLogListContainer: {
display: 'inline-block',
position: 'relative',
- height: 'calc(100% - 103px)',
height: '100%',
overflowY: 'auto',
listStyle: 'none',
diff --git a/lib/views/CallLogItem.js b/lib/views/CallLogItem.js
index 4a689ab..4b2e34c 100644
--- a/lib/views/CallLogItem.js
+++ b/lib/views/CallLogItem.js
@@ -58,15 +58,14 @@ export class CallLogItem {
let hour = parseInt(tempDuration / 3600);
let min = parseInt((tempDuration - (hour * 3600)) / 60);
let sec = tempDuration - (hour * 3600) - (min * 60);
- if( hour > 0 ){
+ if(hour > 0){
callDurationTime = hour + 'h ';
}
- if( min > 0 ){
+ if(min > 0){
callDurationTime += (min + 'm ');
}
callDurationTime += (sec + 's');
- }
- else {
+ } else {
callDurationTime = '0s';
}
diff --git a/lib/views/CallLogView.js b/lib/views/CallLogView.js
index eecc113..88a4371 100644
--- a/lib/views/CallLogView.js
+++ b/lib/views/CallLogView.js
@@ -23,12 +23,12 @@ export default class CallLogView extends BaseElement{
this.getCallLogs(callLogList);
callLogList.onscroll = (e) => {
let scrollposition = e.target.scrollHeight - e.target.clientHeight;
- if( scrollposition === e.target.scrollTop ) {
+ if(scrollposition === e.target.scrollTop) {
this.getCallLogs(callLogList);
}
};
- if( this.args.isWidget ) {
+ if(this.args.isWidget) {
callLogList.classList.add(classes['widgetCallLog']);
this.element.appendChild(callLogList);
}
@@ -47,16 +47,15 @@ export default class CallLogView extends BaseElement{
}
getCallLogs(element){
- if( this.callLogQuery.hasNext && !this.callLogQuery.isLoading ) {
+ if(this.callLogQuery.hasNext && !this.callLogQuery.isLoading) {
this.callLogQuery.next((directCallLog) => {
- if( directCallLog ){
- if( directCallLog.length > 0 ) {
+ if(directCallLog){
+ if(directCallLog.length > 0) {
for( let i = 0; i < directCallLog.length; i++ ){
let callItem = null;
- if( i === 0 ){
+ if(i === 0){
callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']}` });
- }
- else {
+ } else {
callItem = new CallLogItem({ callLogInfo: directCallLog[i], className: `${classes['callLogItemWrap']} ${classes['callLogItemWarpBorder']}` });
}
callItem.onclick = (event, args) => {
From d013352ac5007d70826d4285be92ea60da44b732 Mon Sep 17 00:00:00 2001
From: Cobb Jung
Date: Thu, 14 May 2020 18:06:18 +0900
Subject: [PATCH 10/47] Update gitignore
Add Editor configuration files into gitignore.
Editors : Webstorm, VSCode
---
.gitignore | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/.gitignore b/.gitignore
index 6704566..6de2d07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,3 +102,7 @@ dist
# TernJS port file
.tern-port
+
+# Editor configuration files
+.idea/
+.vscode/
From 94471f14dac4757d2c6392878164083874eaca06 Mon Sep 17 00:00:00 2001
From: Cobb Jung
Date: Thu, 14 May 2020 18:18:16 +0900
Subject: [PATCH 11/47] Update logo images
Altered previous logos with new one.
---
img/ic-logo-horizontal-purple-300.svg | 2 +-
lib/assets/ic-logo-black-01.svg | 4 ++--
lib/assets/ic-logo-horizontal-purple-300.svg | 2 +-
lib/assets/ic-logo-inverse-01.svg | 6 +-----
4 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/img/ic-logo-horizontal-purple-300.svg b/img/ic-logo-horizontal-purple-300.svg
index 78d907c..1c3c7d4 100644
--- a/img/ic-logo-horizontal-purple-300.svg
+++ b/img/ic-logo-horizontal-purple-300.svg
@@ -1,3 +1,3 @@
diff --git a/lib/assets/ic-logo-black-01.svg b/lib/assets/ic-logo-black-01.svg
index ddf7ac9..06a28d8 100644
--- a/lib/assets/ic-logo-black-01.svg
+++ b/lib/assets/ic-logo-black-01.svg
@@ -1,3 +1,3 @@
-