diff --git a/skins/base/views/molecules/voip/CallHandler.js b/skins/base/views/molecules/voip/CallHandler.js
index 8fd8282f..41023dd6 100644
--- a/skins/base/views/molecules/voip/CallHandler.js
+++ b/skins/base/views/molecules/voip/CallHandler.js
@@ -28,7 +28,25 @@ var VideoView = ComponentBroker.get('molecules/voip/VideoView');
module.exports = React.createClass({
displayName: 'CallHandler',
mixins: [CallHandlerController],
+
+ getVideoView: function() {
+ return this.refs.video;
+ },
+
render: function(){
+ if (this.state && this.state.call) {
+ if (this.state.call.type === "video") {
+ return (
+
+ );
+ }
+ else if (this.state.call.type === "voice") {
+ // in the future.
+ return (
+
+ );
+ }
+ }
return (
);
diff --git a/src/controllers/molecules/voip/CallHandler.js b/src/controllers/molecules/voip/CallHandler.js
index f5e09338..0bb4685b 100644
--- a/src/controllers/molecules/voip/CallHandler.js
+++ b/src/controllers/molecules/voip/CallHandler.js
@@ -15,13 +15,25 @@ limitations under the License.
*/
'use strict';
-
+var MatrixClientPeg = require("../../../MatrixClientPeg");
+var Matrix = require("matrix-js-sdk");
var dis = require("../../../dispatcher");
+/*
+ * State vars:
+ * this.state.call = MatrixCall|null
+ *
+ * Props:
+ * this.props.room = Room (JS SDK) - can be null (for singleton views)
+ */
+
module.exports = {
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
+ this.setState({
+ call: null
+ });
},
componentWillUnmount: function() {
@@ -37,12 +49,75 @@ module.exports = {
switch (payload.action) {
case 'place_call':
+ if (this.state.call) {
+ return; // don't allow >1 call to be placed.
+ }
console.log("Place %s call in %s", payload.type, payload.room_id);
+ var call = Matrix.createNewMatrixCall(
+ MatrixClientPeg.get(), payload.room_id
+ );
+ this._setCallListeners(call);
+ this.setState({
+ call: call
+ });
+ if (payload.type === 'voice') {
+ call.placeVoiceCall();
+ }
+ else if (payload.type === 'video') {
+ var videoView = this.getVideoView();
+ call.placeVideoCall(
+ videoView.getRemoteVideoElement(),
+ videoView.getLocalVideoElement()
+ );
+ }
+ else {
+ console.error("Unknown call type: %s", payload.type);
+ }
break;
case 'incoming_call':
+ if (this.state.call) {
+ payload.call.hangup("busy");
+ return; // don't allow >1 call to be received.
+ }
+ this._setCallListeners(call);
+ this.setState({
+ call: call
+ });
console.log("Incoming call: %s", payload.call);
break;
+ case 'hangup':
+ if (!this.state.call) {
+ return; // no call to hangup
+ }
+ this.state.call.hangup();
+ this.setState({
+ call: null
+ });
+ break;
+ case 'answer':
+ if (!this.state.call) {
+ return; // no call to answer
+ }
+ this.state.call.answer();
+ break;
}
+ },
+
+ _setCallListeners: function(call) {
+ var self = this;
+ call.on("error", function(err) {
+ console.error("Call error: %s", err);
+ console.error(err.stack);
+ call.hangup();
+ self.setState({
+ call: null
+ });
+ });
+ call.on("hangup", function() {
+ self.setState({
+ call: null
+ });
+ })
}
};