Skip to content

Commit 7779191

Browse files
Eric Huangembbnux
authored andcommitted
Add call recording (#321)
* init recording * add recording in call control page * show messages when recording is disabled * upgrade ringcentral-integration * use i18n string interpolate * fix conflict
1 parent cfd56ab commit 7779191

File tree

9 files changed

+44
-26
lines changed

9 files changed

+44
-26
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
"redux-thunk": "^2.1.0",
8585
"ringcentral": "^3.1.2",
8686
"ringcentral-client": "^1.0.0-rc1",
87-
"ringcentral-integration": "^0.7.0",
87+
"ringcentral-integration": "^0.7.1",
8888
"sass-loader": "^6.0.5",
8989
"source-map-loader": "^0.2.1",
9090
"style-loader": "^0.18.2",

src/components/ActiveCallPad/index.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import classnames from 'classnames';
4+
import recordStatus from 'ringcentral-integration/modules/Webphone/recordStatus';
45
import CircleButton from '../CircleButton';
56
import ActiveCallButton from '../ActiveCallButton';
67
import MuteIcon from '../../assets/images/Mute.svg';
@@ -37,10 +38,15 @@ export default function ActiveCallPad(props) {
3738
const onHoldClicked = props.isOnHold ?
3839
props.onUnhold :
3940
props.onHold;
40-
const onRecordClicked = props.isOnRecord ?
41+
const onRecordClicked = props.recordStatus === recordStatus.recording ?
4142
props.onStopRecord :
4243
props.onRecord;
4344
const disabledFlip = props.flipNumbers.length === 0;
45+
const recordTitle = props.recordStatus === recordStatus.recording ?
46+
i18n.getString('stopRecord', props.currentLocale) :
47+
i18n.getString('record', props.currentLocale);
48+
const isRecordButtonActive = props.recordStatus === recordStatus.recording;
49+
const isRecordDisabled = props.recordStatus === recordStatus.pending;
4450
return (
4551
<div className={classnames(styles.root, props.className)}>
4652
<div className={styles.callCtrlButtonGroup}>
@@ -74,15 +80,11 @@ export default function ActiveCallPad(props) {
7480
/>
7581
<ActiveCallButton
7682
onClick={props.isOnHold ? () => {} : onRecordClicked}
77-
title={
78-
props.isOnRecord ?
79-
i18n.getString('stopRecord', props.currentLocale) :
80-
i18n.getString('record', props.currentLocale)
81-
}
82-
active={props.isOnRecord}
83+
title={recordTitle}
84+
active={isRecordButtonActive}
8385
className={styles.callButton}
8486
icon={RecordIcon}
85-
disabled={props.isOnHold}
87+
disabled={props.isOnHold || isRecordDisabled}
8688
/>
8789
<ActiveCallButton
8890
onClick={props.onAdd}
@@ -126,7 +128,7 @@ ActiveCallPad.propTypes = {
126128
className: PropTypes.string,
127129
isOnMute: PropTypes.bool,
128130
isOnHold: PropTypes.bool,
129-
isOnRecord: PropTypes.bool,
131+
recordStatus: PropTypes.string.isRequired,
130132
onMute: PropTypes.func.isRequired,
131133
onUnmute: PropTypes.func.isRequired,
132134
onHold: PropTypes.func.isRequired,
@@ -144,5 +146,4 @@ ActiveCallPad.defaultProps = {
144146
className: null,
145147
isOnMute: false,
146148
isOnHold: false,
147-
isOnRecord: false,
148149
};

src/components/ActiveCallPanel/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ function ActiveCallPanel({
100100
avatarUrl,
101101
isOnMute,
102102
isOnHold,
103-
isOnRecord,
103+
recordStatus,
104104
onMute,
105105
onUnmute,
106106
onHold,
@@ -149,7 +149,7 @@ function ActiveCallPanel({
149149
currentLocale={currentLocale}
150150
isOnMute={isOnMute}
151151
isOnHold={isOnHold}
152-
isOnRecord={isOnRecord}
152+
recordStatus={recordStatus}
153153
onMute={onMute}
154154
onUnmute={onUnmute}
155155
onHold={onHold}
@@ -176,7 +176,7 @@ ActiveCallPanel.propTypes = {
176176
startTime: PropTypes.number,
177177
isOnMute: PropTypes.bool,
178178
isOnHold: PropTypes.bool,
179-
isOnRecord: PropTypes.bool,
179+
recordStatus: PropTypes.string.isRequired,
180180
onMute: PropTypes.func.isRequired,
181181
onUnmute: PropTypes.func.isRequired,
182182
onHold: PropTypes.func.isRequired,

src/components/CallCtrlPanel/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class CallCtrlPanel extends Component {
7373
startTime={this.props.startTime}
7474
isOnMute={this.props.isOnMute}
7575
isOnHold={this.props.isOnHold}
76-
isOnRecord={this.props.isOnRecord}
76+
recordStatus={this.props.recordStatus}
7777
onBackButtonClick={this.props.onBackButtonClick}
7878
onMute={this.props.onMute}
7979
onUnmute={this.props.onUnmute}
@@ -112,9 +112,9 @@ CallCtrlPanel.propTypes = {
112112
startTime: PropTypes.number,
113113
isOnMute: PropTypes.bool,
114114
isOnHold: PropTypes.bool,
115-
isOnRecord: PropTypes.bool,
116115
isOnFlip: PropTypes.bool,
117116
flipNumbers: PropTypes.array,
117+
recordStatus: PropTypes.string.isRequired,
118118
onMute: PropTypes.func.isRequired,
119119
onUnmute: PropTypes.func.isRequired,
120120
onHold: PropTypes.func.isRequired,

src/components/CircleButton/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ function CircleButton(props) {
2424
styles.circle,
2525
props.showBorder ? null : styles.noBorder
2626
);
27+
const onClick = props.disabled ? () => {} : props.onClick;
2728
return (
2829
<div
2930
className={classnames(styles.root, props.className)}
30-
onClick={props.onClick}
31+
onClick={onClick}
3132
>
3233
<svg className={styles.btnSvg} viewBox="0 0 500 500">
3334
<g
@@ -52,13 +53,15 @@ CircleButton.propTypes = {
5253
showBorder: PropTypes.bool,
5354
iconClassName: PropTypes.string,
5455
onClick: PropTypes.func,
56+
disabled: PropTypes.bool
5557
};
5658

5759
CircleButton.defaultProps = {
5860
icon: undefined,
5961
className: undefined,
6062
showBorder: true,
6163
iconClassName: undefined,
64+
disabled: false,
6265
onClick: () => null,
6366
};
6467

src/components/WebphoneAlert/i18n/en-US.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ export default {
1010
[webphoneErrors.toVoiceMailError]: 'Cannot send call to voicemail due to internal error',
1111
[webphoneErrors.muteError]: 'Call cannot be muted at the moment.',
1212
[webphoneErrors.holdError]: 'Call cannot be hold at the moment.',
13-
[webphoneErrors.flipError]: 'Cannot flip the call. Please try again later.'
13+
[webphoneErrors.flipError]: 'Cannot flip the call. Please try again later.',
14+
[webphoneErrors.recordError]: 'You cannot record the call at the moment. Error code: {errorCode}',
15+
[webphoneErrors.recordDisabled]: 'Sorry, your account does not have the feature to record a call. Please contact your account administrator.'
1416
};

src/components/WebphoneAlert/index.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import webphoneErrors from 'ringcentral-integration/modules/Webphone/webphoneErrors';
4+
import FormattedMessage from '../FormattedMessage';
45
import i18n from './i18n';
56

67
export default function WebphoneAlert(props) {
78
const message = props.message.message;
8-
return (
9-
<span>{i18n.getString(message, props.currentLocale)}</span>
10-
);
9+
let view = (<span>{i18n.getString(message, props.currentLocale)}</span>);
10+
// Handle call record error
11+
if (message === webphoneErrors.recordError) {
12+
const errorCode = props.message.payload.errorCode;
13+
view = (
14+
<FormattedMessage
15+
message={i18n.getString(message, props.currentLocale)}
16+
values={{ errorCode }}
17+
/>
18+
);
19+
}
20+
return view;
1121
}
1222

1323
WebphoneAlert.propTypes = {
@@ -25,5 +35,7 @@ WebphoneAlert.handleMessage = ({ message }) => (
2535
(message === webphoneErrors.connected) ||
2636
(message === webphoneErrors.muteError) ||
2737
(message === webphoneErrors.holdError) ||
28-
(message === webphoneErrors.flipError)
38+
(message === webphoneErrors.flipError) ||
39+
(message === webphoneErrors.recordError) ||
40+
(message === webphoneErrors.recordDisabled)
2941
);

src/containers/CallCtrlPage/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ class CallCtrlPage extends Component {
118118
startTime={session.startTime}
119119
isOnMute={session.isOnMute}
120120
isOnHold={session.isOnHold}
121-
isOnRecord={session.isOnRecord}
122121
isOnFlip={session.isOnFlip}
122+
recordStatus={session.recordStatus}
123123
onBackButtonClick={this.props.onBackButtonClick}
124124
onMute={this.onMute}
125125
onUnmute={this.onUnmute}

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6314,9 +6314,9 @@ ringcentral-client@^1.0.0-rc1:
63146314
form-data "^2.1.2"
63156315
isomorphic-fetch "^2.2.1"
63166316

6317-
ringcentral-integration@^0.7.0:
6318-
version "0.7.0"
6319-
resolved "https://registry.yarnpkg.com/ringcentral-integration/-/ringcentral-integration-0.7.0.tgz#f65fe97b7dcafebffef6ddfe42da9fa65d365b6f"
6317+
ringcentral-integration@^0.7.1:
6318+
version "0.7.1"
6319+
resolved "https://registry.yarnpkg.com/ringcentral-integration/-/ringcentral-integration-0.7.1.tgz#eead2056a8ddc6ad23df6b18c117d16e163cb566"
63206320
dependencies:
63216321
file-loader "^0.10.1"
63226322
json-mask "^0.3.8"

0 commit comments

Comments
 (0)