Skip to content

Commit cfd56ab

Browse files
sophiewu2333embbnux
authored andcommitted
Call control flip (#324)
* add flip panel * adjust ui * add call flip * adjust indentation * add cursor style * change key to id * when user confirm to flip then user cannot select flip number * adjust
1 parent d7088a6 commit cfd56ab

File tree

15 files changed

+392
-8
lines changed

15 files changed

+392
-8
lines changed

dev-server/containers/App/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ export default function App({
192192
contactMatcher={phone.contactMatcher}
193193
webphone={phone.webphone}
194194
regionSettings={phone.regionSettings}
195+
forwardingNumber={phone.forwardingNumber}
195196
showContactDisplayPlaceholder={false}
196197
onAdd={() => {
197198
phone.router.push('/');

src/components/ActiveCallPad/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default function ActiveCallPad(props) {
4040
const onRecordClicked = props.isOnRecord ?
4141
props.onStopRecord :
4242
props.onRecord;
43+
const disabledFlip = props.flipNumbers.length === 0;
4344
return (
4445
<div className={classnames(styles.root, props.className)}>
4546
<div className={styles.callCtrlButtonGroup}>
@@ -98,11 +99,11 @@ export default function ActiveCallPad(props) {
9899
className={styles.callButton}
99100
/>
100101
<ActiveCallButton
101-
onClick={props.isOnHold ? () => {} : () => {}}
102+
onClick={(disabledFlip || props.isOnHold) ? () => {} : props.onShowFlipPanel}
102103
title={i18n.getString('flip', props.currentLocale)}
103104
icon={FlipIcon}
104105
className={styles.callButton}
105-
disabled={props.isOnHold}
106+
disabled={disabledFlip || props.isOnHold}
106107
/>
107108
</div>
108109
</div>
@@ -135,6 +136,8 @@ ActiveCallPad.propTypes = {
135136
hangup: PropTypes.func.isRequired,
136137
onShowKeyPad: PropTypes.func.isRequired,
137138
onAdd: PropTypes.func.isRequired,
139+
onShowFlipPanel: PropTypes.func.isRequired,
140+
flipNumbers: PropTypes.array.isRequired,
138141
};
139142

140143
ActiveCallPad.defaultProps = {

src/components/ActiveCallPanel/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,11 @@ function ActiveCallPanel({
110110
onShowKeyPad,
111111
hangup,
112112
onAdd,
113+
onShowFlipPanel,
113114
children,
114115
showContactDisplayPlaceholder,
115116
brand,
117+
flipNumbers
116118
}) {
117119
return (
118120
<div className={styles.root}>
@@ -157,6 +159,8 @@ function ActiveCallPanel({
157159
onShowKeyPad={onShowKeyPad}
158160
hangup={hangup}
159161
onAdd={onAdd}
162+
onShowFlipPanel={onShowFlipPanel}
163+
flipNumbers={flipNumbers}
160164
/>
161165
{children}
162166
</Panel>
@@ -193,6 +197,8 @@ ActiveCallPanel.propTypes = {
193197
backButtonLabel: PropTypes.string,
194198
brand: PropTypes.string,
195199
showContactDisplayPlaceholder: PropTypes.bool,
200+
onShowFlipPanel: PropTypes.func.isRequired,
201+
flipNumbers: PropTypes.array.isRequired,
196202
};
197203

198204
ActiveCallPanel.defaultProps = {
@@ -206,6 +212,7 @@ ActiveCallPanel.defaultProps = {
206212
backButtonLabel: 'Active Calls',
207213
brand: 'RingCentral',
208214
showContactDisplayPlaceholder: true,
215+
flipNumbers: [],
209216
};
210217

211218
export default ActiveCallPanel;

src/components/CallCtrlPanel/index.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import PropTypes from 'prop-types';
33

44
import ActiveCallDialPad from '../ActiveCallDialPad';
55
import ActiveCallPanel from '../ActiveCallPanel';
6+
import FlipPanel from '../FlipPanel';
67

78
class CallCtrlPanel extends Component {
89
constructor(props) {
910
super(props);
1011
this.state = {
1112
isShowKeyPad: false,
13+
isShowFlipPanel: false,
1214
};
1315

1416
this.hiddenKeyPad = () => {
@@ -22,6 +24,18 @@ class CallCtrlPanel extends Component {
2224
isShowKeyPad: true,
2325
});
2426
};
27+
28+
this.showFlipPanel = () => {
29+
this.setState({
30+
isShowFlipPanel: true
31+
});
32+
};
33+
34+
this.hideFlipPanel = () => {
35+
this.setState({
36+
isShowFlipPanel: false
37+
});
38+
};
2539
}
2640

2741
render() {
@@ -35,6 +49,19 @@ class CallCtrlPanel extends Component {
3549
/>
3650
);
3751
}
52+
if (this.state.isShowFlipPanel) {
53+
return (
54+
<FlipPanel
55+
isOnFlip={this.props.isOnFlip}
56+
flipNumbers={this.props.flipNumbers}
57+
currentLocale={this.props.currentLocale}
58+
formatPhone={this.props.formatPhone}
59+
hideFlipPanel={this.hideFlipPanel}
60+
flip={this.props.flip}
61+
hangup={this.props.hangup}
62+
/>
63+
);
64+
}
3865
return (
3966
<ActiveCallPanel
4067
backButtonLabel={this.props.backButtonLabel}
@@ -66,6 +93,8 @@ class CallCtrlPanel extends Component {
6693
avatarUrl={this.props.avatarUrl}
6794
brand={this.props.brand}
6895
showContactDisplayPlaceholder={this.props.showContactDisplayPlaceholder}
96+
onShowFlipPanel={this.showFlipPanel}
97+
flipNumbers={this.props.flipNumbers}
6998
>
7099
{this.props.children}
71100
</ActiveCallPanel>
@@ -84,6 +113,8 @@ CallCtrlPanel.propTypes = {
84113
isOnMute: PropTypes.bool,
85114
isOnHold: PropTypes.bool,
86115
isOnRecord: PropTypes.bool,
116+
isOnFlip: PropTypes.bool,
117+
flipNumbers: PropTypes.array,
87118
onMute: PropTypes.func.isRequired,
88119
onUnmute: PropTypes.func.isRequired,
89120
onHold: PropTypes.func.isRequired,
@@ -92,6 +123,7 @@ CallCtrlPanel.propTypes = {
92123
onStopRecord: PropTypes.func.isRequired,
93124
onAdd: PropTypes.func.isRequired,
94125
hangup: PropTypes.func.isRequired,
126+
flip: PropTypes.func.isRequired,
95127
onBackButtonClick: PropTypes.func.isRequired,
96128
onKeyPadChange: PropTypes.func.isRequired,
97129
formatPhone: PropTypes.func.isRequired,
@@ -111,6 +143,8 @@ CallCtrlPanel.defaultProps = {
111143
isOnMute: false,
112144
isOnHold: false,
113145
isOnRecord: false,
146+
isOnFlip: false,
147+
flipNumbers: [],
114148
phoneNumber: null,
115149
children: undefined,
116150
avatarUrl: null,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
flipHeader: 'Flip call to...',
3+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import I18n from 'ringcentral-integration/lib/I18n';
2+
import loadLocale from './loadLocale';
3+
4+
export default new I18n(loadLocale);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* loadLocale */

src/components/FlipPanel/index.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React, { Component } from 'react';
2+
import classnames from 'classnames';
3+
import PropTypes from 'prop-types';
4+
import BackHeader from '../BackHeader';
5+
import RadioButtonGroup from '../RadioBtnGroup';
6+
import CircleButton from '../CircleButton';
7+
import FlipIcon from '../../assets/images/Flip.svg';
8+
import EndIcon from '../../assets/images/End.svg';
9+
import dynamicsFont from '../../assets/DynamicsFont/DynamicsFont.scss';
10+
import styles from './styles.scss';
11+
import i18n from './i18n';
12+
13+
export default class FlipPanel extends Component {
14+
constructor(props) {
15+
super(props);
16+
this.state = {
17+
flipValue: '',
18+
};
19+
this.onRadioSelect = (value) => {
20+
this.setState({
21+
flipValue: value,
22+
});
23+
};
24+
this.flip = () => {
25+
this.props.flip(this.state.flipValue);
26+
};
27+
}
28+
render() {
29+
return (
30+
<div className={styles.root}>
31+
<BackHeader
32+
onBackClick={this.props.isOnFlip ? () => {} : this.props.hideFlipPanel}
33+
backButton={(
34+
<span className={styles.backButton}>
35+
{
36+
this.props.isOnFlip ? null :
37+
<i className={classnames(dynamicsFont.arrow, styles.backIcon)} />
38+
}
39+
</span>
40+
)}
41+
buttons={[]}
42+
>
43+
{i18n.getString('flipHeader', this.props.currentLocale)}
44+
</BackHeader>
45+
<div className={styles.flipContainer}>
46+
<RadioButtonGroup
47+
className={styles.radioGroup}
48+
radioOptions={this.props.flipNumbers}
49+
disabled={this.props.isOnFlip}
50+
formatPhone={this.props.formatPhone}
51+
onRadioSelect={this.onRadioSelect}
52+
/>
53+
<div className={styles.buttonGroup}>
54+
<div className={styles.button}>
55+
<CircleButton
56+
className={this.props.isOnFlip ? styles.buttonDisabled : styles.flipButton}
57+
iconClassName={styles.flipIcon}
58+
onClick={this.props.isOnFlip ? () => {} : this.flip}
59+
icon={FlipIcon}
60+
showBorder
61+
/>
62+
</div>
63+
<div className={styles.button}>
64+
<CircleButton
65+
className={styles.hangupButton}
66+
iconClassName={styles.hangupIcon}
67+
onClick={this.props.hangup}
68+
icon={EndIcon}
69+
showBorder={false}
70+
/>
71+
</div>
72+
</div>
73+
</div>
74+
</div>
75+
);
76+
}
77+
}
78+
79+
FlipPanel.propTypes = {
80+
isOnFlip: PropTypes.bool.isRequired,
81+
flipNumbers: PropTypes.array.isRequired,
82+
currentLocale: PropTypes.string.isRequired,
83+
formatPhone: PropTypes.func.isRequired,
84+
hideFlipPanel: PropTypes.func.isRequired,
85+
flip: PropTypes.func.isRequired,
86+
hangup: PropTypes.func.isRequired,
87+
};
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
@import '../../lib/commonStyles/colors';
2+
@import '../../lib/commonStyles/full-size';
3+
@import '../../lib/commonStyles/fonts';
4+
5+
.root {
6+
@include full-size;
7+
box-sizing: border-box;
8+
}
9+
10+
.backButton {
11+
color: $lightblack;
12+
13+
.backIcon {
14+
display: inline-block;
15+
transform: rotate(90deg);
16+
margin-top: 5px;
17+
margin-left: 10px;
18+
}
19+
.backLabel {
20+
display: inline-block;
21+
width: 79px;
22+
font-size: 14px;
23+
}
24+
}
25+
26+
.flipContainer {
27+
width: 100%;
28+
height: 100%;
29+
}
30+
31+
.radioGroup{
32+
height: 60%;
33+
overflow-y: scroll;
34+
}
35+
36+
.buttonGroup {
37+
height: 35%;
38+
margin-top: 5%;
39+
text-align: center;
40+
41+
.button{
42+
display: inline-block;
43+
width: calc(100% / 6);
44+
height: 33%;
45+
padding: 0 20px 0 20px;
46+
}
47+
48+
.flipButton {
49+
circle {
50+
stroke: solid 1px #0073ae;
51+
opacity: 0.24;
52+
&:hover {
53+
opacity: 1;
54+
}
55+
}
56+
}
57+
58+
.buttonDisabled {
59+
circle {
60+
fill: $lightgray;
61+
stroke: $gray;
62+
}
63+
path {
64+
fill: $primary-color-highlight-solid;
65+
}
66+
g {
67+
cursor: default;
68+
}
69+
}
70+
71+
.hangupButton {
72+
circle {
73+
fill: #0073ae;
74+
opacity: 0.45;
75+
&:hover {
76+
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.25);
77+
opacity: 1;
78+
}
79+
}
80+
}
81+
82+
.hangupIcon {
83+
path {
84+
fill: $line-background-color
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)