crcastle/collaborative-code-conference

View on GitHub
src/client/webrtc.js

Summary

Maintainability
A
1 hr
Test Coverage
/* global Twilio:true */
 
require('es6-promise').polyfill();
require('isomorphic-fetch');
 
var bsn = require("bootstrap.native");
 
var conversationsClient;
var activeConversation;
var previewMedia;
var identity;
 
// Check for WebRTC
if (!navigator.webkitGetUserMedia && !navigator.mozGetUserMedia) {
Unexpected alert.
alert('Your browser does not support WebRTC, which is required for video and audio.\n\n'
+ 'You can still use the collaborative editor, though!\n\n'
+ 'Use Chrome or Firefox to experience video and audio.');
document.querySelector('#connect').setAttribute('disabled', 'disabled');
document.querySelector('#connect-dropdown').setAttribute('disabled', 'disabled');
}
 
var docName = window.location.pathname.slice(1);
 
function getConnectedConversationsClientFor(name) {
// If the conversationsClient is currently listening,
// stop before getting a new client and listening on that one
if (conversationsClient && conversationsClient.isListening) {
console.log('Stopping listening to', conversationsClient.identity);
conversationsClient.unlisten();
}
 
return fetch('/token?identity=' + name)
.then(function(response) {
if (response.status >= 400) {
throw new Error('Bad response from server');
}
return response.json();
})
.then(function(data) {
identity = data.identity;
var accessManager = new Twilio.AccessManager(data.token);
 
// Check the browser console to see your generated identity.
// Send an invite to yourself if you want!
console.log(identity);
 
// Create a Conversations Client and connect to Twilio
conversationsClient = new Twilio.Conversations.Client(accessManager);
return conversationsClient.listen();
});
}
 
getConnectedConversationsClientFor(docName)
.then(clientConnected, function(error) {
console.log('Could not connect to Twilio:', error.message);
});
 
// Successfully connected!
Function `clientConnected` has 42 lines of code (exceeds 25 allowed). Consider refactoring.
function clientConnected() {
// document.getElementById('invite-controls').style.display = 'block';
console.log("Connected to Twilio. Listening for incoming Invites as '", conversationsClient.identity, "'");
 
conversationsClient.on('invite', function (invite) {
console.log('Incoming invite from:', invite.from);
 
// Show dialog asking to accept or decline invitation
var accept = false;
if (invite.from === docName) {
accept = true;
} else {
Unexpected confirm.
accept = window.confirm('Accept video/audio connection from ' + invite.from + '?');
}
 
if (accept) {
invite.accept().then(conversationStarted);
} else {
invite.reject();
}
});
 
// Bind button to connect to audio/video conversation
document.getElementById('connect').onclick = function() {
Do not use 'new' for side effects.
new bsn.Button(document.querySelector('#connect'), 'loading');
Do not use 'new' for side effects.
new bsn.Button(document.querySelector('#connect-dropdown'), 'loading');
 
var docName = window.location.pathname.slice(1);
TODO found
var username = 'the-other-user'; //TODO: prompt user for their name
 
console.log('Getting new conversations client');
getConnectedConversationsClientFor(username)
.then(function() {
console.log('Got conversations client');
if (activeConversation) {
// Add a video/audio participant
// activeConversation.invite(docName);
Unexpected alert.
alert('Only two participants supported at this time.');
} else {
var options = {};
if (previewMedia) {
console.log('Preview media already displayed');
options.localMedia = previewMedia;
}
console.log('Sending invite to', docName);
conversationsClient.inviteToConversation(docName, options).then(conversationStarted, function(error) {
console.error('Unable to create conversation', error);
FIXME found
// FIXME: show error to user, un-disable button, and change identity back to docName
});
}
},
function(error) {
console.error('Could not connect to Twilio:', error.message);
});
};
}
 
// Conversation is live
function conversationStarted(conversation) {
console.log('In an active Conversation');
activeConversation = conversation;
// Draw local video, if not already previewing
if (!previewMedia) {
conversation.localMedia.attach('#local-media');
}
 
// When a participant joins, draw their video on screen
conversation.on('participantConnected', function (participant) {
console.log("Participant '" + participant.identity + "' connected");
participant.media.attach('#remote-media');
toggleConnectButton();
});
 
// When a participant disconnects, note in log
conversation.on('participantDisconnected', function (participant) {
console.log("Participant '" + participant.identity + "' disconnected");
toggleConnectButton();
});
 
// When the conversation ends, stop capturing local video
conversation.on('disconnected', function (conversation) {
console.log("Connected to Twilio. Listening for incoming Invites as '" + conversationsClient.identity + "'");
conversation.localMedia.stop();
conversation.disconnect();
activeConversation = null;
});
}
 
function toggleConnectButton() {
var connectButton = document.querySelector('#connect');
var connectDropdownButton = document.querySelector('#connect-dropdown');
 
if (connectButton.hasAttribute('disabled') && connectButton.hasAttribute('data-original-text')) {
Do not use 'new' for side effects.
new bsn.Button(connectButton, 'reset');
TODO found
connectButton.setAttribute('disabled', 'disabled'); //TODO: change this to 'Disconnect'
connectDropdownButton.setAttribute('disabled', 'disabled');
} else if (connectButton.hasAttribute('disabled')) {
connectButton.removeAttribute('disabled');
connectDropdownButton.removeAttribute('disabled');
} else {
TODO found
connectButton.setAttribute('disabled', 'disabled'); //TODO: change this to 'Disconnect'
connectDropdownButton.setAttribute('disabled', 'disabled');
}
}
 
// Local video preview
document.getElementById('button-preview').onclick = function () {
if (!previewMedia) {
previewMedia = new Twilio.Conversations.LocalMedia();
Twilio.Conversations.getUserMedia().then(
function (mediaStream) {
previewMedia.addStream(mediaStream);
previewMedia.attach('#local-media');
TODO found
// TODO: change button text to 'Stop My Camera'
},
function (error) {
console.error('Unable to access camera and microphone', error);
});
} else {
previewMedia.stop();
previewMedia = null;
}
};
 
module.exports = {
conversationsClient: conversationsClient,
activeConversation: activeConversation,
previewMedia: previewMedia,
identity: identity,
docName: docName
};