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