diff --git a/src/components/ActiveCallButton/index.js b/src/components/ActiveCallButton/index.js index 848108d7c9..e47a0d4b58 100644 --- a/src/components/ActiveCallButton/index.js +++ b/src/components/ActiveCallButton/index.js @@ -16,16 +16,16 @@ export default function ActiveCallButton(props) { return ( {props.title} @@ -59,6 +63,10 @@ ActiveCallButton.propTypes = { height: PropTypes.string, x: PropTypes.number, y: PropTypes.number, + iconWidth: PropTypes.number, + iconHeight: PropTypes.number, + iconX: PropTypes.number, + iconY: PropTypes.number, }; ActiveCallButton.defaultProps = { @@ -72,4 +80,8 @@ ActiveCallButton.defaultProps = { height: '100%', x: 0, y: 0, + iconWidth: undefined, + iconHeight: undefined, + iconX: undefined, + iconY: undefined, }; diff --git a/src/components/ActiveCallButton/styles.scss b/src/components/ActiveCallButton/styles.scss index bdee89c2e6..734a9ef92c 100644 --- a/src/components/ActiveCallButton/styles.scss +++ b/src/components/ActiveCallButton/styles.scss @@ -22,7 +22,7 @@ $title-height: 24px; .buttonTitle { @include secondary-font; - font-size: 73px; + font-size: 80px; fill: $darkergray; } diff --git a/src/components/ActiveCallDialPad/styles.scss b/src/components/ActiveCallDialPad/styles.scss index 22d5cdc576..71d394a229 100644 --- a/src/components/ActiveCallDialPad/styles.scss +++ b/src/components/ActiveCallDialPad/styles.scss @@ -46,6 +46,10 @@ $input-height: 30px; width: 33.3%; text-align: center; padding: 2px; + + text { + font-size: 68px; + } } .stopButton { @@ -59,5 +63,5 @@ $input-height: 30px; .buttonRow { text-align: center; - height: 35%; + height: 22%; } diff --git a/src/components/ActiveCallPad/index.js b/src/components/ActiveCallPad/index.js index 17bb55dce3..3936b47710 100644 --- a/src/components/ActiveCallPad/index.js +++ b/src/components/ActiveCallPad/index.js @@ -116,6 +116,8 @@ export default function ActiveCallPad(props) { onClick={props.hangup} icon={EndIcon} showBorder={false} + iconWidth={250} + iconX={125} /> diff --git a/src/components/ActiveCallPad/styles.scss b/src/components/ActiveCallPad/styles.scss index f9d829e30e..30df0998cf 100644 --- a/src/components/ActiveCallPad/styles.scss +++ b/src/components/ActiveCallPad/styles.scss @@ -10,6 +10,8 @@ .callButton { width: 33.33%; + box-sizing: border-box; + padding: 0 7px; } .buttonRow { @@ -18,12 +20,16 @@ } .button { - width: 17%; + width: 17.2%; + height: 100%; border-radius: 63%; margin-left: auto; margin-right: auto; overflow: hidden; - margin-top: 10px; + + text { + font-size: 88px; + } } .stopButton { @@ -36,7 +42,7 @@ } .callCtrlButtonGroup { - height: 60%; + height: 70%; } .stopButtonGroup { diff --git a/src/components/ActiveCallPanel/styles.scss b/src/components/ActiveCallPanel/styles.scss index 688e4024ec..e0b189b126 100644 --- a/src/components/ActiveCallPanel/styles.scss +++ b/src/components/ActiveCallPanel/styles.scss @@ -42,6 +42,7 @@ $avatar-width: 60px; padding-top: 15px; margin-left: auto; margin-right: auto; + box-sizing: border-box; } .avatarContainer { @@ -103,5 +104,7 @@ $avatar-width: 60px; } .callPad { - height: calc(100% - 70px); + box-sizing: border-box; + height: calc(100% - 73px); + padding-bottom: 50px; } diff --git a/src/components/CircleButton/index.js b/src/components/CircleButton/index.js index 29df4438f2..2c68056feb 100644 --- a/src/components/CircleButton/index.js +++ b/src/components/CircleButton/index.js @@ -13,10 +13,10 @@ function CircleButton(props) { icon = ( ); } @@ -60,7 +60,11 @@ CircleButton.propTypes = { height: PropTypes.string, x: PropTypes.number, y: PropTypes.number, - disabled: PropTypes.bool + disabled: PropTypes.bool, + iconWidth: PropTypes.number, + iconHeight: PropTypes.number, + iconX: PropTypes.number, + iconY: PropTypes.number, }; CircleButton.defaultProps = { @@ -74,6 +78,10 @@ CircleButton.defaultProps = { height: '100%', x: 0, y: 0, + iconWidth: 200, + iconHeight: 200, + iconX: 150, + iconY: 150, }; export default CircleButton; diff --git a/src/components/IncomingCallPad/i18n/en-US.js b/src/components/IncomingCallPad/i18n/en-US.js index afc81f7b7d..268a131e21 100644 --- a/src/components/IncomingCallPad/i18n/en-US.js +++ b/src/components/IncomingCallPad/i18n/en-US.js @@ -4,4 +4,6 @@ export default { ignore: 'Ignore', toVoicemail: 'To Voicemail', answer: 'Answer', + answerAndEnd: 'Answer & End', + answerAndHold: 'Answer & Hold', }; diff --git a/src/components/IncomingCallPad/index.js b/src/components/IncomingCallPad/index.js index 6aba076567..ba225b60c1 100644 --- a/src/components/IncomingCallPad/index.js +++ b/src/components/IncomingCallPad/index.js @@ -7,6 +7,8 @@ import 'rc-tooltip/assets/bootstrap_white.css'; import ForwardForm from '../ForwardForm'; import ReplyWithMessage from '../ReplyWithMessage'; import ActiveCallButton from '../ActiveCallButton'; +import MultiCallAnswerButton from '../MultiCallAnswerButton'; + import MessageIcon from '../../assets/images/MessageFill.svg'; import ForwardIcon from '../../assets/images/Forward.svg'; import IgnoreIcon from '../../assets/images/Ignore.svg'; @@ -59,7 +61,59 @@ export default class IncomingCallPad extends Component { forwardingNumbers, formatPhone, className, + hasOtherActiveCall, + answerAndEnd, + answerAndHold, } = this.props; + // const isMultiCall = true; + const multiCallButtons = ( +
+ + + +
+ ); + const singleCallButtons = ( +
+ + +
+ ); return (
null} title={i18n.getString('forward', currentLocale)} className={styles.callButton} @@ -134,24 +190,7 @@ export default class IncomingCallPad extends Component { className={styles.callButton} />
-
- - -
+ {hasOtherActiveCall ? multiCallButtons : singleCallButtons}
); } @@ -166,10 +205,16 @@ IncomingCallPad.propTypes = { formatPhone: PropTypes.func, onForward: PropTypes.func.isRequired, replyWithMessage: PropTypes.func.isRequired, - className: PropTypes.string + className: PropTypes.string, + answerAndEnd: PropTypes.func, + answerAndHold: PropTypes.func, + hasOtherActiveCall: PropTypes.bool, }; IncomingCallPad.defaultProps = { formatPhone: phone => phone, className: null, + answerAndEnd: () => null, + answerAndHold: () => null, + hasOtherActiveCall: false, }; diff --git a/src/components/IncomingCallPad/styles.scss b/src/components/IncomingCallPad/styles.scss index 324a286668..7cd2cb3832 100644 --- a/src/components/IncomingCallPad/styles.scss +++ b/src/components/IncomingCallPad/styles.scss @@ -1,13 +1,13 @@ .root { position: relative; - margin-left: 5%; - margin-right: 5%; } .buttonRow { text-align: center; margin-bottom: 10px; - height: 24%; + height: 26.5%; + margin-left: 5%; + margin-right: 5%; } .callButton { @@ -15,7 +15,7 @@ padding: 0; text { - font-size: 73px; + font-size: 78px; } } @@ -23,7 +23,7 @@ composes: callButton; width: 50%; text { - font-size: 65px; + font-size: 70px; } } @@ -47,7 +47,20 @@ width: 76%; margin-left: auto; margin-right: auto; - height: 27%; + height: 29%; +} + +.multiCallsButtonGroup { + width: 100%; + margin-left: auto; + margin-right: auto; + height: 29.5%; + + .callButton { + text { + font-size: 70px; + } + } } .forwardContainner{ diff --git a/src/components/IncomingCallPanel/index.js b/src/components/IncomingCallPanel/index.js index 824ec60551..3c61672d7a 100644 --- a/src/components/IncomingCallPanel/index.js +++ b/src/components/IncomingCallPanel/index.js @@ -104,6 +104,9 @@ export default function IncomingCallPanel(props) { replyWithMessage={props.replyWithMessage} onForward={props.onForward} currentLocale={props.currentLocale} + hasOtherActiveCall={props.hasOtherActiveCall} + answerAndEnd={props.answerAndEnd} + answerAndHold={props.answerAndHold} /> {props.children} @@ -132,6 +135,9 @@ IncomingCallPanel.propTypes = { onForward: PropTypes.func.isRequired, brand: PropTypes.string, showContactDisplayPlaceholder: PropTypes.bool, + answerAndEnd: PropTypes.func, + answerAndHold: PropTypes.func, + hasOtherActiveCall: PropTypes.bool, }; IncomingCallPanel.defaultProps = { @@ -141,4 +147,7 @@ IncomingCallPanel.defaultProps = { avatarUrl: null, brand: 'RingCentral', showContactDisplayPlaceholder: true, + answerAndEnd: undefined, + answerAndHold: undefined, + hasOtherActiveCall: false, }; diff --git a/src/components/MultiCallAnswerButton/index.js b/src/components/MultiCallAnswerButton/index.js new file mode 100644 index 0000000000..07e8830cbc --- /dev/null +++ b/src/components/MultiCallAnswerButton/index.js @@ -0,0 +1,77 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +import AnswerIcon from '../../assets/images/Answer.svg'; +import HoldIcon from '../../assets/images/Hold.svg'; +import EndIcon from '../../assets/images/End.svg'; + +import CircleButton from '../CircleButton'; + +import styles from './styles.scss'; + +export default function MultiCallAnswerButton(props) { + const Icon = props.isEndOtherCall ? EndIcon : HoldIcon; + const iconClassName = classnames( + styles.button, + props.isEndOtherCall ? styles.endButton : '' + ); + return ( + + + + + {props.title} + + + ); +} + +MultiCallAnswerButton.propTypes = { + title: PropTypes.string.isRequired, + className: PropTypes.string, + onClick: PropTypes.func.isRequired, + isEndOtherCall: PropTypes.bool, + width: PropTypes.string, + height: PropTypes.string, + x: PropTypes.number, + y: PropTypes.number, +}; + +MultiCallAnswerButton.defaultProps = { + className: null, + isEndOtherCall: true, + width: '100%', + height: '100%', + x: 0, + y: 0, +}; diff --git a/src/components/MultiCallAnswerButton/styles.scss b/src/components/MultiCallAnswerButton/styles.scss new file mode 100644 index 0000000000..bd636545f4 --- /dev/null +++ b/src/components/MultiCallAnswerButton/styles.scss @@ -0,0 +1,35 @@ +@import '../../lib/commonStyles/colors.scss'; +@import '../../lib/commonStyles/fonts.scss'; + +.button { + width: 100%; + border-radius: 100%; + margin-left: auto; + margin-right: auto; + margin-bottom: 2px; +} + +.answer { + circle { + fill: #4cd964; + opacity: 1; + } + g, path { + fill: #ffffff; + } +} + +.endButton { + circle { + stroke: #ff4646; + } + g, path { + fill: #ff4646; + } +} + +.buttonTitle { + @include secondary-font; + font-size: 73px; + fill: $darkergray; +} \ No newline at end of file diff --git a/src/containers/IncomingCallPage/index.js b/src/containers/IncomingCallPage/index.js index 51ffdf5349..343778a70d 100644 --- a/src/containers/IncomingCallPage/index.js +++ b/src/containers/IncomingCallPage/index.js @@ -20,6 +20,7 @@ class IncomingCallPage extends Component { this.state = { selectedMatcherIndex: 0, avatarUrl: null, + hasOtherActiveCall: false, }; this.onSelectMatcherName = (option) => { @@ -55,6 +56,14 @@ class IncomingCallPage extends Component { this.props.onForward(this.props.session.id, forwardNumber); this.toggleMinimized = () => this.props.toggleMinimized(this.props.session.id); + this.answerAndEnd = async () => { + this.props.hangup(this.props.activeSessionId); + await this.props.answer(this.props.session.id); + }; + this.answerAndHold = async () => { + await this.props.onHold(this.props.activeSessionId); + await this.props.answer(this.props.session.id); + }; } componentDidMount() { @@ -64,6 +73,9 @@ class IncomingCallPage extends Component { componentWillReceiveProps(nextProps) { if (this.props.session.id !== nextProps.session.id) { this._updateAvatarAndMatchIndex(nextProps); + this.setState({ + hasOtherActiveCall: !!nextProps.activeSessionId, + }); } } @@ -127,6 +139,9 @@ class IncomingCallPage extends Component { onForward={this.onForward} brand={this.props.brand} showContactDisplayPlaceholder={this.props.showContactDisplayPlaceholder} + hasOtherActiveCall={this.state.hasOtherActiveCall} + answerAndEnd={this.answerAndEnd} + answerAndHold={this.answerAndHold} > {this.props.children} @@ -163,10 +178,12 @@ IncomingCallPage.propTypes = { updateSessionMatchedContact: PropTypes.func.isRequired, showContactDisplayPlaceholder: PropTypes.bool.isRequired, brand: PropTypes.string.isRequired, + activeSessionId: PropTypes.string, }; IncomingCallPage.defaultProps = { children: undefined, + activeSessionId: null, }; function mapToProps(_, { @@ -189,6 +206,7 @@ function mapToProps(_, { nameMatches, currentLocale: locale.currentLocale, session: currentSession, + activeSessionId: webphone.activeSessionId, areaCode: regionSettings.areaCode, countryCode: regionSettings.countryCode, forwardingNumbers: forwardingNumber.forwardingNumbers, @@ -216,6 +234,8 @@ function mapToFunctions(_, { updateSessionMatchedContact: (sessionId, contact) => webphone.updateSessionMatchedContact(sessionId, contact), getAvatarUrl, + hangup: sessionId => webphone.hangup(sessionId), + onHold: sessionId => webphone.hold(sessionId), }; }