diff --git a/app.js b/app.js index b8ec80cf1..b29fd2c64 100644 --- a/app.js +++ b/app.js @@ -182,6 +182,8 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) { container = document.createElement('span'); container.className = 'videocontainer'; remotes.appendChild(container); + console.log("PLAY USER JOINEDDDDDDDD"); + Util.playSoundNotification('userJoined'); } var vid = document.createElement('video'); var id = 'remoteVideo_' + sid + '_' + data.stream.id; @@ -212,11 +214,12 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) { if (pick) { if (pick.src === localVideoSrc) isLocalVideo = true; - + updateLargeVideo(pick.src, isLocalVideo, pick.volume); } } $('#' + id).parent().remove(); + Util.playSoundNotification('userLeft'); resizeThumbnails(); }; sel.click( @@ -632,8 +635,8 @@ function toggleAudio() { } } -function resizeLarge() { - resizeChat(); +var resizeLarge = function () { + Chat.resizeChat(); var availableHeight = window.innerHeight; var chatspaceWidth = $('#chatspace').is(":visible") ? $('#chatspace').width() @@ -666,7 +669,7 @@ function resizeLarge() { } resizeThumbnails(); -} +}; function resizeThumbnails() { // Calculate the available height, which is the inner window height minus 39px for the header @@ -691,70 +694,8 @@ function resizeThumbnails() { $('#remoteVideos>span').height(availableHeight); } -function resizeChat() { - var availableHeight = window.innerHeight; - var availableWidth = window.innerWidth; - - var chatWidth = 200; - if (availableWidth*0.2 < 200) - chatWidth = availableWidth*0.2; - - $('#chatspace').width(chatWidth); - $('#chatspace').height(availableHeight - 40); - - resizeChatConversation(); -} - -function resizeChatConversation() { - var usermsgStyleHeight = document.getElementById("usermsg").style.height; - var usermsgHeight = usermsgStyleHeight.substring(0, usermsgStyleHeight.indexOf('px')); - - $('#chatconversation').width($('#chatspace').width() - 10); - $('#chatconversation').height(window.innerHeight - 50 - parseInt(usermsgHeight)); -} - $(document).ready(function () { - var storedDisplayName = window.localStorage.displayname; - if (storedDisplayName) { - nickname = storedDisplayName; - - setChatConversationMode(true); - } - - $('#nickinput').keydown(function(event) { - if (event.keyCode == 13) { - event.preventDefault(); - var val = this.value; - this.value = ''; - if (!nickname) { - nickname = val; - window.localStorage.displayname = nickname; - - connection.emuc.addDisplayNameToPresence(nickname); - connection.emuc.sendPresence(); - - setChatConversationMode(true); - - return; - } - } - }); - - $('#usermsg').keydown(function(event) { - if (event.keyCode == 13) { - event.preventDefault(); - var message = this.value; - $('#usermsg').val('').trigger('autosize.resize'); - this.focus(); - connection.emuc.sendMessage(message, nickname); - } - }); - - var onTextAreaResize = function() { - resizeChatConversation(); - scrollChatToBottom(); - }; - $('#usermsg').autosize({callback: onTextAreaResize}); + Chat.init(); // Set the defaults for prompt dialogs. jQuery.prompt.setDefaults({persistent: false}); @@ -826,24 +767,6 @@ function dump(elem, filename){ return false; } -/* - * Appends the given message to the chat conversation. - */ -function updateChatConversation(nick, message) -{ - var divClassName = ''; - if (nickname == nick) - divClassName = "localuser"; - else - divClassName = "remoteuser"; - - //replace links and smileys - message = processReplacements(message); - - $('#chatconversation').append('
' + nick + ': ' + message + '
'); - $('#chatconversation').animate({ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000); -} - /* * Changes the style class of the element given by id. */ @@ -1092,44 +1015,6 @@ function updateLockButton() { buttonClick("#lockIcon", "fa fa-unlock fa-lg fa fa-lock fa-lg"); } -/* - * Opens / closes the chat area. - */ -function openChat() { - 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(); - }; - - if (chatspace.css("display") == 'block') { - videospace.animate({right: 0}, {queue: false, duration: 500, progress: onHide}); - } - else { - videospace.animate({right: chatspace.width()}, - {queue: false, - duration: 500, - progress: onShow, - complete: function() { - scrollChatToBottom(); - } - }); - } - - // Request the focus in the nickname field or the chat input field. - if ($('#nickname').css('visibility') == 'visible') - $('#nickinput').focus(); - else { - $('#usermsg').focus(); - } -} - /* * Shows the call main toolbar. */ @@ -1199,7 +1084,7 @@ function addRemoteVideoContainer(id) { return container; } -/* +/** * Creates the element indicating the focus of the conference. */ function createFocusIndicatorElement(parentElement) { @@ -1209,13 +1094,7 @@ function createFocusIndicatorElement(parentElement) { parentElement.appendChild(focusIndicator); } -function scrollChatToBottom() { - setTimeout(function() { - $('#chatconversation').scrollTop($('#chatconversation')[0].scrollHeight); - }, 5); -} - -/* +/** * Toggles the application in and out of full screen mode * (a.k.a. presentation mode in Chrome). */ @@ -1246,7 +1125,7 @@ function toggleFullScreen() { } /** - * + * Shows the display name for the given video. */ function showDisplayName(videoSpanId, displayName) { var nameSpan = $('#' + videoSpanId + '>span.displayname'); @@ -1306,7 +1185,7 @@ function showDisplayName(videoSpanId, displayName) { connection.emuc.addDisplayNameToPresence(nickname); connection.emuc.sendPresence(); - setChatConversationMode(true); + Chat.setChatConversationMode(true); } if (!$('#localDisplayName').is(":visible")) { @@ -1337,13 +1216,4 @@ function createEditDisplayNameButton() { editButton.innerHTML = ''; return editButton; -} - -function setChatConversationMode(isConversationMode) { - if (isConversationMode) { - $('#nickname').css({visibility:"hidden"}); - $('#chatconversation').css({visibility:'visible'}); - $('#usermsg').css({visibility:'visible'}); - $('#usermsg').focus(); - } -} +} \ No newline at end of file diff --git a/chat.js b/chat.js new file mode 100644 index 000000000..11217bced --- /dev/null +++ b/chat.js @@ -0,0 +1,222 @@ +/** + * Chat related user interface. + */ +var Chat = (function (my) { + var notificationInterval = false; + var unreadMessages = 0; + + /** + * Initializes chat related interface. + */ + my.init = function () { + var storedDisplayName = window.localStorage.displayname; + if (storedDisplayName) { + nickname = storedDisplayName; + + Chat.setChatConversationMode(true); + } + + $('#nickinput').keydown(function(event) { + if (event.keyCode == 13) { + event.preventDefault(); + var val = this.value; + this.value = ''; + if (!nickname) { + nickname = val; + window.localStorage.displayname = nickname; + + connection.emuc.addDisplayNameToPresence(nickname); + connection.emuc.sendPresence(); + + Chat.setChatConversationMode(true); + + return; + } + } + }); + + $('#usermsg').keydown(function(event) { + if (event.keyCode == 13) { + event.preventDefault(); + var message = this.value; + $('#usermsg').val('').trigger('autosize.resize'); + this.focus(); + connection.emuc.sendMessage(message, nickname); + } + }); + + var onTextAreaResize = function() { + resizeChatConversation(); + scrollChatToBottom(); + }; + $('#usermsg').autosize({callback: onTextAreaResize}); + + $("#chatspace").bind("shown", + function() { + unreadMessages = 0; + setVisualNotification(false); + }); + }; + + /** + * Appends the given message to the chat conversation. + */ + my.updateChatConversation = function (nick, message) { + var divClassName = ''; + + if (nickname == nick) { + divClassName = "localuser"; + } + else { + divClassName = "remoteuser"; + + if (!$('#chatspace').is(":visible")) { + unreadMessages++; + Util.playSoundNotification('chatNotification'); + setVisualNotification(true); + } + } + + //replace links and smileys + message = processReplacements(message); + + $('#chatconversation').append('
' + + nick + ': ' + message + '
'); + $('#chatconversation').animate( + { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000); + }; + + /** + * Opens / closes the chat area. + */ + my.toggleChat = function () { + 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(); + }; + + if (chatspace.is(":visible")) { + videospace.animate( {right: 0}, + {queue: false, + duration: 500, + progress: onHide}); + } + else { + videospace.animate({right: chatspace.width()}, + {queue: false, + duration: 500, + progress: onShow, + complete: function() { + scrollChatToBottom(); + chatspace.trigger('shown'); + } + }); + } + + // Request the focus in the nickname field or the chat input field. + if ($('#nickname').css('visibility') == 'visible') + $('#nickinput').focus(); + else { + $('#usermsg').focus(); + } + }; + + /** + * Sets the chat conversation mode. + */ + my.setChatConversationMode = function (isConversationMode) { + if (isConversationMode) { + $('#nickname').css({visibility:"hidden"}); + $('#chatconversation').css({visibility:'visible'}); + $('#usermsg').css({visibility:'visible'}); + $('#usermsg').focus(); + } + }; + + /** + * Resizes the chat area. + */ + my.resizeChat = function () { + var availableHeight = window.innerHeight; + var availableWidth = window.innerWidth; + + var chatWidth = 200; + if (availableWidth*0.2 < 200) + chatWidth = availableWidth*0.2; + + $('#chatspace').width(chatWidth); + $('#chatspace').height(availableHeight - 40); + + resizeChatConversation(); + }; + + /** + * Resizes the chat conversation. + */ + function resizeChatConversation() { + var usermsgStyleHeight = document.getElementById("usermsg").style.height; + var usermsgHeight = usermsgStyleHeight + .substring(0, usermsgStyleHeight.indexOf('px')); + + $('#chatconversation').width($('#chatspace').width() - 10); + $('#chatconversation') + .height(window.innerHeight - 50 - parseInt(usermsgHeight)); + }; + + /** + * Shows/hides a visual notification, indicating that a message has arrived. + */ + function setVisualNotification(show) { + var unreadMsgElement = document.getElementById('unreadMessages'); + + if (unreadMessages) { + unreadMsgElement.innerHTML = unreadMessages.toString(); + + var chatButtonElement + = document.getElementById('chat').parentNode; + var leftIndent = (Util.getTextWidth(chatButtonElement) + - Util.getTextWidth(unreadMsgElement) - 5)/2; + var topIndent = (Util.getTextHeight(chatButtonElement) + - Util.getTextHeight(unreadMsgElement))/2 - 2; + + unreadMsgElement.setAttribute( + 'style', + 'top:' + Util.toInteger(topIndent) + + '; left:' + Util.toInteger(leftIndent) +';'); + } + else + unreadMsgElement.innerHTML = ''; + + var glower = $('#chat'); + + if (show && !notificationInterval) { + notificationInterval = window.setInterval(function() { + glower.toggleClass('active'); + }, 800); + } + else if (!show && notificationInterval) { + window.clearInterval(notificationInterval); + notificationInterval = false; + glower.removeClass('active'); + } + } + + /** + * Scrolls chat to the bottom. + */ + function scrollChatToBottom() { + setTimeout(function() { + $('#chatconversation').scrollTop( + $('#chatconversation')[0].scrollHeight); + }, 5); + } + + return my; +}(Chat || {})); \ No newline at end of file diff --git a/css/main.css b/css/main.css index 8f1f0856b..71f37f3af 100644 --- a/css/main.css +++ b/css/main.css @@ -3,7 +3,7 @@ html, body{ height:100%; color: #424242; font-family:'Helvetica Neue', Helvetica, sans-serif; - font-weight: 400; + font-weight: 400; background: #e9e9e9; overflow-x: hidden; } @@ -185,16 +185,16 @@ html, body{ } #left { - display:block; + display:block; position: absolute; - left: 0px; + left: 0px; top: 0px; width: 100px; height: 39px; - background-image:url(../images/left1.png); - background-repeat:no-repeat; - margin: 0; - padding: 0; + background-image:url(../images/left1.png); + background-repeat:no-repeat; + margin: 0; + padding: 0; } #leftlogo { @@ -222,6 +222,11 @@ html, body{ visibility: hidden; } +.toolbar_span { + display: inline-block; + position: relative; +} + .button { display: inline-block; position: relative; @@ -233,6 +238,30 @@ html, body{ font-size: 11pt; text-align: center; text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7); + z-index: 1; +} + +.toolbar_span>span { + display: inline-block; + position: absolute; + font-size: 7pt; + color: #ffffff; + text-align:center; + cursor: pointer; +} + +#chat { + font-size:1.65em; + -webkit-transition: all .5s ease-in-out;; + -moz-transition: all .5s ease-in-out;; + transition: all .5s ease-in-out;; +} + +#chat.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 { @@ -266,15 +295,15 @@ a.button:hover { } #right { - display:block; + display:block; position:absolute; right: 0px; top: 0px; - background-image:url(../images/right1.png); - background-repeat:no-repeat; - margin:0; - padding:0; - width:100px; + background-image:url(../images/right1.png); + background-repeat:no-repeat; + margin:0; + padding:0; + width:100px; height:39px; } diff --git a/etherpad.js b/etherpad.js index 50bee2f50..de6d18969 100644 --- a/etherpad.js +++ b/etherpad.js @@ -15,7 +15,8 @@ var Etherpad = (function (my) { if (!name) { // In case we're the focus we generate the name. - etherpadName = Math.random().toString(36).substring(7) + '_' + (new Date().getTime()).toString(); + etherpadName = Math.random().toString(36).substring(7) + + '_' + (new Date().getTime()).toString(); shareEtherpad(); } else @@ -94,7 +95,8 @@ var Etherpad = (function (my) { button.appendChild(buttonImage); var toolbar = document.getElementById('toolbar'); - toolbar.insertBefore(button, toolbar.childNodes[toolbar.childNodes.length - 4]); + toolbar.insertBefore(button, + toolbar.childNodes[toolbar.childNodes.length - 4]); toolbar.insertBefore(separator, button); } diff --git a/index.html b/index.html index 5e2531b68..d728824f8 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,8 @@ + + @@ -25,17 +27,22 @@ - + +
- + +
- + + + +
- +
@@ -65,6 +72,8 @@ + +
@@ -74,9 +83,10 @@
- +
+ diff --git a/muc.js b/muc.js index 94b39d3b7..da746c75c 100644 --- a/muc.js +++ b/muc.js @@ -143,7 +143,7 @@ Strophe.addConnectionPlugin('emuc', { if (txt) { console.log('chat', nick, txt); - updateChatConversation(nick, txt); + Chat.updateChatConversation(nick, txt); } return true; }, diff --git a/sounds/incomingMessage.wav b/sounds/incomingMessage.wav new file mode 100644 index 000000000..012dbab16 Binary files /dev/null and b/sounds/incomingMessage.wav differ diff --git a/sounds/joined.wav b/sounds/joined.wav new file mode 100644 index 000000000..16ceb80ac Binary files /dev/null and b/sounds/joined.wav differ diff --git a/sounds/left.wav b/sounds/left.wav new file mode 100644 index 000000000..0c9cee0a3 Binary files /dev/null and b/sounds/left.wav differ diff --git a/util.js b/util.js new file mode 100644 index 000000000..81f6cfe22 --- /dev/null +++ b/util.js @@ -0,0 +1,43 @@ +/** + * Utility functions. + */ +var Util = (function (my) { + + /** + * Returns the text width for the given element. + * + * @param el the element + */ + my.getTextWidth = function(el) { + return (el.clientWidth + 1); + }; + + /** + * Returns the text height for the given element. + * + * @param el the element + */ + my.getTextHeight = function(el) { + return (el.clientHeight + 1); + }; + + /** + * Casts the given number to integer. + * + * @param number the number to cast + */ + my.toInteger = function(number) { + return Math.round(Number(number)); + }; + + /** + * Plays the sound given by id. + * + * @param id the identifier of the audio element. + */ + my.playSoundNotification = function(id) { + document.getElementById(id).play(); + }; + + return my; +}(Util || {})); \ No newline at end of file