diff --git a/app.js b/app.js
index b76bc450f..9ed8ff46c 100644
--- a/app.js
+++ b/app.js
@@ -10,7 +10,10 @@ var roomUrl = null;
var ssrc2jid = {};
var localVideoSrc = null;
var flipXLocalVideo = true;
-var preziPlayer = null;
+var isFullScreen = false;
+var toolbarTimeout = null;
+var currentVideoWidth = null;
+var currentVideoHeight = null;
/* window.onbeforeunload = closePageWarning; */
@@ -154,7 +157,6 @@ function doJoin() {
}
function change_local_audio(stream) {
-
connection.jingle.localAudio = stream;
RTC.attachMediaStream($('#localAudio'), stream);
document.getElementById('localAudio').autoplay = true;
@@ -171,7 +173,11 @@ function change_local_video(stream, flipX) {
localVideo.volume = 0; // is it required if audio is separated ?
localVideo.oncontextmenu = function () { return false; };
- var localVideoContainer = document.getElementById('localVideoContainer');
+ localVideo.addEventListener('loadedmetadata', function(e){
+ positionLarge(this.videoWidth, this.videoHeight);
+ });
+
+ var localVideoContainer = document.getElementById('localVideoWrapper');
localVideoContainer.appendChild(localVideo);
var localVideoSelector = $('#' + localVideo.id);
@@ -265,7 +271,17 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
vid.id = id;
vid.autoplay = true;
vid.oncontextmenu = function () { return false; };
+
+ vid.addEventListener('loadedmetadata', function(e){
+ positionLarge(this.videoWidth, this.videoHeight);
+ });
+
container.appendChild(vid);
+ var sel = $('#' + id);
+ sel.hide();
+ RTC.attachMediaStream(sel, data.stream);
+ waitForRemoteVideo(sel, sid);
+
// TODO: make mixedstream display:none via css?
if (id.indexOf('mixedmslabel') !== -1) {
container.id = 'mixedstream';
@@ -555,6 +571,7 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
showDisplayName(videoSpanId, info.displayName);
var nickfield = document.createElement('span');
+ nickfield.className = "nick";
nickfield.appendChild(document.createTextNode(Strophe.getResourceFromJid(jid)));
container.appendChild(nickfield);
resizeThumbnails();
@@ -681,160 +698,20 @@ $(document).bind('passwordrequired.muc', function (event, jid) {
});
});
-/*
- * Presentation has been removed.
- */
-$(document).bind('presentationremoved.muc', function(event, jid, presUrl) {
- console.log('presentation removed', presUrl);
- var presId = getPresentationId(presUrl);
- setPresentationVisible(false);
- $('#participant_' + Strophe.getResourceFromJid(jid) + '_' + presId).remove();
- $('#presentation>iframe').remove();
- if (preziPlayer !== null) {
- preziPlayer.destroy();
- preziPlayer = null;
- }
-});
-
-/*
- * Presentation has been added.
- */
-$(document).bind('presentationadded.muc', function (event, jid, presUrl, currentSlide) {
- console.log("presentation added", presUrl);
-
- var presId = getPresentationId(presUrl);
- var elementId = 'participant_' + Strophe.getResourceFromJid(jid) + '_' + presId;
-
- var container = addRemoteVideoContainer(elementId);
- resizeThumbnails();
-
- var controlsEnabled = false;
- if (jid === connection.emuc.myroomjid)
- controlsEnabled = true;
-
- setPresentationVisible(true);
- $('#largeVideoContainer').hover(
- function (event) {
- if (isPresentationVisible())
- $('#reloadPresentation').css({display:'inline-block'});
- },
- function (event) {
- if (!isPresentationVisible())
- $('#reloadPresentation').css({display:'none'});
- else {
- var e = event.toElement || event.relatedTarget;
-
- while(e && e.parentNode && e.parentNode !== window) {
- if (e.parentNode === this || e === this) {
- return false;
- }
- e = e.parentNode;
- }
- $('#reloadPresentation').css({display:'none'});
- }
- });
-
- preziPlayer = new PreziPlayer(
- 'presentation',
- {preziId: presId,
- width: $('#largeVideoContainer').width(),
- height: $('#largeVideoContainer').height(),
- controls: controlsEnabled,
- debug: true
- });
-
- $('#presentation>iframe').attr('id', preziPlayer.options.preziId);
-
- preziPlayer.on(PreziPlayer.EVENT_STATUS, function(event) {
- console.log("prezi status", event.value);
- if (event.value === PreziPlayer.STATUS_CONTENT_READY) {
- if (jid !== connection.emuc.myroomjid)
- preziPlayer.flyToStep(currentSlide);
- }
- });
-
- preziPlayer.on(PreziPlayer.EVENT_CURRENT_STEP, function(event) {
- console.log("event value", event.value);
- connection.emuc.addCurrentSlideToPresence(event.value);
- connection.emuc.sendPresence();
- });
-
- $("#" + elementId).css('background-image','url(../images/avatarprezi.png)');
- $("#" + elementId).click(
- function () {
- setPresentationVisible(true);
- }
- );
-});
-
-/*
- * Indicates presentation slide change.
- */
-$(document).bind('gotoslide.muc', function (event, jid, presUrl, current) {
- if (preziPlayer) {
- preziPlayer.flyToStep(current);
- }
-});
-
-/**
- * Returns the presentation id from the given url.
- */
-function getPresentationId (presUrl) {
- var presIdTmp = presUrl.substring(presUrl.indexOf("prezi.com/") + 10);
- return presIdTmp.substring(0, presIdTmp.indexOf('/'));
-}
-
-/*
- * Reloads the current presentation.
- */
-function reloadPresentation() {
- var iframe = document.getElementById(preziPlayer.options.preziId);
- iframe.src = iframe.src;
-}
-
-/*
- * Shows/hides a presentation.
- */
-function setPresentationVisible(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').css({visibility:'hidden'});
- $('#presentation>iframe').fadeIn(300, function() {
- $('#presentation>iframe').css({opacity:'1'});
- });
- });
- }
- else {
- if ($('#presentation>iframe')) {
- $('#presentation>iframe').fadeOut(300, function () {
- $('#presentation>iframe').css({opacity:'0'});
- $('#largeVideo').fadeIn(300, function() {
- $('#largeVideo').css({visibility:'visible'});
- });
- });
- }
- }
-}
-
-function isPresentationVisible() {
- return ($('#presentation>iframe') !== null && $('#presentation>iframe').css('opacity') == 1);
-}
-
/**
* Updates the large video with the given new video source.
*/
function updateLargeVideo(newSrc, vol) {
console.log('hover in', newSrc);
- setPresentationVisible(false);
+ if ($('#largeVideo').attr('src') != newSrc) {
+ document.getElementById('largeVideo')
+ .addEventListener('loadedmetadata', function(e){
+ currentVideoWidth = this.videoWidth;
+ currentVideoHeight = this.videoHeight;
+ });
- if ($('#largeVideo').attr('src') !== newSrc) {
-
- // FIXME: is it still required ? audio is separated
- //document.getElementById('largeVideo').volume = vol;
+ var isVisible = $('#largeVideo').is(':visible');
$('#largeVideo').fadeOut(300, function () {
$(this).attr('src', newSrc);
@@ -850,11 +727,26 @@ function updateLargeVideo(newSrc, vol) {
document.getElementById('largeVideo').style.webkitTransform = "none";
}
- $(this).fadeIn(300);
+ if (isVisible)
+ $(this).fadeIn(300);
});
}
}
+/**
+ * Shows/hides the large video.
+ */
+function setLargeVideoVisible(isVisible) {
+ if (isVisible) {
+ $('#largeVideo').css({visibility:'visible'});
+ $('#watermark').css({visibility:'visible'});
+ }
+ else {
+ $('#largeVideo').css({visibility:'hidden'});
+ $('#watermark').css({visibility:'hidden'});
+ }
+}
+
function getConferenceHandler() {
return focus ? focus : activecall;
}
@@ -876,6 +768,12 @@ function toggleVideo() {
}
);
}
+ var sess = focus || activecall;
+ if (!sess) {
+ return;
+ }
+ sess.pendingop = ismuted ? 'unmute' : 'mute';
+ sess.modifySources();
}
function toggleAudio() {
@@ -886,47 +784,140 @@ function toggleAudio() {
}
}
-var resizeLarge = function () {
+/**
+ * Positions the large video.
+ *
+ * @param videoWidth the stream video width
+ * @param videoHeight the stream video height
+ */
+var positionLarge = function(videoWidth, videoHeight) {
+ var videoSpaceWidth = $('#videospace').width();
+ var videoSpaceHeight = window.innerHeight;
+
+ var videoSize = getVideoSize( videoWidth,
+ videoHeight,
+ videoSpaceWidth,
+ videoSpaceHeight);
+
+ var availableWidth = videoSize[0];
+ var availableHeight = videoSize[1];
+
+ var videoPosition = getVideoPosition( availableWidth,
+ availableHeight,
+ videoSpaceWidth,
+ videoSpaceHeight);
+
+ var horizontalIndent = videoPosition[0];
+ var verticalIndent = videoPosition[1];
+
+ positionVideo( $('#largeVideo'),
+ availableWidth,
+ availableHeight,
+ horizontalIndent, verticalIndent);
+};
+
+/**
+ * Returns an array of the video horizontal and vertical indents,
+ * so that if fits its parent.
+ *
+ * @return an array with 2 elements, the horizontal indent and the vertical
+ * indent
+ */
+var getVideoPosition = function ( videoWidth,
+ videoHeight,
+ videoSpaceWidth,
+ videoSpaceHeight) {
+ // Parent height isn't completely calculated when we position the video in
+ // full screen mode and this is why we use the screen height in this case.
+ // Need to think it further at some point and implement it properly.
+ var isFullScreen = document.fullScreen
+ || document.mozFullScreen
+ || document.webkitIsFullScreen;
+ if (isFullScreen)
+ videoSpaceHeight = window.innerHeight;
+
+ var horizontalIndent = (videoSpaceWidth - videoWidth)/2;
+ var verticalIndent = (videoSpaceHeight - videoHeight)/2;
+
+ return [horizontalIndent, verticalIndent];
+};
+
+/**
+ * Returns an array of the video dimensions, so that if fits the screen.
+ *
+ * @return an array with 2 elements, the video width and the video height
+ */
+var getVideoSize = function(videoWidth,
+ videoHeight,
+ videoSpaceWidth,
+ videoSpaceHeight) {
+ if (!videoWidth)
+ videoWidth = currentVideoWidth;
+ if (!videoHeight)
+ videoHeight = currentVideoHeight;
+
+ var aspectRatio = videoWidth / videoHeight;
+
+ var availableWidth = Math.max(videoWidth, videoSpaceWidth);
+ var availableHeight = Math.max(videoHeight, videoSpaceHeight);
+
+ if (availableWidth / aspectRatio < videoSpaceHeight) {
+ availableHeight = videoSpaceHeight;
+ availableWidth = availableHeight*aspectRatio;
+ }
+
+ if (availableHeight*aspectRatio < videoSpaceWidth) {
+ availableWidth = videoSpaceWidth;
+ availableHeight = availableWidth / aspectRatio;
+ }
+
+ return [availableWidth, availableHeight];
+};
+
+/**
+ * Sets the size and position of the given video element.
+ *
+ * @param video the video element to position
+ * @param width the desired video width
+ * @param height the desired video height
+ * @param horizontalIndent the left and right indent
+ * @param verticalIndent the top and bottom indent
+ */
+function positionVideo( video,
+ width,
+ height,
+ horizontalIndent,
+ verticalIndent) {
+ video.width(width);
+ video.height(height);
+ video.css({ top: verticalIndent + 'px',
+ bottom: verticalIndent + 'px',
+ left: horizontalIndent + 'px',
+ right: horizontalIndent + 'px'});
+}
+
+var resizeLargeVideoContainer = function () {
Chat.resizeChat();
var availableHeight = window.innerHeight;
- var chatspaceWidth = $('#chatspace').is(":visible")
- ? $('#chatspace').width()
- : 0;
+ var availableWidth = Util.getAvailableVideoWidth();
- var numvids = $('#remoteVideos>video:visible').length;
- if (numvids < 5)
- availableHeight -= 100; // min thumbnail height for up to 4 videos
- else
- availableHeight -= 50; // min thumbnail height for more than 5 videos
-
- availableHeight -= 79; // padding + link ontop
- var availableWidth = window.innerWidth - chatspaceWidth;
- var aspectRatio = 16.0 / 9.0;
- if (availableHeight < availableWidth / aspectRatio) {
- availableWidth = Math.floor(availableHeight * aspectRatio);
- }
if (availableWidth < 0 || availableHeight < 0) return;
- $('#largeVideo').parent().width(availableWidth);
- $('#largeVideo').parent().height(availableWidth / aspectRatio);
- if ($('#presentation>iframe')) {
- $('#presentation>iframe').width(availableWidth);
- $('#presentation>iframe').height(availableWidth / aspectRatio);
- }
-
- if ($('#etherpad>iframe')) {
- $('#etherpad>iframe').width(availableWidth);
- $('#etherpad>iframe').height(availableWidth / aspectRatio);
- }
+ $('#videospace').width(availableWidth);
+ $('#videospace').height(availableHeight);
+ $('#largeVideoContainer').width(availableWidth);
+ $('#largeVideoContainer').height(availableHeight);
resizeThumbnails();
};
function resizeThumbnails() {
- // Calculate the available height, which is the inner window height minus 39px for the header
- // 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.
- var availableHeight = window.innerHeight - $('#largeVideo').height() - 59;
+ // Calculate the available height, which is the inner window height minus
+ // 39px for the header 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.
+ var availableHeight = 100;
+
var numvids = $('#remoteVideos>span:visible').length;
// Remove the 1px borders arround videos and the chat width.
@@ -951,9 +942,10 @@ $(document).ready(function () {
// Set the defaults for prompt dialogs.
jQuery.prompt.setDefaults({persistent: false});
- resizeLarge();
+ resizeLargeVideoContainer();
$(window).resize(function () {
- resizeLarge();
+ resizeLargeVideoContainer();
+ positionLarge();
});
if (!$('#settings').is(':visible')) {
console.log('init');
@@ -1035,14 +1027,14 @@ function dump(elem, filename){
return false;
}
-/*
+/**
* Changes the style class of the element given by id.
*/
function buttonClick(id, classname) {
$(id).toggleClass(classname); // add the class to the clicked element
}
-/*
+/**
* Opens the lock room dialog.
*/
function openLockDialog() {
@@ -1103,7 +1095,7 @@ function openLockDialog() {
}
}
-/*
+/**
* Opens the invite link dialog.
*/
function openLinkDialog() {
@@ -1119,7 +1111,7 @@ function openLinkDialog() {
});
}
-/*
+/**
* Opens the settings dialog.
*/
function openSettingsDialog() {
@@ -1160,110 +1152,7 @@ function openSettingsDialog() {
});
}
-/*
- * Opens the Prezi dialog, from which the user could choose a presentation to load.
- */
-function openPreziDialog() {
- var myprezi = connection.emuc.getPrezi(connection.emuc.myroomjid);
- if (myprezi) {
- $.prompt("Are you sure you would like to remove your Prezi?",
- {
- title: "Remove Prezi",
- buttons: { "Remove": true, "Cancel": false},
- defaultButton: 1,
- submit: function(e,v,m,f){
- if(v)
- {
- connection.emuc.removePreziFromPresence();
- connection.emuc.sendPresence();
- }
- }
- });
- }
- else if (preziPlayer !== null) {
- $.prompt("Another participant is already sharing a Prezi." +
- "This conference allows only one Prezi at a time.",
- {
- title: "Share a Prezi",
- buttons: { "Ok": true},
- defaultButton: 0,
- submit: function(e,v,m,f){
- $.prompt.close();
- }
- });
- }
- else {
- var openPreziState = {
- state0: {
- html: '
Share a Prezi
' +
- '',
- persistent: false,
- buttons: { "Share": true , "Cancel": false},
- defaultButton: 1,
- submit: function(e,v,m,f){
- e.preventDefault();
- if(v)
- {
- var preziUrl = document.getElementById('preziUrl');
-
- if (preziUrl.value)
- {
- var urlValue
- = encodeURI(Util.escapeHtml(preziUrl.value));
-
- if (urlValue.indexOf('http://prezi.com/') !== 0
- && urlValue.indexOf('https://prezi.com/') !== 0)
- {
- $.prompt.goToState('state1');
- return false;
- }
- else {
- var presIdTmp = urlValue.substring(urlValue.indexOf("prezi.com/") + 10);
- if (!Util.isAlphanumeric(presIdTmp)
- || presIdTmp.indexOf('/') < 2) {
- $.prompt.goToState('state1');
- return false;
- }
- else {
- connection.emuc.addPreziToPresence(urlValue, 0);
- connection.emuc.sendPresence();
- $.prompt.close();
- }
- }
- }
- }
- else
- $.prompt.close();
- }
- },
- state1: {
- html: 'Share a Prezi
' +
- 'Please provide a correct prezi link.',
- persistent: false,
- buttons: { "Back": true, "Cancel": false },
- defaultButton: 1,
- submit:function(e,v,m,f) {
- e.preventDefault();
- if (v === 0)
- $.prompt.close();
- else
- $.prompt.goToState('state0');
- }
- }
- };
-
- var myPrompt = jQuery.prompt(openPreziState);
-
- myPrompt.on('impromptu:loaded', function(e) {
- document.getElementById('preziUrl').focus();
- });
- myPrompt.on('impromptu:statechanged', function(e) {
- document.getElementById('preziUrl').focus();
- });
- }
-}
-
-/*
+/**
* Locks / unlocks the room.
*/
function lockRoom(lock) {
@@ -1275,26 +1164,59 @@ function lockRoom(lock) {
updateLockButton();
}
-/*
+/**
* Sets the shared key.
*/
function setSharedKey(sKey) {
sharedKey = sKey;
}
-/*
+/**
* Updates the lock button state.
*/
function updateLockButton() {
- buttonClick("#lockIcon", "fa fa-unlock fa-lg fa fa-lock fa-lg");
+ buttonClick("#lockIcon", "icon-security icon-security-locked");
}
-/*
+/**
+ * Hides the toolbar.
+ */
+var hideToolbar = function() {
+
+ var isToolbarHover = false;
+ $('#header').find('*').each(function(){
+ var id = $(this).attr('id');
+ if ($("#" + id + ":hover").length > 0) {
+ isToolbarHover = true;
+ }
+ });
+
+ clearTimeout(toolbarTimeout);
+ toolbarTimeout = null;
+
+ if (!isToolbarHover) {
+ $('#header').hide("slide", { direction: "up", duration: 300});
+ }
+ else {
+ toolbarTimeout = setTimeout(hideToolbar, 2000);
+ }
+};
+
+/**
* Shows the call main toolbar.
*/
function showToolbar() {
- $('#toolbar').css({visibility:"visible"});
- if (focus !== null)
+ if (!$('#header').is(':visible')) {
+ $('#header').show("slide", { direction: "up", duration: 300});
+
+ if (toolbarTimeout) {
+ clearTimeout(toolbarTimeout);
+ toolbarTimeout = null;
+ }
+ toolbarTimeout = setTimeout(hideToolbar, 2000);
+ }
+
+ if (focus != null)
{
// TODO: Enable settings functionality. Need to uncomment the settings button in index.html.
// $('#settingsButton').css({visibility:"visible"});
@@ -1303,14 +1225,39 @@ function showToolbar() {
setDesktopSharing(config.desktopSharing);
}
-/*
+/**
+ * Docks/undocks the toolbar.
+ *
+ * @param isDock indicates what operation to perform
+ */
+function dockToolbar(isDock) {
+ if (isDock) {
+ // First make sure the toolbar is shown.
+ if (!$('#header').is(':visible')) {
+ showToolbar();
+ }
+ // Then clear the time out, to dock the toolbar.
+ clearTimeout(toolbarTimeout);
+ toolbarTimeout = null;
+ }
+ else {
+ if (!$('#header').is(':visible')) {
+ showToolbar();
+ }
+ else {
+ toolbarTimeout = setTimeout(hideToolbar, 2000);
+ }
+ }
+}
+
+/**
* Updates the room invite url.
*/
function updateRoomUrl(newRoomUrl) {
roomUrl = newRoomUrl;
}
-/*
+/**
* Warning to the user that the conference window is about to be closed.
*/
function closePageWarning() {
@@ -1320,7 +1267,7 @@ function closePageWarning() {
return "You are about to leave this conversation.";
}
-/*
+/**
* Shows a visual indicator for the focus of the conference.
* Currently if we're not the owner of the conference we obtain the focus
* from the connection.jingle.sessions.
@@ -1385,21 +1332,17 @@ function toggleFullScreen() {
//Enter Full Screen
if (fsElement.mozRequestFullScreen) {
-
fsElement.mozRequestFullScreen();
}
else {
fsElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
-
} else {
-
//Exit Full Screen
if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else {
document.webkitCancelFullScreen();
- document.webkitCancelFullScreen();
}
}
}
@@ -1493,6 +1436,11 @@ function showDisplayName(videoSpanId, displayName) {
}
}
+/**
+ * Creates the edit display name button.
+ *
+ * @returns the edit button
+ */
function createEditDisplayNameButton() {
var editButton = document.createElement('a');
editButton.className = 'displayname';
@@ -1500,3 +1448,36 @@ function createEditDisplayNameButton() {
return editButton;
}
+
+/**
+ * Resizes and repositions videos in full screen mode.
+ */
+$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange',
+ function() {
+ resizeLargeVideoContainer();
+ positionLarge();
+ isFullScreen = document.fullScreen
+ || document.mozFullScreen
+ || document.webkitIsFullScreen;
+
+ if (isFullScreen) {
+ setView("fullscreen");
+ }
+ else {
+ setView("default");
+ }
+});
+
+/**
+ * Sets the current view.
+ */
+function setView(viewName) {
+// if (viewName == "fullscreen") {
+// document.getElementById('videolayout_fullscreen').disabled = false;
+// document.getElementById('videolayout_default').disabled = true;
+// }
+// else {
+// document.getElementById('videolayout_default').disabled = false;
+// document.getElementById('videolayout_fullscreen').disabled = true;
+// }
+}
\ No newline at end of file
diff --git a/chat.js b/chat.js
index fd48ee2d0..b9d8e9cfc 100644
--- a/chat.js
+++ b/chat.js
@@ -96,31 +96,78 @@ var Chat = (function (my) {
var chatspace = $('#chatspace');
var videospace = $('#videospace');
- var onShow = function () {
- resizeLarge();
- $('#chatspace').show("slide", { direction: "right", duration: 500});
- };
- var onHide = function () {
- $('#chatspace').hide("slide", { direction: "right", duration: 500});
- resizeLarge();
- };
+ var chatSize = (chatspace.is(":visible")) ? [0, 0] : Chat.getChatSize();
+ var videospaceWidth = window.innerWidth - chatSize[0];
+ var videospaceHeight = window.innerHeight;
+ var videoSize
+ = getVideoSize(null, null, videospaceWidth, videospaceHeight);
+ var videoWidth = videoSize[0];
+ var videoHeight = videoSize[1];
+ var videoPosition = getVideoPosition( videoWidth,
+ videoHeight,
+ videospaceWidth,
+ videospaceHeight);
+ var horizontalIndent = videoPosition[0];
+ var verticalIndent = videoPosition[1];
if (chatspace.is(":visible")) {
- videospace.animate( {right: 0},
+ videospace.animate( {right: chatSize[0],
+ width: videospaceWidth,
+ height: videospaceHeight},
{queue: false,
- duration: 500,
- progress: onHide});
+ duration: 500});
+
+ $('#largeVideoContainer').animate({ width: videospaceWidth,
+ height: videospaceHeight},
+ {queue: false,
+ duration: 500
+ });
+
+ $('#largeVideo').animate({ width: videoWidth,
+ height: videoHeight,
+ top: verticalIndent,
+ bottom: verticalIndent,
+ left: horizontalIndent,
+ right: horizontalIndent},
+ { queue: false,
+ duration: 500
+ });
+
+ $('#chatspace').hide("slide", { direction: "right",
+ queue: false,
+ duration: 500});
}
else {
- videospace.animate({right: chatspace.width()},
+ videospace.animate({right: chatSize[0],
+ width: videospaceWidth,
+ height: videospaceHeight},
{queue: false,
duration: 500,
- progress: onShow,
complete: function() {
scrollChatToBottom();
chatspace.trigger('shown');
}
});
+
+ $('#largeVideoContainer').animate({ width: videospaceWidth,
+ height: videospaceHeight},
+ {queue: false,
+ duration: 500
+ });
+
+ $('#largeVideo').animate({ width: videoWidth,
+ height: videoHeight,
+ top: verticalIndent,
+ bottom: verticalIndent,
+ left: horizontalIndent,
+ right: horizontalIndent},
+ {queue: false,
+ duration: 500
+ });
+
+ $('#chatspace').show("slide", { direction: "right",
+ queue: false,
+ duration: 500});
}
// Request the focus in the nickname field or the chat input field.
@@ -147,6 +194,18 @@ var Chat = (function (my) {
* Resizes the chat area.
*/
my.resizeChat = function () {
+ var chatSize = Chat.getChatSize();
+
+ $('#chatspace').width(chatSize[0]);
+ $('#chatspace').height(chatSize[1]);
+
+ resizeChatConversation();
+ };
+
+ /**
+ * Returns the size of the chat.
+ */
+ my.getChatSize = function() {
var availableHeight = window.innerHeight;
var availableWidth = window.innerWidth;
@@ -154,10 +213,7 @@ var Chat = (function (my) {
if (availableWidth*0.2 < 200)
chatWidth = availableWidth*0.2;
- $('#chatspace').width(chatWidth);
- $('#chatspace').height(availableHeight - 40);
-
- resizeChatConversation();
+ return [chatWidth, availableHeight];
};
/**
@@ -168,10 +224,11 @@ var Chat = (function (my) {
var usermsgHeight = usermsgStyleHeight
.substring(0, usermsgStyleHeight.indexOf('px'));
+ $('#usermsg').width($('#chatspace').width() - 10);
$('#chatconversation').width($('#chatspace').width() - 10);
$('#chatconversation')
- .height(window.innerHeight - 50 - parseInt(usermsgHeight));
- }
+ .height(window.innerHeight - 10 - parseInt(usermsgHeight));
+ };
/**
* Shows/hides a visual notification, indicating that a message has arrived.
@@ -179,25 +236,35 @@ var Chat = (function (my) {
function setVisualNotification(show) {
var unreadMsgElement = document.getElementById('unreadMessages');
+ var glower = $('#chatButton');
+
if (unreadMessages) {
unreadMsgElement.innerHTML = unreadMessages.toString();
+ showToolbar();
+
var chatButtonElement
- = document.getElementById('chat').parentNode;
+ = document.getElementById('chatButton').parentNode;
var leftIndent = (Util.getTextWidth(chatButtonElement)
- - Util.getTextWidth(unreadMsgElement) - 5)/2;
+ - Util.getTextWidth(unreadMsgElement))/2;
var topIndent = (Util.getTextHeight(chatButtonElement)
- - Util.getTextHeight(unreadMsgElement))/2 - 2;
+ - Util.getTextHeight(unreadMsgElement))/2 - 3;
unreadMsgElement.setAttribute(
'style',
'top:' + topIndent
+ '; left:' + leftIndent +';');
- }
- else
- unreadMsgElement.innerHTML = '';
- var glower = $('#chat');
+ if (!glower.hasClass('icon-chat-simple')) {
+ glower.removeClass('icon-chat');
+ glower.addClass('icon-chat-simple');
+ }
+ }
+ else {
+ unreadMsgElement.innerHTML = '';
+ glower.removeClass('icon-chat-simple');
+ glower.addClass('icon-chat');
+ }
if (show && !notificationInterval) {
notificationInterval = window.setInterval(function() {
diff --git a/css/font.css b/css/font.css
new file mode 100755
index 000000000..f62621791
--- /dev/null
+++ b/css/font.css
@@ -0,0 +1,71 @@
+@font-face {
+ font-family: 'jitsi';
+ src:url('../fonts/jitsi.eot?94d075');
+ src:url('../fonts/jitsi.eot?#iefix94d075') format('embedded-opentype'),
+ url('../fonts/jitsi.woff?94d075') format('woff'),
+ url('../fonts/jitsi.ttf?94d075') format('truetype'),
+ url('../fonts/jitsi.svg?94d075#jitsi') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+[class^="icon-"], [class*=" icon-"] {
+ font-family: 'jitsi';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 0.75em;
+ font-size: 1.22em;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-share-desktop:before {
+ content: "\e602";
+}
+.icon-chat-simple:before {
+ content: "\e606";
+}
+.icon-full-screen:before {
+ content: "\e60d";
+}
+.icon-exit-full-screen:before {
+ content: "\e60e";
+}
+.icon-prezi:before {
+ content: "\e60c";
+}
+.icon-link:before {
+ content: "\e600";
+}
+.icon-chat:before {
+ content: "\e601";
+}
+.icon-presentation:before {
+ content: "\e603";
+}
+.icon-security:before {
+ content: "\e604";
+}
+.icon-share-doc:before {
+ content: "\e605";
+}
+.icon-security-locked:before {
+ content: "\e607";
+}
+.icon-camera:before {
+ content: "\e608";
+}
+.icon-camera-disabled:before {
+ content: "\e609";
+}
+.icon-mic-disabled:before {
+ content: "\e60a";
+}
+.icon-microphone:before {
+ content: "\e60b";
+}
diff --git a/css/main.css b/css/main.css
index e702cc948..dc1b4729f 100644
--- a/css/main.css
+++ b/css/main.css
@@ -4,99 +4,15 @@ html, body{
color: #424242;
font-family:'Helvetica Neue', Helvetica, sans-serif;
font-weight: 400;
- background: #e9e9e9;
+ background: #000000;
overflow-x: hidden;
}
-#videospace {
- display: block;
- position: absolute;
- top: 39px;
- left: 0px;
- right: 0px;
- float: left;
-}
-
-.videocontainer {
- position: relative;
- margin-left: auto;
- margin-right: auto;
-}
-#presentation, #etherpad, .videocontainer>video {
- position: absolute;
- left: 0px;
- top: 0px;
- z-index: 1;
- width: 100%;
- height: 100%;
-}
-
-#etherpad {
- z-index: 0;
-}
-
-#etherpadButton {
- display: none;
-}
-
-.videocontainer>span {
- display: none; /* enable when you want nicks to be shown */
- position: absolute;
- left: 0px;
- bottom: -20px;
- z-index: 0;
- width: 100%;
- font-size: 10pt;
-}
-
-.flipVideoX {
- -moz-transform: scaleX(-1);
- -webkit-transform: scaleX(-1);
- -o-transform: scaleX(-1);
- transform: scaleX(-1);
-}
-
-#remoteVideos {
- display:block;
- position:relative;
- text-align:center;
- height:196px;
- padding: 5px 0px;
- width:auto;
- overflow: hidden;
- border:1px solid transparent;
- z-index: 2;
-}
-
-#remoteVideos>span {
- display: inline-block;
- z-index:0;
- border:1px solid #FFFFFF;
- background-image:url(../images/avatar1.png);
- background-size: contain;
-}
-
-#remoteVideos>span:hover {
- cursor: pointer;
- cursor: hand;
- transform:scale(1.08, 1.08);
- -webkit-transform:scale(1.08, 1.08);
- transition-duration: 0.5s;
- -webkit-transition-duration: 0.5s;
- background-color: #FFFFFF;
- -webkit-animation-name: greyPulse;
- -webkit-animation-duration: 2s;
- -webkit-animation-iteration-count: 1;
- -webkit-box-shadow: 0 0 18px #515151;
- border:1px solid #FFFFFF;
- z-index: 10;
-}
-
#chatspace {
display:none;
position:absolute;
float: right;
- top: 40px;
+ top: 0px;
bottom: 0px;
right: 0px;
width: 20%;
@@ -105,9 +21,11 @@ html, body{
/* background-color:#dfebf1;*/
background-color:#FFFFFF;
border-left:1px solid #424242;
+ z-index: 5;
}
#chatconversation {
+ visibility: hidden;
position: relative;
top: 5px;
padding: 5px;
@@ -119,7 +37,6 @@ html, body{
overflow-y: scroll;
overflow-x: hidden;
word-wrap: break-word;
- visibility: hidden;
}
.localuser {
@@ -131,20 +48,20 @@ html, body{
}
#usermsg {
+ visibility:hidden;
position: relative;
width: 100%;
height: 5%;
padding: 5px;
- z-index: 5;
max-height:150px;
min-height:50px;
- visibility:hidden;
border: 0px none;
border-top: 1px solid #cccccc;
background: #FFFFFF;
box-shadow: none;
border-radius:0;
font-size: 10pt;
+ overflow: hidden;
}
#usermsg: hover {
@@ -169,10 +86,6 @@ html, body{
font-size: 14;
}
-#spacer {
- height:5px;
-}
-
#settings {
display:none;
}
@@ -181,47 +94,6 @@ html, body{
display:none;
}
-#header{
- display:block;
- height:39px;
- text-align:center;
- background-color: #2591e5;
-}
-
-#left {
- display:block;
- position: absolute;
- left: 0px;
- top: 0px;
- width: 100px;
- height: 39px;
- background-image:url(../images/left1.png);
- background-repeat:no-repeat;
- margin: 0;
- padding: 0;
-}
-
-#leftlogo {
- position:absolute;
- top: 5px;
- left: 15px;
- background-image:url(../images/jitsilogo.png);
- background-repeat:no-repeat;
- height: 31px;
- width: 68px;
- z-index:1;
-}
-
-#toolbar {
- display:block;
- position:relative;
- height:39px;
- width:auto;
- overflow: hidden;
- z-index:0;
- visibility: hidden;
-}
-
#settingsButton {
visibility: hidden;
}
@@ -254,18 +126,16 @@ html, body{
cursor: pointer;
}
-#chat {
- font-size:1.65em;
+#chatButton {
-webkit-transition: all .5s ease-in-out;;
-moz-transition: all .5s ease-in-out;;
transition: all .5s ease-in-out;;
}
-#chat.active {
+#chatButton.active {
-webkit-text-shadow: 0 0 10px #ffffff;
-moz-text-shadow: 0 0 10px #ffffff;
text-shadow: 0 0 10px #ffffff;
- /* -webkit-transform: scale(1.1); */
}
a.button:hover {
@@ -282,44 +152,13 @@ a.button:hover {
color: #636363;
}
-.fade_line {
- height: 1px;
- background: black;
- background: -webkit-gradient(linear, 0 0, 100% 0, from(#e9e9e9), to(#e9e9e9), color-stop(50%, black));
-}
-
.header_button_separator {
display: inline-block;
position:relative;
- top: 7;
+ top: 5;
width: 1px;
- height: 25px;
- background: white;
- background: -webkit-gradient(linear, 0 0, 0 100%, from(#087dba), to(#087dba), color-stop(50%, white));
-}
-
-#right {
- display:block;
- position:absolute;
- right: 0px;
- top: 0px;
- background-image:url(../images/right1.png);
- background-repeat:no-repeat;
- margin:0;
- padding:0;
- width:100px;
- height:39px;
-}
-
-#rightlogo {
- position:absolute;
- top: 6px;
- right: 15px;
- background-image:url(../images/estoslogo.png);
- background-repeat:no-repeat;
- height: 25px;
- width: 62px;
- z-index:1;
+ height: 20px;
+ background: #676767;
}
input[type='text'], textarea {
@@ -387,70 +226,3 @@ form {
overflow: visible;
z-index: 100;
}
-
-.videocontainer>span.focusindicator {
- display: inline-block;
- position: absolute;
- color: #FFFFFF;
- top: 0;
- padding: 5px 0px;
- width: 25px;
- font-size: 11pt;
- text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
- border: 0px;
- z-index: 2;
-}
-
-.videocontainer>span.displayname,
-.videocontainer>input.displayname {
- display: inline-block;
- position: absolute;
- background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
- color: #b7b7b7;
- bottom: 0;
- left: 0;
- padding: 3px 5px;
- width: 100%;
- height: auto;
- max-height: 18px;
- font-size: 9pt;
- text-align: left;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- z-index: 2;
- box-sizing: border-box;
-}
-
-#localVideoContainer>span.displayname:hover {
- cursor: text;
-}
-
-.videocontainer>a.displayname {
- display: inline-block;
- position: absolute;
- color: #b7b7b7;
- bottom: 0;
- right: 0;
- padding: 3px 5px;
- font-size: 9pt;
- cursor: pointer;
- z-index: 2;
-}
-
-#reloadPresentation {
- display: none;
- position: absolute;
- color: #FFFFFF;
- top: 0;
- right: 0;
- padding: 10px 10px;
- font-size: 11pt;
- cursor: pointer;
- background: rgba(0, 0, 0, 0.3);
- border-radius: 5px;
- background-clip: padding-box;
- -webkit-border-radius: 5px;
- -webkit-background-clip: padding-box;
- z-index: 3;
-}
diff --git a/css/videolayout_default.css b/css/videolayout_default.css
new file mode 100644
index 000000000..366d44f87
--- /dev/null
+++ b/css/videolayout_default.css
@@ -0,0 +1,226 @@
+#videospace {
+ display: block;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+}
+
+#remoteVideos {
+ display:block;
+ position:absolute;
+ text-align:right;
+ height:196px;
+ padding: 18px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width:auto;
+ overflow: hidden;
+ border:1px solid transparent;
+ z-index: 2;
+}
+
+.videocontainer {
+ position: relative;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#remoteVideos .videocontainer {
+ display: inline-block;
+ background-image:url(../images/avatar1.png);
+ background-size: contain;
+ border-radius:8px;
+ border: 2px solid #212425;
+}
+
+#remoteVideos .videocontainer:hover {
+ width: 100%;
+ height: 100%;
+ content:"";
+ cursor: pointer;
+ cursor: hand;
+ transform:scale(1.08, 1.08);
+ -webkit-transform:scale(1.08, 1.08);
+ transition-duration: 0.5s;
+ -webkit-transition-duration: 0.5s;
+ -webkit-animation-name: greyPulse;
+ -webkit-animation-duration: 2s;
+ -webkit-animation-iteration-count: 1;
+ -webkit-box-shadow: 0 0 18px #388396;
+ border: 2px solid #388396;
+ z-index: 3;
+}
+
+#localVideoWrapper {
+ display:inline-block;
+ -webkit-mask-box-image: url(http://emcho.com/db/videomask.svg);
+ border-radius:0px !important;
+ border: 0px !important;
+}
+
+#remoteVideos .videocontainer>video {
+ border-radius:6px;
+}
+
+.flipVideoX {
+ transform: scale(-1, 1);
+ -moz-transform: scale(-1, 1);
+ -webkit-transform: scale(-1, 1);
+ -o-transform: scale(-1, 1);
+}
+
+#localVideoWrapper>video {
+ border-radius:0px !important;
+}
+
+#largeVideo,
+#largeVideoContainer {
+ overflow: hidden;
+ text-align: center;
+}
+
+#presentation,
+#etherpad,
+#localVideoWrapper>video,
+#localVideoWrapper,
+.videocontainer>video {
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 1;
+ width: 100%;
+ height: 100%;
+}
+
+#etherpad,
+#presentation {
+ text-align: center;
+}
+
+#etherpad {
+ z-index: 0;
+}
+
+#etherpadButton {
+ display: none;
+}
+
+#remoteVideos .videocontainer>span.focusindicator {
+ display: inline-block;
+ position: absolute;
+ color: #FFFFFF;
+ top: 0;
+ left: 0;
+ padding: 5px 0px;
+ width: 25px;
+ font-size: 11pt;
+ text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
+ border: 0px;
+ z-index: 2;
+}
+
+#remoteVideos .nick {
+ display: none; /* enable when you want nicks to be shown */
+ position: absolute;
+ left: 0px;
+ bottom: -20px;
+ z-index: 0;
+ width: 100%;
+ font-size: 10pt;
+}
+
+.videocontainer>span.displayname,
+.videocontainer>input.displayname {
+ display: inline-block;
+ position: absolute;
+ background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
+ color: #FFFFFF;
+ bottom: 0;
+ left: 0;
+ padding: 3px 5px;
+ width: 100%;
+ height: auto;
+ max-height: 18px;
+ font-size: 9pt;
+ text-align: left;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ z-index: 2;
+ box-sizing: border-box;
+ border-bottom-left-radius:6px;
+ border-bottom-right-radius:6px;
+}
+
+#localVideoContainer>span.displayname:hover {
+ cursor: text;
+}
+
+.videocontainer>a.displayname {
+ display: inline-block;
+ position: absolute;
+ color: #FFFFFF;
+ bottom: 0;
+ right: 0;
+ padding: 3px 5px;
+ font-size: 9pt;
+ cursor: pointer;
+ z-index: 2;
+}
+
+#reloadPresentation {
+ display: none;
+ position: absolute;
+ color: #FFFFFF;
+ top: 0;
+ right:0;
+ padding: 10px 10px;
+ font-size: 11pt;
+ cursor: pointer;
+ background: rgba(0, 0, 0, 0.3);
+ border-radius: 5px;
+ background-clip: padding-box;
+ -webkit-border-radius: 5px;
+ -webkit-background-clip: padding-box;
+ z-index: 20; /*The reload button should appear on top of the header!*/
+}
+
+#header{
+ display:none;
+ position:absolute;
+ height:39px;
+ text-align:center;
+ top:0;
+ left:0;
+ right:0;
+ z-index:10;
+}
+
+#toolbar {
+ display:inline-block;
+ position:relative;
+ margin-left:auto;
+ margin-right:auto;
+ height:39px;
+ width:auto;
+ overflow: hidden;
+ background: linear-gradient(to bottom, rgba(103,103,103,.65) , rgba(0,0,0,.65));
+ -webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
+ border-bottom-left-radius: 12px;
+ border-bottom-right-radius: 12px;
+}
+
+#watermark {
+ display: block;
+ position: absolute;
+ left: 15;
+ top: 15;
+ width: 20%;
+ height: 10%;
+ background-image:url(../images/watermark.png);
+ background-size: contain;
+ background-repeat: no-repeat;
+ z-index: 2;
+}
\ No newline at end of file
diff --git a/etherpad.js b/etherpad.js
index 9336d6e00..4b9d0acbd 100644
--- a/etherpad.js
+++ b/etherpad.js
@@ -33,21 +33,23 @@ var Etherpad = (function (my) {
if (!etherpadIFrame)
createIFrame();
- // TODO FIX large video and prezi toggling. Too many calls from different places.
var largeVideo = null;
- if (isPresentationVisible())
+ if (Prezi.isPresentationVisible())
largeVideo = $('#presentation>iframe');
else
largeVideo = $('#largeVideo');
if ($('#etherpad>iframe').css('visibility') === 'hidden') {
largeVideo.fadeOut(300, function () {
- if (isPresentationVisible())
+ if (Prezi.isPresentationVisible())
largeVideo.css({opacity:'0'});
- else
- largeVideo.css({visibility:'hidden'});
+ else {
+ setLargeVideoVisible(false);
+ dockToolbar(true);
+ }
$('#etherpad>iframe').fadeIn(300, function() {
+ document.body.style.background = '#eeeeee';
$('#etherpad>iframe').css({visibility:'visible'});
$('#etherpad').css({zIndex:2});
});
@@ -57,15 +59,38 @@ var Etherpad = (function (my) {
$('#etherpad>iframe').fadeOut(300, function () {
$('#etherpad>iframe').css({visibility:'hidden'});
$('#etherpad').css({zIndex:0});
+ document.body.style.background = 'black';
if (!isPresentation) {
$('#largeVideo').fadeIn(300, function() {
- $('#largeVideo').css({visibility:'visible'});
+ setLargeVideoVisible(true);
+ dockToolbar(false);
});
}
});
}
+ resize();
};
+ /**
+ * Resizes the etherpad.
+ */
+ function resize() {
+ if ($('#etherpad>iframe').length) {
+ var remoteVideos = $('#remoteVideos');
+ var availableHeight
+ = window.innerHeight - remoteVideos.outerHeight();
+ var availableWidth = Util.getAvailableVideoWidth();
+
+ var aspectRatio = 16.0 / 9.0;
+ if (availableHeight < availableWidth / aspectRatio) {
+ availableWidth = Math.floor(availableHeight * aspectRatio);
+ }
+
+ $('#etherpad>iframe').width(availableWidth);
+ $('#etherpad>iframe').height(availableHeight);
+ }
+ }
+
/**
* Shares the Etherpad name with other participants.
*/
@@ -127,5 +152,12 @@ var Etherpad = (function (my) {
Etherpad.toggleEtherpad(isPresentation);
});
+ /**
+ * Resizes the etherpad, when the window is resized.
+ */
+ $(window).resize(function () {
+ resize();
+ });
+
return my;
}(Etherpad || {}));
diff --git a/fonts/jitsi.eot b/fonts/jitsi.eot
new file mode 100755
index 000000000..26d0f7d65
Binary files /dev/null and b/fonts/jitsi.eot differ
diff --git a/fonts/jitsi.svg b/fonts/jitsi.svg
new file mode 100755
index 000000000..91ad129c5
--- /dev/null
+++ b/fonts/jitsi.svg
@@ -0,0 +1,25 @@
+
+
+
\ No newline at end of file
diff --git a/fonts/jitsi.ttf b/fonts/jitsi.ttf
new file mode 100755
index 000000000..b0adc9cae
Binary files /dev/null and b/fonts/jitsi.ttf differ
diff --git a/fonts/jitsi.woff b/fonts/jitsi.woff
new file mode 100755
index 000000000..468e18307
Binary files /dev/null and b/fonts/jitsi.woff differ
diff --git a/images/avatar1.png b/images/avatar1.png
index 98f6873b3..d3e9f351e 100644
Binary files a/images/avatar1.png and b/images/avatar1.png differ
diff --git a/images/avatarprezi.png b/images/avatarprezi.png
index 99e23af2d..949c49ec6 100644
Binary files a/images/avatarprezi.png and b/images/avatarprezi.png differ
diff --git a/images/watermark.png b/images/watermark.png
new file mode 100644
index 000000000..6fa553d3b
Binary files /dev/null and b/images/watermark.png differ
diff --git a/index.html b/index.html
index 15be85df5..f21d83e06 100644
--- a/index.html
+++ b/index.html
@@ -20,10 +20,14 @@
+
+
+
+
+
+
+
+
diff --git a/prezi.js b/prezi.js
new file mode 100644
index 000000000..4800f5d34
--- /dev/null
+++ b/prezi.js
@@ -0,0 +1,333 @@
+var Prezi = (function (my) {
+ var preziPlayer = null;
+
+ /**
+ * Reloads the current presentation.
+ */
+ my.reloadPresentation = function() {
+ var iframe = document.getElementById(preziPlayer.options.preziId);
+ iframe.src = iframe.src;
+ };
+
+ /**
+ * Shows/hides a presentation.
+ */
+ my.setPresentationVisible = function (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 () {
+ setLargeVideoVisible(false);
+ $('#presentation>iframe').fadeIn(300, function() {
+ $('#presentation>iframe').css({opacity:'1'});
+ dockToolbar(true);
+ });
+ });
+ }
+ else {
+ if ($('#presentation>iframe').css('opacity') == '1') {
+ $('#presentation>iframe').fadeOut(300, function () {
+ $('#presentation>iframe').css({opacity:'0'});
+ $('#reloadPresentation').css({display:'none'});
+ $('#largeVideo').fadeIn(300, function() {
+ setLargeVideoVisible(true);
+ dockToolbar(false);
+ });
+ });
+ }
+ }
+ };
+
+ /**
+ * Returns true if the presentation is visible, false -
+ * otherwise.
+ */
+ my.isPresentationVisible = function () {
+ return ($('#presentation>iframe') != null
+ && $('#presentation>iframe').css('opacity') == 1);
+ };
+
+ /**
+ * Opens the Prezi dialog, from which the user could choose a presentation
+ * to load.
+ */
+ my.openPreziDialog = function() {
+ var myprezi = connection.emuc.getPrezi(connection.emuc.myroomjid);
+ if (myprezi) {
+ $.prompt("Are you sure you would like to remove your Prezi?",
+ {
+ title: "Remove Prezi",
+ buttons: { "Remove": true, "Cancel": false},
+ defaultButton: 1,
+ submit: function(e,v,m,f){
+ if(v)
+ {
+ connection.emuc.removePreziFromPresence();
+ connection.emuc.sendPresence();
+ }
+ }
+ });
+ }
+ else if (preziPlayer != null) {
+ $.prompt("Another participant is already sharing a Prezi." +
+ "This conference allows only one Prezi at a time.",
+ {
+ title: "Share a Prezi",
+ buttons: { "Ok": true},
+ defaultButton: 0,
+ submit: function(e,v,m,f){
+ $.prompt.close();
+ }
+ });
+ }
+ else {
+ var openPreziState = {
+ state0: {
+ html: 'Share a Prezi
' +
+ '',
+ persistent: false,
+ buttons: { "Share": true , "Cancel": false},
+ defaultButton: 1,
+ submit: function(e,v,m,f){
+ e.preventDefault();
+ if(v)
+ {
+ var preziUrl = document.getElementById('preziUrl');
+
+ if (preziUrl.value)
+ {
+ var urlValue
+ = encodeURI(Util.escapeHtml(preziUrl.value));
+
+ if (urlValue.indexOf('http://prezi.com/') != 0
+ && urlValue.indexOf('https://prezi.com/') != 0)
+ {
+ $.prompt.goToState('state1');
+ return false;
+ }
+ else {
+ var presIdTmp = urlValue.substring(
+ urlValue.indexOf("prezi.com/") + 10);
+ if (!Util.isAlphanumeric(presIdTmp)
+ || presIdTmp.indexOf('/') < 2) {
+ $.prompt.goToState('state1');
+ return false;
+ }
+ else {
+ connection.emuc
+ .addPreziToPresence(urlValue, 0);
+ connection.emuc.sendPresence();
+ $.prompt.close();
+ }
+ }
+ }
+ }
+ else
+ $.prompt.close();
+ }
+ },
+ state1: {
+ html: 'Share a Prezi
' +
+ 'Please provide a correct prezi link.',
+ persistent: false,
+ buttons: { "Back": true, "Cancel": false },
+ defaultButton: 1,
+ submit:function(e,v,m,f) {
+ e.preventDefault();
+ if(v==0)
+ $.prompt.close();
+ else
+ $.prompt.goToState('state0');
+ }
+ }
+ };
+
+ var myPrompt = jQuery.prompt(openPreziState);
+
+ myPrompt.on('impromptu:loaded', function(e) {
+ document.getElementById('preziUrl').focus();
+ });
+ myPrompt.on('impromptu:statechanged', function(e) {
+ document.getElementById('preziUrl').focus();
+ });
+ }
+ };
+
+ /**
+ * A new presentation has been added.
+ *
+ * @param event the event indicating the add of a presentation
+ * @param jid the jid from which the presentation was added
+ * @param presUrl url of the presentation
+ * @param currentSlide the current slide to which we should move
+ */
+ var presentationAdded = function(event, jid, presUrl, currentSlide) {
+ console.log("presentation added", presUrl);
+
+ var presId = getPresentationId(presUrl);
+ var elementId = 'participant_'
+ + Strophe.getResourceFromJid(jid)
+ + '_' + presId;
+
+ addRemoteVideoContainer(elementId);
+ resizeThumbnails();
+
+ var controlsEnabled = false;
+ if (jid === connection.emuc.myroomjid)
+ controlsEnabled = true;
+
+ Prezi.setPresentationVisible(true);
+ $('#largeVideoContainer').hover(
+ function (event) {
+ if (Prezi.isPresentationVisible()) {
+ var reloadButtonRight = window.innerWidth
+ - $('#presentation>iframe').offset().left
+ - $('#presentation>iframe').width();
+
+ $('#reloadPresentation').css({ right: reloadButtonRight,
+ display:'inline-block'});
+ }
+ },
+ function (event) {
+ if (!Prezi.isPresentationVisible())
+ $('#reloadPresentation').css({display:'none'});
+ else {
+ var e = event.toElement || event.relatedTarget;
+
+ if (e && e.id != 'reloadPresentation' && e.id != 'header')
+ $('#reloadPresentation').css({display:'none'});
+ }
+ });
+
+ preziPlayer = new PreziPlayer(
+ 'presentation',
+ {preziId: presId,
+ width: getPresentationWidth(),
+ height: getPresentationHeihgt(),
+ controls: controlsEnabled,
+ debug: true
+ });
+
+ $('#presentation>iframe').attr('id', preziPlayer.options.preziId);
+
+ preziPlayer.on(PreziPlayer.EVENT_STATUS, function(event) {
+ console.log("prezi status", event.value);
+ if (event.value == PreziPlayer.STATUS_CONTENT_READY) {
+ if (jid != connection.emuc.myroomjid)
+ preziPlayer.flyToStep(currentSlide);
+ }
+ });
+
+ preziPlayer.on(PreziPlayer.EVENT_CURRENT_STEP, function(event) {
+ console.log("event value", event.value);
+ connection.emuc.addCurrentSlideToPresence(event.value);
+ connection.emuc.sendPresence();
+ });
+
+ $("#" + elementId).css( 'background-image',
+ 'url(../images/avatarprezi.png)');
+ $("#" + elementId).click(
+ function () {
+ Prezi.setPresentationVisible(true);
+ }
+ );
+ };
+
+ /**
+ * A presentation has been removed.
+ *
+ * @param event the event indicating the remove of a presentation
+ * @param jid the jid for which the presentation was removed
+ * @param the url of the presentation
+ */
+ var presentationRemoved = function (event, jid, presUrl) {
+ console.log('presentation removed', presUrl);
+ var presId = getPresentationId(presUrl);
+ Prezi.setPresentationVisible(false);
+ $('#participant_'
+ + Strophe.getResourceFromJid(jid)
+ + '_' + presId).remove();
+ $('#presentation>iframe').remove();
+ if (preziPlayer != null) {
+ preziPlayer.destroy();
+ preziPlayer = null;
+ }
+ };
+
+ /**
+ * Returns the presentation id from the given url.
+ */
+ function getPresentationId (presUrl) {
+ var presIdTmp = presUrl.substring(presUrl.indexOf("prezi.com/") + 10);
+ return presIdTmp.substring(0, presIdTmp.indexOf('/'));
+ }
+
+ /**
+ * Returns the presentation width.
+ */
+ function getPresentationWidth() {
+ var availableWidth = Util.getAvailableVideoWidth();
+ var availableHeight = getPresentationHeihgt();
+
+ var aspectRatio = 16.0 / 9.0;
+ if (availableHeight < availableWidth / aspectRatio) {
+ availableWidth = Math.floor(availableHeight * aspectRatio);
+ }
+ return availableWidth;
+ }
+
+ /**
+ * Returns the presentation height.
+ */
+ function getPresentationHeihgt() {
+ var remoteVideos = $('#remoteVideos');
+ return window.innerHeight - remoteVideos.outerHeight();
+ }
+
+ /**
+ * Resizes the presentation iframe.
+ */
+ function resize() {
+ if ($('#presentation>iframe')) {
+ $('#presentation>iframe').width(getPresentationWidth());
+ $('#presentation>iframe').height(getPresentationHeihgt());
+ }
+ }
+
+ /**
+ * Presentation has been removed.
+ */
+ $(document).bind('presentationremoved.muc', presentationRemoved);
+
+ /**
+ * Presentation has been added.
+ */
+ $(document).bind('presentationadded.muc', presentationAdded);
+
+ /*
+ * Indicates presentation slide change.
+ */
+ $(document).bind('gotoslide.muc', function (event, jid, presUrl, current) {
+ if (preziPlayer) {
+ preziPlayer.flyToStep(current);
+ }
+ });
+
+ /**
+ * On video selected event.
+ */
+ $(document).bind('video.selected', function (event, isPresentation) {
+ if (!isPresentation && $('#presentation>iframe'))
+ Prezi.setPresentationVisible(false);
+ });
+
+ $(window).resize(function () {
+ resize();
+ });
+
+ return my;
+}(Prezi || {}));
\ No newline at end of file
diff --git a/util.js b/util.js
index 9cff8c18a..b2f6d2ed2 100644
--- a/util.js
+++ b/util.js
@@ -57,5 +57,16 @@ var Util = (function (my) {
return regex.test(unsafeText);
};
+ /**
+ * Returns the available video width.
+ */
+ my.getAvailableVideoWidth = function() {
+ var chatspaceWidth = $('#chatspace').is(":visible")
+ ? $('#chatspace').width()
+ : 0;
+
+ return window.innerWidth - chatspaceWidth;
+ };
+
return my;
}(Util || {}));
\ No newline at end of file