diff --git a/docs/src/app/pages/Components/IncomingCallPad/Demo.js b/docs/src/app/pages/Components/IncomingCallPad/Demo.js
index 599fe9a4e3..4f6b63847e 100644
--- a/docs/src/app/pages/Components/IncomingCallPad/Demo.js
+++ b/docs/src/app/pages/Components/IncomingCallPad/Demo.js
@@ -5,6 +5,7 @@ import IncomingCallPad from 'ringcentral-widget/components/IncomingCallPad';
const props = {};
props.answer = () => null;
props.reject = () => null;
+props.replyWithMessage = () => null;
props.toVoiceMail = () => null;
props.currentLocale = 'en-US';
props.forwardingNumbers = [{
diff --git a/package.json b/package.json
index cc947c19c7..da6bde33d5 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,7 @@
"redux-thunk": "^2.1.0",
"ringcentral": "^3.1.1",
"ringcentral-client": "^1.0.0-rc1",
- "ringcentral-integration": "^0.7.0-rc5",
+ "ringcentral-integration": "^0.7.0-rc10",
"sass-loader": "^6.0.5",
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
diff --git a/src/components/IncomingCallPad/index.js b/src/components/IncomingCallPad/index.js
index 915aa003b3..56a16e5b4b 100644
--- a/src/components/IncomingCallPad/index.js
+++ b/src/components/IncomingCallPad/index.js
@@ -4,6 +4,7 @@ import Tooltip from 'rc-tooltip';
import 'rc-tooltip/assets/bootstrap_white.css';
import ForwardForm from '../ForwardForm';
+import ReplyWithMessage from '../ReplyWithMessage';
import ActiveCallButton from '../ActiveCallButton';
import MessageIcon from '../../assets/images/MessageFill.svg';
import ForwardIcon from '../../assets/images/Forward.svg';
@@ -19,6 +20,9 @@ export default class IncomingCallPad extends Component {
super(props);
this.state = {
showForward: false,
+ forwardNumber: '',
+ replyMessage: null,
+ showReplyWithMessage: false,
};
this.onShowForwardChange = (visible) => {
this.setState({
@@ -32,6 +36,17 @@ export default class IncomingCallPad extends Component {
this.closeForwardForm = () => {
this.onShowForwardChange(false);
};
+ this.onShowReplyWithMessageChange = (visible) => {
+ this.setState({
+ showReplyWithMessage: visible,
+ });
+ };
+ this.onReplyMessageChange = (message) => {
+ this.setState({ replyMessage: message });
+ };
+ this.closeReplyWithMessage = () => {
+ this.onShowReplyWithMessageChange(false);
+ };
}
render() {
@@ -51,6 +66,12 @@ export default class IncomingCallPad extends Component {
this.forwardContainner = containner;
}}
/>
+
{
+ this.replyWithMessageContainner = containner;
+ }}
+ />
+ );
+}
+
+TimeInput.propTypes = {
+ currentLocale: PropTypes.string.isRequired,
+ timeValue: PropTypes.string,
+ timeUnit: PropTypes.number,
+ inputRef: PropTypes.func.isRequired,
+ onTimeValueChange: PropTypes.func.isRequired,
+ onSelectTimeUnit: PropTypes.func.isRequired,
+};
+
+TimeInput.defaultProps = {
+ timeValue: '',
+ timeUnit: MINS,
+};
+
+export default class ReplyWithMessage extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ type: ON_MY_WAY,
+ customValue: '',
+ callYouTimeValue: '',
+ callYouTimeUnit: MINS,
+ callMeTimeValue: '',
+ callMeTimeUnit: MINS,
+ };
+
+ this.onSelectType = (index) => {
+ this.setState({
+ type: index,
+ });
+ this.props.onChange(this._getValue());
+ };
+
+ this.onCustomValueChange = (e) => {
+ const value = e.target.value;
+ this.setState({
+ customValue: value,
+ });
+ this.props.onChange(this._getValue());
+ };
+
+ this.onCallYouTimeValueChange = (e) => {
+ const value = e.target.value;
+ this.setState({
+ callYouTimeValue: value.replace(cleanRegex, ''),
+ });
+ };
+
+ this.onCallYouTimeUnitChange = (unit) => {
+ this.setState({
+ callYouTimeUnit: unit,
+ });
+ };
+
+ this.onCallMeTimeValueChange = (e) => {
+ const value = e.target.value;
+ this.setState({
+ callMeTimeValue: value.replace(cleanRegex, ''),
+ });
+ };
+
+ this.onCallMeTimeUnitChange = (unit) => {
+ this.setState({
+ callMeTimeUnit: unit,
+ });
+ };
+
+ this.onReply = () => {
+ this.props.onReply(this._getValue());
+ };
+ this.onCallYouInputRef = (input) => {
+ this.callYouInputRef = input;
+ };
+ this.onCallMeInputRef = (input) => {
+ this.callMeInputRef = input;
+ };
+ }
+
+ _getValue() {
+ const value = { replyType: 0 };
+ if (this.state.type === CUSTOM_MESSAGE) {
+ value.replyText = this.state.customValue;
+ }
+ if (this.state.type === ON_MY_WAY) {
+ value.replyText = 'On my way';
+ }
+ if (this.state.type < 2) {
+ value.replyType = 1;
+ value.callbackDirection = this.state.type;
+ if (this.state.type === 0) {
+ value.timeValue = this.state.callYouTimeValue;
+ value.timeUnits = this.state.callYouTimeUnit;
+ value.replyText = this.state.callYouTimeValue;
+ } else {
+ value.timeValue = this.state.callMeTimeValue;
+ value.timeUnits = this.state.callMeTimeUnit;
+ value.replyText = this.state.callMeTimeValue;
+ }
+ }
+ return value;
+ }
+
+ render() {
+ const {
+ className,
+ onCancel,
+ currentLocale,
+ } = this.props;
+ const disableButton = isBlank(this._getValue().replyText);
+ return (
+
+
+
{
+ this.onSelectType(CALL_YOU);
+ setTimeout(() => {
+ this.callYouInputRef.focus();
+ }, 100);
+ }}
+ className={classnames(
+ styles.messageItem, this.state.type === CALL_YOU ? styles.active : null
+ )}
+ >
+
{i18n.getString('willCallYouBackIn', currentLocale)}...
+
+
+
+
+
{
+ this.onSelectType(CALL_ME);
+ setTimeout(() => {
+ this.callMeInputRef.focus();
+ }, 100);
+ }}
+ className={classnames(
+ styles.messageItem, this.state.type === CALL_ME ? styles.active : null
+ )}
+ >
+
{i18n.getString('callMeBackIn', currentLocale)}...
+
+
+
+
+
this.onSelectType(ON_MY_WAY)}
+ className={classnames(
+ styles.messageItem, this.state.type === ON_MY_WAY ? styles.active : null
+ )}
+ >
+
{i18n.getString('onMyWay', currentLocale)}
+
+
{
+ this.onSelectType(CUSTOM_MESSAGE);
+ setTimeout(() => {
+ this.customValueInput.focus();
+ }, 100);
+ }}
+ className={classnames(
+ styles.messageItem, this.state.type === CUSTOM_MESSAGE ? styles.active : null
+ )}
+ >
+
{i18n.getString('customMessage', currentLocale)}
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+ReplyWithMessage.propTypes = {
+ className: PropTypes.string,
+ onCancel: PropTypes.func.isRequired,
+ onReply: PropTypes.func.isRequired,
+ currentLocale: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+};
+
+ReplyWithMessage.defaultProps = {
+ className: null,
+ onChange: undefined,
+};
diff --git a/src/components/ReplyWithMessage/styles.scss b/src/components/ReplyWithMessage/styles.scss
new file mode 100644
index 0000000000..0112b6ad0d
--- /dev/null
+++ b/src/components/ReplyWithMessage/styles.scss
@@ -0,0 +1,122 @@
+@import '../../lib/commonStyles/fonts.scss';
+@import '../../lib/commonStyles/colors.scss';
+
+.root {
+ display: block;
+ width: 100%;
+ padding: 0 0 16px 0;
+ background: #ffffff;
+
+ * {
+ box-sizing: border-box;
+ }
+}
+
+.buttonGroup {
+ @include primary-font;
+ display: block;
+ margin-top: 10px;
+ padding: 0 20px;
+}
+
+.cancelButton {
+ font-size: 12px;
+ color: $primary-color;
+ display: inline-block;
+ width: 65px;
+ height: 28px;
+ border-radius: 100px;
+ border: solid 1px $primary-color-highlight;
+ line-height: 28px;
+ text-align: center;
+ margin-right: 15px;
+ opacity: 0.9;
+ &:hover {
+ color: $primary-color;
+ }
+}
+
+.replyButton {
+ display: inline-block;
+ width: 65px;
+ height: 28px;
+ border-radius: 100px;
+ background: $primary-color;
+ font-size: 12px;
+ color: #ffffff;
+ line-height: 28px;
+ text-align: center;
+ &:hover {
+ color: #ffffff;
+ }
+ &.disabled {
+ background: #ffffff;
+ border: solid 1px #e3e3e3;
+ .buttonText {
+ color: $darkergray;
+ }
+ }
+}
+
+.messages {
+ display: block;
+ overflow-y: auto;
+ max-height: 160px;
+
+ .messageItem {
+ padding: 5px 20px;
+ @include secondary-font;
+ font-size: 14px;
+ line-height: 16px;
+ .label {
+ cursor: pointer;
+ }
+ .inputField {
+ display: none;
+ margin-top: 10px;
+ margin-bottom: 5px;
+ textarea {
+ @include secondary-font;
+ font-size: 12px;
+ padding: 7px 9px;
+ resize: none;
+ width: 150px;
+ height: 42px;
+ border: solid 1px #e3e3e3;
+ outline: none;
+ background: #ffffff;
+ }
+ }
+ &.active {
+ color: $primary-color;
+ background: #f5f5f5;
+ .inputField {
+ display: block;
+ }
+ }
+ }
+}
+
+.timeInput {
+ display: block;
+ @include secondary-font;
+ font-size: 12px;
+ span {
+ margin-right: 10px;
+ cursor: pointer;
+ }
+ .timeUnitSelected {
+ color: $primary-color;
+ }
+}
+
+.timeValue {
+ cursor: auto;
+ input {
+ outline: none;
+ line-height: 18px;
+ padding: 1px 0 1px 5px;
+ width: 40px;
+ height: 20px;
+ }
+}
diff --git a/src/containers/ActiveCallPage/index.js b/src/containers/ActiveCallPage/index.js
index 1371b41328..4db53775ac 100644
--- a/src/containers/ActiveCallPage/index.js
+++ b/src/containers/ActiveCallPage/index.js
@@ -158,6 +158,7 @@ class ActiveCallPage extends Component {
}
return (
=0.0.5:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
+
orchestrator@^0.3.0:
version "0.3.8"
resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e"
@@ -5045,6 +5071,10 @@ performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+phoneformat.js@^1.0.3:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/phoneformat.js/-/phoneformat.js-1.0.5.tgz#aeda52ea1a11358dd240f4896ee3446d6b9e0da0"
+
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -5393,6 +5423,16 @@ progress@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
+promiscuous@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/promiscuous/-/promiscuous-0.6.0.tgz#54014cd3d62cafe831e3354990c05ff5b78c8892"
+
+promise@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-5.0.0.tgz#ac40b7866bed7aaf796ab5b79b80325e047ec0ef"
+ dependencies:
+ asap "~1.0.0"
+
promise@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf"
@@ -5773,7 +5813,7 @@ redux-thunk@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"
-redux@^3.6.0:
+redux@^3.5.2, redux@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/redux/-/redux-3.6.0.tgz#887c2b3d0b9bd86eca2be70571c27654c19e188d"
dependencies:
@@ -5944,6 +5984,10 @@ requires-port@1.0.x, requires-port@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+reselect@2.5.4:
+ version "2.5.4"
+ resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047"
+
resolve-dir@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
@@ -6003,6 +6047,27 @@ ringcentral-client@^1.0.0-rc1:
form-data "^2.1.2"
isomorphic-fetch "^2.2.1"
+ringcentral-integration@^0.7.0-rc10:
+ version "0.7.0-rc10"
+ resolved "https://registry.yarnpkg.com/ringcentral-integration/-/ringcentral-integration-0.7.0-rc10.tgz#b3dc7fbbf5e0720a58fa3054002ca5e8b239e40a"
+ dependencies:
+ file-loader "^0.11.2"
+ json-mask "^0.3.8"
+ loganberry "^0.9.1"
+ phoneformat.js "^1.0.3"
+ redux "^3.5.2"
+ reselect "2.5.4"
+ ringcentral-web-phone "^0.4.1"
+ url-loader "^0.5.8"
+ uuid "^3.0.1"
+ yards "^0.1.4"
+
+ringcentral-web-phone@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/ringcentral-web-phone/-/ringcentral-web-phone-0.4.1.tgz#dfa9d7e67dc8ae02bea844718552cd5738138001"
+ dependencies:
+ sip.js "^0.7.7"
+
ringcentral@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/ringcentral/-/ringcentral-3.1.1.tgz#7f73f768f5ae8a62c1121b8356032cf4321ecc11"
@@ -6190,6 +6255,14 @@ signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+sip.js@^0.7.7:
+ version "0.7.8"
+ resolved "https://registry.yarnpkg.com/sip.js/-/sip.js-0.7.8.tgz#48709ba13485bcc050869b77a93c21658095b430"
+ dependencies:
+ ws "^1.0.1"
+ optionalDependencies:
+ promiscuous "^0.6.0"
+
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -6745,6 +6818,10 @@ uid-number@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
+ultron@1.0.x:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
+
unc-path-regex@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
@@ -7065,6 +7142,13 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"
+ws@^1.0.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.4.tgz#57f40d036832e5f5055662a397c4de76ed66bf61"
+ dependencies:
+ options ">=0.0.5"
+ ultron "1.0.x"
+
xml-js@^1.0.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.3.2.tgz#6157f1987f0f0ab994237bb827aa0c3401aea843"
@@ -7087,6 +7171,12 @@ yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+yards@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/yards/-/yards-0.1.4.tgz#f7da295448ab1740bf56b7512a841a0f969cb0d3"
+ dependencies:
+ promise "5.0.0"
+
yargs-parser@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"