Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 564 lines (463 sloc) 23.3 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
<title>Admin/Guest demo using RTCMultiConnection</title>
<meta name="description" content="Admin/Guest demo using RTCMultiConnection" />
<meta name="keywords" content="WebRTC,RTCMultiConnection,Demos,Experiments,Samples,Examples" />
<style>
video {
object-fit: fill;
width: 30%;
}
button,
input,
select {
font-weight: normal;
padding: 2px 4px;
text-decoration: none;
display: inline-block;
text-shadow: none;
font-size: 16px;
outline: none;
}
.make-center {
text-align: center;
padding: 5px 10px;
}
.prompt-bar {
background: rgb(255, 255, 255);
border: 9px solid rgb(216, 216, 216);
border-radius: 5px;
bottom: 0;
box-shadow: 0 0 5px, inset 0 0 2px;
display: none;
position: fixed;
right: 0;
width: 30%;
z-index: 100;
}
.prompt-bar #notification-header {
border-bottom: 1px solid rgb(213, 211, 211);
display: block;
padding: .1em .6em;
}
.prompt-bar #notification-text {
padding: .2em .6em;
}
.prompt-bar #controls {
background: rgb(175, 174, 174);
border: 1px solid gray;
text-align: center;
}
</style>
</head>
<body>
<article>
<header style="text-align: center;">
<h1>Admin/Guest demo using RTCMultiConnection</h1>
<p>
<a href="https://rtcmulticonnection.herokuapp.com/">HOME</a>
<span> &copy; </span>
<a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a> .
<a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a> .
<a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a> .
<a href="https://github.com/muaz-khan/RTCMultiConnection/issues?state=open" target="_blank">Latest issues</a> .
<a href="https://github.com/muaz-khan/RTCMultiConnection/commits/master" target="_blank">What's New?</a>
</p>
</header>
<div class="github-stargazers"></div>
<section class="experiment">
<div class="make-center">
<input type="text" id="admin-id" value="abcdef">
<button id="btn-become-admin">I'm Admin</button>
<button id="btn-become-guest">I'm Guest</button>
<div id="room-urls" style="text-align: center;display: none;background: #F1EDED;margin: 15px -10px;border: 1px solid rgb(189, 189, 189);border-left: 0;border-right: 0;"></div>
<br><br>
<input type="text" id="input-text-chat" placeholder="Enter Text Chat" disabled>
<button id="share-file" disabled>Share File</button>
</div>
<div id="chat-container">
<div id="file-container"></div>
<div class="chat-output"></div>
</div>
<div id="videos-container"></div>
</section>
<div id="notification-box" class="prompt-bar">
<h2 id="notification-header">Notification</h2>
<p id="notification-text">Notification</p>
<div id="controls">
<button id="btn-notification-accept" style="float:right;">Accept</button>
<button id="btn-notification-close" style="float:left;">Close</button>
<section style="color: transparent;">Control Panel</section>
</div>
</div>
<script src="/dist/RTCMultiConnection.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.webrtc-experiment.com:443/FileBufferReader.js"></script>
<script>
// ......................................................
// .......................UI Code........................
// ......................................................
document.getElementById('btn-become-admin').onclick = function() {
disableInputButtons();
connection.adminId = document.getElementById('admin-id').value;
connection.socketCustomEvent = connection.adminId;
connection.checkPresence(connection.adminId, function(isAdminOnline, adminId, adminInfo) {
if(isAdminOnline) {
rmcNotificationBox('Multiple admins are NOT allowed. An admin is using same "admin-id".', {
btnClose: false,
btnAccept: false,
btnAcceptText: '',
onBtnAcceptClicked: function() {},
autoClose: true,
autoCloseInterval: 5 * 1000
});
return;
}
connection.open(connection.adminId, function() {
showRoomURL(connection.sessionid);
});
handleSocketCustomMessages();
});
};
document.getElementById('btn-become-guest').onclick = function() {
disableInputButtons();
connection.adminId = document.getElementById('admin-id').value;
connection.socketCustomEvent = connection.adminId;
connection.checkPresence(connection.adminId, function(isAdminOnline, adminId, adminInfo) {
handleSocketCustomMessages();
if(!isAdminOnline) {
rmcNotificationBox('Admin seems offline.', {
btnClose: true,
btnAccept: false,
btnAcceptText: '',
onBtnAcceptClicked: function() {},
autoClose: true,
autoCloseInterval: 5 * 1000
});
return;
}
if(adminInfo.adminBusy) {
rmcNotificationBox('Admin seems online however his status is showing "busy".', {
btnClose: true,
btnAccept: false,
btnAcceptText: '',
onBtnAcceptClicked: function() {},
autoClose: true,
autoCloseInterval: 5 * 1000
});
return;
}
rmcNotificationBox('Admin is online. You can join him. He seems "available" as well.', {
btnClose: true,
btnAccept: true,
btnAcceptText: 'Join Admin',
onBtnAcceptClicked: function() {
connection.sendCustomMessage({
messageFor: adminId,
newGuest: true,
guestId: connection.userid,
guestInfo: connection.extra
});
},
autoClose: false,
autoCloseInterval: 2 * 1000
});
});
};
var notificationBox = document.getElementById('notification-box');
var notificationText = document.getElementById('notification-text');
var btnNotificationClose = document.getElementById('btn-notification-close');
var btnNotificationAccept = document.getElementById('btn-notification-accept');
function rmcNotificationBox(text, config) {
notificationText.innerHTML = text;
notificationBox.style.display = 'block';
if(config.btnClose && config.btnClose === true) {
btnNotificationClose.style.display = 'inline-block';
}
else {
btnNotificationClose.style.display = 'none';
}
if(config.btnAccept && config.btnAccept === true) {
btnNotificationAccept.style.display = 'inline-block';
}
else {
btnNotificationAccept.style.display = 'none';
}
if(config.btnAcceptText && config.btnAcceptText.length) {
btnNotificationAccept.innerHTML = config.btnAcceptText;
}
else {
btnNotificationAccept.innerHTML = 'Accept';
}
if(config.autoClose) {
setTimeout(function() {
notificationBox.style.display = 'none';
}, config.autoCloseInterval || 5 * 1000);
}
btnNotificationClose.onclick = function() {
notificationBox.style.display = 'none';
};
btnNotificationAccept.onclick = function() {
notificationBox.style.display = 'none';
if(config.onBtnAcceptClicked && typeof config.onBtnAcceptClicked === 'function') {
config.onBtnAcceptClicked();
}
};
}
// ......................................................
// ................FileSharing/TextChat Code.............
// ......................................................
document.getElementById('share-file').onclick = function() {
var fileSelector = new FileSelector();
fileSelector.selectSingleFile(function(file) {
connection.send(file);
});
};
document.getElementById('input-text-chat').onkeyup = function(e) {
if (e.keyCode != 13) return;
// removing trailing/leading whitespace
this.value = this.value.replace(/^\s+|\s+$/g, '');
if (!this.value.length) return;
connection.send(this.value);
appendDIV(this.value);
this.value = '';
};
var chatContainer = document.querySelector('.chat-output');
function appendDIV(event) {
var div = document.createElement('div');
div.innerHTML = event.data || event;
chatContainer.insertBefore(div, chatContainer.firstChild);
div.tabIndex = 0;
div.focus();
document.getElementById('input-text-chat').focus();
}
// ......................................................
// ..................RTCMultiConnection Code.............
// ......................................................
var connection = new RTCMultiConnection();
// by default, socket.io server is assumed to be deployed on your own URL
connection.socketURL = '/';
// comment-out below line if you do not have your own socket.io server
// connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
connection.socketMessageEvent = 'admin-guest-demo';
connection.enableFileSharing = true; // by default, it is "false".
connection.session = {
audio: true,
video: true,
data: true
};
connection.sdpConstraints.mandatory = {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
};
connection.videosContainer = document.getElementById('videos-container');
connection.onstream = function(event) {
connection.videosContainer.appendChild(event.mediaElement);
event.mediaElement.play();
setTimeout(function() {
event.mediaElement.play();
}, 5000);
};
connection.onmessage = appendDIV;
connection.filesContainer = document.getElementById('file-container');
connection.onopen = function() {
document.getElementById('share-file').disabled = false;
document.getElementById('input-text-chat').disabled = false;
document.querySelector('h1').innerHTML = 'You are connected with: ' + connection.getAllParticipants().join(', ');
};
connection.onclose = function() {
if(connection.getAllParticipants().length) {
document.querySelector('h1').innerHTML = 'You are still connected with: ' + connection.getAllParticipants().join(', ');
}
else {
document.querySelector('h1').innerHTML = 'Seems session has been closed or all participants left.';
}
};
connection.___updateExtraData = connection.updateExtraData;
connection.updateExtraData = function() {
connection.___updateExtraData();
connection.sendCustomMessage({
updatedExtraData: true,
adminId: connection.userid,
extra: connection.extra
});
};
connection.onNewParticipant = function(participantId, userPreferences) {
if(connection.userid === connection.adminId && !connection.extra.adminBusy) {
connection.connectedGuestId = participantId;
connection.extra.adminBusy = true;
connection.updateExtraData();
connection.acceptParticipationRequest(participantId, userPreferences);
}
};
connection.onleave = function(event) {
if(event.userid === connection.connectedGuestId) {
connection.connectedGuestId = null;
connection.extra.adminBusy = false;
connection.updateExtraData();
}
};
connection.sendCustomMessage = function(message) {
if(!connection.socket) connection.connectSocket();
connection.socket.emit(connection.socketCustomEvent, message);
};
connection.onExtraDataUpdated = function(event) {
if(connection.userid == connection.adminId) return;
if(event.userid === connection.adminId && event.extra.adminBusy === false) {
notificationBox.style.display = 'none';
}
if(connection.getAllParticipants().length) return;
if(event.userid === connection.adminId && event.extra.adminBusy === false) {
rmcNotificationBox('Admin is online. You can join him. He seems "available" as well.', {
btnClose: true,
btnAccept: true,
btnAcceptText: 'Join Admin',
onBtnAcceptClicked: function() {
connection.sendCustomMessage({
messageFor: event.userid,
newGuest: true,
guestId: connection.userid,
guestInfo: connection.extra
});
},
autoClose: false,
autoCloseInterval: 2 * 1000
});
}
};
function handleSocketCustomMessages() {
if(!connection.socket) connection.connectSocket();
connection.socket.on(connection.socketCustomEvent, function(message) {
if(message.updatedExtraData && message.adminId === connection.adminId) {
connection.onExtraDataUpdated({
userid: connection.adminId,
extra: message.extra
});
return;
}
if(message.messageFor !== connection.userid) return;
if(message.newGuest) {
var text = 'A new guest asked you to join him.';
text += '<br>Guest User-ID: ' + message.guestId;
text += '<br>Guest Info: ' + JSON.stringify(message.guestInfo);
rmcNotificationBox(text, {
btnClose: true,
btnAccept: true,
btnAcceptText: 'Allow Guest to Join You',
onBtnAcceptClicked: function() {
connection.sendCustomMessage({
messageFor: message.guestId,
youCanJoinAdmin: true,
adminId: connection.userid,
adminInfo: connection.extra
});
},
autoClose: false,
autoCloseInterval: 2 * 1000
});
return;
}
if(message.youCanJoinAdmin) {
connection.join(message.adminId);
var text = 'Admin accepted your request. Setting WebRTC connection...';
rmcNotificationBox(text, {
btnClose: false,
btnAccept: false,
btnAcceptText: '',
onBtnAcceptClicked: function() {},
autoClose: true,
autoCloseInterval: 2 * 1000
});
return;
}
});
}
function disableInputButtons() {
document.getElementById('btn-become-admin').disabled = true;
document.getElementById('btn-become-guest').disabled = true;
document.getElementById('admin-id').disabled = true;
}
// ......................................................
// ......................Handling admin-id................
// ......................................................
function showRoomURL(adminId) {
var roomHashURL = '#' + adminId;
var roomQueryStringURL = '?adminId=' + adminId;
var html = '<h2>Unique URL for your room:</h2><br>';
html += 'Hash URL: <a href="' + roomHashURL + '" target="_blank">' + roomHashURL + '</a>';
html += '<br>';
html += 'QueryString URL: <a href="' + roomQueryStringURL + '" target="_blank">' + roomQueryStringURL + '</a>';
var roomURLsDiv = document.getElementById('room-urls');
roomURLsDiv.innerHTML = html;
roomURLsDiv.style.display = 'block';
}
(function() {
var params = {},
r = /([^&=]+)=?([^&]*)/g;
function d(s) {
return decodeURIComponent(s.replace(/\+/g, ' '));
}
var match, search = window.location.search;
while (match = r.exec(search.substring(1)))
params[d(match[1])] = d(match[2]);
window.params = params;
})();
var adminId = '';
if (localStorage.getItem(connection.socketMessageEvent)) {
adminId = localStorage.getItem(connection.socketMessageEvent);
} else {
adminId = connection.token();
}
document.getElementById('admin-id').value = adminId;
document.getElementById('admin-id').onkeyup = function() {
localStorage.setItem(connection.socketMessageEvent, this.value);
};
var hashString = location.hash.replace('#', '');
if(hashString.length && hashString.indexOf('comment-') == 0) {
hashString = '';
}
var adminId = params.adminId;
if(!adminId && hashString.length) {
adminId = hashString;
}
if(adminId && adminId.length) {
document.getElementById('admin-id').value = adminId;
localStorage.setItem(connection.socketMessageEvent, adminId);
disableInputButtons();
document.getElementById('btn-become-guest').onclick();
}
</script>
<section class="experiment own-widgets latest-commits">
<h2 class="header" id="updates" style="color: red;padding-bottom: .1em;"><a href="https://github.com/muaz-khan/RTCMultiConnection/commits/master">Latest Updates</a></h2>
<div id="github-commits"></div>
</section>
<section class="experiment own-widgets">
<h2 class="header" id="updates" style="color: red;padding-bottom: .1em;"><a href="https://github.com/muaz-khan/RTCMultiConnection/issues">Latest Issues</a></h2>
<div id="github-issues"></div>
</section>
<section class="experiment">
<h2 class="header" id="feedback">Feedback</h2>
<div>
<textarea id="message" style="height: 8em; margin: .2em; width: 98%; border: 1px solid rgb(189, 189, 189); outline: none; resize: vertical;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
</div>
<button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left:1em;">Enter your email too; if you want "direct" reply!</small>
</section>
<a href="https://github.com/muaz-khan/RTCMultiConnection" class="fork-left"></a>
<script>
window.useThisGithubPath = 'muaz-khan/RTCMultiConnection';
</script>
<script src="https://cdn.webrtc-experiment.com/commits.js" async></script>
</article>
<footer>
<p>
<a href="https://www.webrtc-experiment.com">WebRTC Experiments</a> © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
<a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
<a href="https://github.com/muaz-khan" target="_blank">Github</a>
</p>
</footer>
</body>
</html>