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 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + \ 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