First working outbound conference calling
This has a number of failings currently: 1) It needs to hide the 1:1 conference room, 2) Swapping tabs on the outbound call mutes audio (this just seems to be a vector bug since I can repro this on a normal 1:1 voip call), 3) Needs a big plinth/etc to say the conf call is in progress.pull/160/head
parent
ee4da24b84
commit
77401e215e
|
@ -57,6 +57,7 @@ var MatrixClientPeg = require("./MatrixClientPeg");
|
|||
var Modal = require("./Modal");
|
||||
var ComponentBroker = require('./ComponentBroker');
|
||||
var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
|
||||
var ConferenceHandler = require("./ConferenceHandler");
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
var dis = require("./dispatcher");
|
||||
|
||||
|
@ -161,37 +162,49 @@ dis.register(function(payload) {
|
|||
console.error("Room %s does not exist.", payload.room_id);
|
||||
return;
|
||||
}
|
||||
|
||||
function placeCall(newCall) {
|
||||
_setCallListeners(newCall);
|
||||
_setCallState(newCall, newCall.roomId, "ringback");
|
||||
if (payload.type === 'voice') {
|
||||
newCall.placeVoiceCall();
|
||||
}
|
||||
else if (payload.type === 'video') {
|
||||
newCall.placeVideoCall(
|
||||
payload.remote_element,
|
||||
payload.local_element
|
||||
);
|
||||
}
|
||||
else {
|
||||
console.error("Unknown conf call type: %s", payload.type);
|
||||
}
|
||||
}
|
||||
|
||||
var members = room.getJoinedMembers();
|
||||
if (members.length !== 2) {
|
||||
var text = members.length === 1 ? "yourself." : "more than 2 people.";
|
||||
if (members.length <= 1) {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
description: "You cannot place a call with " + text
|
||||
description: "You cannot place a call with yourself."
|
||||
});
|
||||
console.error(
|
||||
"Fail: There are %s joined members in this room, not 2.",
|
||||
room.getJoinedMembers().length
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log("Place %s call in %s", payload.type, payload.room_id);
|
||||
var call = Matrix.createNewMatrixCall(
|
||||
MatrixClientPeg.get(), payload.room_id
|
||||
);
|
||||
_setCallListeners(call);
|
||||
_setCallState(call, call.roomId, "ringback");
|
||||
if (payload.type === 'voice') {
|
||||
call.placeVoiceCall();
|
||||
}
|
||||
else if (payload.type === 'video') {
|
||||
call.placeVideoCall(
|
||||
payload.remote_element,
|
||||
payload.local_element
|
||||
else if (members.length === 2) {
|
||||
console.log("Place %s call in %s", payload.type, payload.room_id);
|
||||
var call = Matrix.createNewMatrixCall(
|
||||
MatrixClientPeg.get(), payload.room_id
|
||||
);
|
||||
placeCall(call);
|
||||
}
|
||||
else {
|
||||
console.error("Unknown call type: %s", payload.type);
|
||||
else { // > 2
|
||||
console.log("Place conference call in %s", payload.room_id);
|
||||
var confHandler = new ConferenceHandler(
|
||||
MatrixClientPeg.get(), payload.room_id
|
||||
);
|
||||
confHandler.setup().done(function(call) {
|
||||
placeCall(call);
|
||||
}, function(err) {
|
||||
console.error("Failed to setup conference call: %s", err);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'incoming_call':
|
||||
if (calls[payload.call.roomId]) {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
"use strict";
|
||||
var q = require("q");
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
var Room = Matrix.Room;
|
||||
|
||||
var USER_PREFIX = "fs_";
|
||||
var DOMAIN = "matrix.org";
|
||||
|
||||
function ConferenceHandler(matrixClient, groupChatRoomId) {
|
||||
this.client = matrixClient;
|
||||
this.groupRoomId = groupChatRoomId;
|
||||
// abuse browserify's core node Buffer support (strip padding ='s)
|
||||
this.base64RoomId = new Buffer(this.groupRoomId).toString("base64").replace(/=/g, "");
|
||||
this.confUserId = "@" + USER_PREFIX + this.base64RoomId + ":" + DOMAIN;
|
||||
}
|
||||
|
||||
ConferenceHandler.prototype.setup = function() {
|
||||
var self = this;
|
||||
return this._joinConferenceUser().then(function() {
|
||||
return self._getConferenceUserRoom();
|
||||
}).then(function(room) {
|
||||
// return a call for *this* room to be placed.
|
||||
return Matrix.createNewMatrixCall(self.client, room.roomId);
|
||||
});
|
||||
};
|
||||
|
||||
ConferenceHandler.prototype._joinConferenceUser = function() {
|
||||
// Make sure the conference user is in the group chat room
|
||||
var groupRoom = this.client.getRoom(this.groupRoomId);
|
||||
if (!groupRoom) {
|
||||
return q.reject("Bad group room ID");
|
||||
}
|
||||
var members = groupRoom.getJoinedMembers();
|
||||
var confUserExists = false;
|
||||
for (var i = 0; i < members.length; i++) {
|
||||
if (members[i].userId === this.confUserId) {
|
||||
confUserExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (confUserExists) {
|
||||
return q();
|
||||
}
|
||||
return this.client.invite(this.groupRoomId, this.confUserId);
|
||||
};
|
||||
|
||||
ConferenceHandler.prototype._getConferenceUserRoom = function() {
|
||||
// Use an existing 1:1 with the conference user; else make one
|
||||
var rooms = this.client.getRooms();
|
||||
var confRoom = null;
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
if (rooms[i].hasMembershipState(this.confUserId, "join") &&
|
||||
rooms[i].getJoinedMembers().length === 2) {
|
||||
confRoom = rooms[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (confRoom) {
|
||||
return q(confRoom);
|
||||
}
|
||||
return this.client.createRoom({
|
||||
preset: "private_chat",
|
||||
invite: [this.confUserId]
|
||||
}).then(function(res) {
|
||||
return new Room(res.room_id);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = ConferenceHandler;
|
||||
|
Loading…
Reference in New Issue