Adds support for etherpad in meet.jit.si. Issue #36.

This commit is contained in:
Yana Stamcheva 2014-02-12 23:28:56 +01:00
parent 4ef199304d
commit 4ff1f4a30e
5 changed files with 188 additions and 19 deletions

32
app.js
View File

@ -86,6 +86,7 @@ function doJoin() {
window.history.pushState('VideoChat', 'Room: ' + roomnode, window.location.pathname + roomnode); window.history.pushState('VideoChat', 'Room: ' + roomnode, window.location.pathname + roomnode);
} }
} }
roomjid = roomnode + '@' + config.hosts.muc; roomjid = roomnode + '@' + config.hosts.muc;
if (config.useNicks) { if (config.useNicks) {
@ -111,7 +112,9 @@ $(document).bind('mediaready.jingle', function (event, stream) {
updateLargeVideo(localVideoSrc, true, 0); updateLargeVideo(localVideoSrc, true, 0);
$('#localVideo').click(function () { $('#localVideo').click(function () {
$(document).trigger("video.selected", [false]);
updateLargeVideo($(this).attr('src'), true, 0); updateLargeVideo($(this).attr('src'), true, 0);
$('video').each(function (idx, el) { $('video').each(function (idx, el) {
if (el.id.indexOf('mixedmslabel') != -1) { if (el.id.indexOf('mixedmslabel') != -1) {
el.volume = 0; el.volume = 0;
@ -217,6 +220,7 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
}; };
sel.click( sel.click(
function () { function () {
$(document).trigger("video.selected", [false]);
updateLargeVideo($(this).attr('src'), false, 1); updateLargeVideo($(this).attr('src'), false, 1);
} }
); );
@ -282,6 +286,10 @@ $(document).bind('joined.muc', function (event, jid, info) {
focus = new ColibriFocus(connection, config.hosts.bridge); focus = new ColibriFocus(connection, config.hosts.bridge);
} }
if (focus && config.etherpad_base) {
Etherpad.init();
}
showFocusIndicator(); showFocusIndicator();
// Once we've joined the muc show the toolbar // Once we've joined the muc show the toolbar
@ -338,13 +346,13 @@ $(document).bind('left.muc', function (event, jid) {
$(container).hide(); $(container).hide();
resizeThumbnails(); resizeThumbnails();
} }
if (focus === null && connection.emuc.myroomjid == connection.emuc.list_members[0]) { if (focus === null && connection.emuc.myroomjid == connection.emuc.list_members[0]) {
console.log('welcome to our new focus... myself'); console.log('welcome to our new focus... myself');
focus = new ColibriFocus(connection, config.hosts.bridge); focus = new ColibriFocus(connection, config.hosts.bridge);
if (Object.keys(connection.emuc.members).length > 0) { if (Object.keys(connection.emuc.members).length > 0) {
focus.makeConference(Object.keys(connection.emuc.members)); focus.makeConference(Object.keys(connection.emuc.members));
} }
$(document).trigger('focusechanged.muc', [focus]);
} }
else if (focus && Object.keys(connection.emuc.members).length === 0) { else if (focus && Object.keys(connection.emuc.members).length === 0) {
console.log('everyone left'); console.log('everyone left');
@ -437,11 +445,11 @@ $(document).bind('presentationadded.muc', function (event, jid, presUrl, current
setPresentationVisible(true); setPresentationVisible(true);
$('#largeVideoContainer').hover( $('#largeVideoContainer').hover(
function (event) { function (event) {
if ($('#largeVideo').css('visibility') == 'hidden') if (isPresentationVisible())
$('#reloadPresentation').css({display:'inline-block'}); $('#reloadPresentation').css({display:'inline-block'});
}, },
function (event) { function (event) {
if ($('#largeVideo').css('visibility') == 'visible') if (!isPresentationVisible())
$('#reloadPresentation').css({display:'none'}); $('#reloadPresentation').css({display:'none'});
else { else {
var e = event.toElement || event.relatedTarget; var e = event.toElement || event.relatedTarget;
@ -519,6 +527,9 @@ function reloadPresentation() {
*/ */
function setPresentationVisible(visible) { function setPresentationVisible(visible) {
if (visible) { if (visible) {
// Trigger the video.selected event to indicate a change in the large video.
$(document).trigger("video.selected", [true]);
$('#largeVideo').fadeOut(300, function () { $('#largeVideo').fadeOut(300, function () {
$('#largeVideo').css({visibility:'hidden'}); $('#largeVideo').css({visibility:'hidden'});
$('#presentation>iframe').fadeIn(300, function() { $('#presentation>iframe').fadeIn(300, function() {
@ -538,6 +549,10 @@ function setPresentationVisible(visible) {
} }
} }
var isPresentationVisible = function () {
return ($('#presentation>iframe') != null && $('#presentation>iframe').css('opacity') == 1);
}
/** /**
* Updates the large video with the given new video source. * Updates the large video with the given new video source.
*/ */
@ -608,14 +623,19 @@ function resizeLarge() {
$('#presentation>iframe').height(availableWidth / aspectRatio); $('#presentation>iframe').height(availableWidth / aspectRatio);
} }
if ($('#etherpad>iframe')) {
$('#etherpad>iframe').width(availableWidth);
$('#etherpad>iframe').height(availableWidth / aspectRatio);
}
resizeThumbnails(); resizeThumbnails();
} }
function resizeThumbnails() { function resizeThumbnails() {
// Calculate the available height, which is the inner window height minus 39px for the header // Calculate the available height, which is the inner window height minus 39px for the header
// minus 4px for the delimiter lines on the top and bottom of the large video, // minus 2px for the delimiter lines on the top and bottom of the large video,
// minus the 36px space inside the remoteVideos container used for highlighting shadow. // minus the 36px space inside the remoteVideos container used for highlighting shadow.
var availableHeight = window.innerHeight - $('#largeVideo').height() - 79; var availableHeight = window.innerHeight - $('#largeVideo').height() - 59;
var numvids = $('#remoteVideos>span:visible').length; var numvids = $('#remoteVideos>span:visible').length;
// Remove the 1px borders arround videos and the chat width. // Remove the 1px borders arround videos and the chat width.
@ -629,7 +649,7 @@ function resizeThumbnails() {
} }
// size videos so that while keeping AR and max height, we have a nice fit // size videos so that while keeping AR and max height, we have a nice fit
$('#remoteVideos').height(availableHeight+26); // add the 2*18px-padding-top border used for highlighting shadow. $('#remoteVideos').height(availableHeight);
$('#remoteVideos>span').width(availableWidth); $('#remoteVideos>span').width(availableWidth);
$('#remoteVideos>span').height(availableHeight); $('#remoteVideos>span').height(availableHeight);
} }

View File

@ -22,7 +22,7 @@ html, body{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
#presentation, .videocontainer>video { #presentation, #etherpad, .videocontainer>video {
position: absolute; position: absolute;
left: 0px; left: 0px;
top: 0px; top: 0px;
@ -53,7 +53,7 @@ html, body{
position:relative; position:relative;
text-align:center; text-align:center;
height:196px; height:196px;
padding-top:10px; padding: 5px 0px;
width:auto; width:auto;
overflow: hidden; overflow: hidden;
border:1px solid transparent; border:1px solid transparent;
@ -415,5 +415,5 @@ form {
background-clip: padding-box; background-clip: padding-box;
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
z-index: 2; z-index: 3;
} }

136
etherpad.js Normal file
View File

@ -0,0 +1,136 @@
var Etherpad = (function (my) {
var etherpadName = null;
/**
* Initializes the etherpad.
*/
my.init = function (name) {
if (config.etherpad_base && !etherpadName) {
if (!name) {
// In case we're the focus we generate the name.
etherpadName = Math.random().toString(36).substring(7) + '_' + (new Date().getTime()).toString();
shareEtherpad();
}
else
etherpadName = name;
this.domain = config.etherpad_base;
this.options = "?showControls=true&showChat=false&showLineNumbers=true&useMonospaceFont=false";
createEtherpadButton();
this.iframe = document.createElement('iframe');
this.iframe.src = this.domain + etherpadName + this.options;
this.iframe.frameBorder = 0;
this.iframe.scrolling = "no";
this.iframe.width = $('#largeVideoContainer').width() || 640;
this.iframe.height = $('#largeVideoContainer').height() || 480;
this.iframe.setAttribute('style', 'visibility: hidden;');
document.getElementById('etherpad').appendChild(this.iframe);
}
}
/**
* Opens/hides the Etherpad.
*/
my.toggleEtherpad = function (isPresentation) {
var largeVideo = null;
if (isPresentationVisible())
largeVideo = $('#presentation>iframe');
else
largeVideo = $('#largeVideo');
if ($('#etherpad>iframe').css('visibility') == 'hidden') {
largeVideo.fadeOut(300, function () {
if (isPresentationVisible())
largeVideo.css({opacity:'0'});
else
largeVideo.css({visibility:'hidden'});
$('#etherpad>iframe').fadeIn(300, function() {
$('#etherpad>iframe').css({visibility:'visible'});
$('#etherpad').css({zIndex:2});
});
});
}
else if ($('#etherpad>iframe')) {
$('#etherpad>iframe').fadeOut(300, function () {
$('#etherpad>iframe').css({visibility:'hidden'});
$('#etherpad').css({zIndex:0});
if (!isPresentation) {
$('#largeVideo').fadeIn(300, function() {
$('#largeVideo').css({visibility:'visible'});
});
}
});
}
};
/**
* Shares the Etherpad name with other participants.
*/
function shareEtherpad() {
connection.emuc.addEtherpadToPresence(etherpadName);
connection.emuc.sendPresence();
}
/**
* Creates the Etherpad button and adds it to the toolbar.
*/
function createEtherpadButton() {
//<div class="header_button_separator"></div>
//<a class="button" onclick='Etherpad.openEtherpad("teeest");'>
//<i title="Open shared document" class="fa fa-file-text fa-lg"></i></a>
var separator = document.createElement('div');
separator.className = 'header_button_separator';
var button = document.createElement('a');
button.className = 'button';
button.setAttribute('onclick', 'Etherpad.toggleEtherpad(0);');
var buttonImage = document.createElement('i');
buttonImage.setAttribute('title', 'Open shared document');
buttonImage.className = 'fa fa-file-text fa-lg';
button.appendChild(buttonImage);
var toolbar = document.getElementById('toolbar');
toolbar.insertBefore(button, toolbar.childNodes[toolbar.childNodes.length - 4]);
toolbar.insertBefore(separator, button);
}
/**
* On Etherpad added to muc.
*/
$(document).bind('etherpadadded.muc', function (event, jid, etherpadName) {
console.log("Etherpad added", etherpadName);
if (config.etherpad_base && !focus) {
Etherpad.init(etherpadName);
}
});
/**
* On focus changed event.
*/
$(document).bind('focusechanged.muc', function (event, focus) {
console.log("Focus changed");
if (config.etherpad_base)
shareEtherpad();
});
/**
* On video selected event.
*/
$(document).bind('video.selected', function (event, isPresentation) {
if (!config.etherpad_base)
return;
if ($('#etherpad>iframe').css('visibility') != 'hidden')
Etherpad.toggleEtherpad(isPresentation);
});
return my;
}(Etherpad || {}));

View File

@ -5,13 +5,14 @@
<script src="libs/strophejingle.bundle.js?v=7"></script><!-- strophe.jingle bundle --> <script src="libs/strophejingle.bundle.js?v=7"></script><!-- strophe.jingle bundle -->
<script src="libs/colibri.js?v=7"></script><!-- colibri focus implementation --> <script src="libs/colibri.js?v=7"></script><!-- colibri focus implementation -->
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script src="muc.js?v=5"></script><!-- simple MUC library --> <script src="muc.js?v=6"></script><!-- simple MUC library -->
<script src="estos_log.js?v=2"></script><!-- simple stanza logger --> <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
<script src="app.js?v=19"></script><!-- application logic --> <script src="app.js?v=20"></script><!-- application logic -->
<script src="etherpad.js?v=1"></script><!-- etherpad plugin -->
<script src="smileys.js?v=1"></script><!-- smiley images --> <script src="smileys.js?v=1"></script><!-- smiley images -->
<script src="replacement.js?v=5"></script><!-- link and smiley replacement --> <script src="replacement.js?v=5"></script><!-- link and smiley replacement -->
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=15"/> <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=16"/>
<link rel="stylesheet" href="css/jquery-impromptu.css?v=4"> <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
<link rel="stylesheet" href="css/modaldialog.css?v=3"> <link rel="stylesheet" href="css/modaldialog.css?v=3">
<script src="libs/jquery-impromptu.js"></script> <script src="libs/jquery-impromptu.js"></script>
@ -36,11 +37,7 @@
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='openPreziDialog();'><i title="Share prezi" class="fa fa-desktop fa-lg"></i></a> <a class="button" onclick='openPreziDialog();'><i title="Share prezi" class="fa fa-desktop fa-lg"></i></a>
<div class="header_button_separator"></div> <div class="header_button_separator"></div>
<a class="button" onclick='toggleFullScreen();'><i title="Enter / Exit Full Screen" class="fa fa-arrows-alt"></i></a> <a class="button" onclick='toggleFullScreen();'><i title="Enter / Exit Full Screen" class="fa fa-arrows-alt fa-lg"></i></a>
<!--span id="settingsButton">
<div class="header_button_separator"></div>
<a class="button" onclick='openSettingsDialog();'><i title="Settings" class="fa fa-cog fa-lg"></i></a>
</span-->
</span> </span>
</div> </div>
<div id="settings"> <div id="settings">
@ -58,6 +55,7 @@
<div id="largeVideoContainer" class="videocontainer"> <div id="largeVideoContainer" class="videocontainer">
<div id="reloadPresentation"><a onclick='reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div> <div id="reloadPresentation"><a onclick='reloadPresentation();'><i title="Reload Prezi" class="fa fa-repeat fa-lg"></i></a></div>
<div id="presentation"></div> <div id="presentation"></div>
<div id="etherpad"></div>
<video id="largeVideo" autoplay oncontextmenu="return false;"></video> <video id="largeVideo" autoplay oncontextmenu="return false;"></video>
</div> </div>
<div class="fade_line"></div> <div class="fade_line"></div>

15
muc.js
View File

@ -43,6 +43,13 @@ Strophe.addConnectionPlugin('emuc', {
return true; return true;
} }
// Parse etherpad tag.
var etherpad = $(pres).find('>etherpad');
if (etherpad.length) {
$(document).trigger('etherpadadded.muc', [from, etherpad.text()]);
}
// Parse prezi tag.
var presentation = $(pres).find('>prezi'); var presentation = $(pres).find('>prezi');
if (presentation.length) if (presentation.length)
{ {
@ -188,6 +195,10 @@ Strophe.addConnectionPlugin('emuc', {
c('current').t(this.presMap['prezicurrent']).up().up(); c('current').t(this.presMap['prezicurrent']).up().up();
} }
if (this.presMap['etherpadns']) {
pres.c('etherpad', {xmlns: this.presMap['etherpadns']}).t(this.presMap['etherpadname']).up();
}
if (this.presMap['medians']) if (this.presMap['medians'])
{ {
pres.c('media', {xmlns: this.presMap['medians']}); pres.c('media', {xmlns: this.presMap['medians']});
@ -232,5 +243,9 @@ Strophe.addConnectionPlugin('emuc', {
}, },
getPrezi: function (roomjid) { getPrezi: function (roomjid) {
return this.preziMap[roomjid]; return this.preziMap[roomjid];
},
addEtherpadToPresence: function(etherpadName) {
this.presMap['etherpadns'] = 'http://jitsi.org/jitmeet/etherpad';
this.presMap['etherpadname'] = etherpadName;
} }
}); });