2016-11-02 14:58:43 +00:00
|
|
|
/* global APP, $ */
|
2015-12-11 14:48:16 +00:00
|
|
|
|
|
|
|
import {processReplacements, linkify} from './Replacement';
|
|
|
|
import CommandsProcessor from './Commands';
|
|
|
|
import ToolbarToggler from '../../toolbars/ToolbarToggler';
|
2016-09-15 19:02:56 +00:00
|
|
|
import VideoLayout from "../../videolayout/VideoLayout";
|
2015-12-11 14:48:16 +00:00
|
|
|
|
|
|
|
import UIUtil from '../../util/UIUtil';
|
|
|
|
import UIEvents from '../../../../service/UI/UIEvents';
|
|
|
|
|
2016-09-19 17:48:38 +00:00
|
|
|
import { smileys } from './smileys';
|
2015-01-07 14:54:03 +00:00
|
|
|
|
2016-11-02 14:58:43 +00:00
|
|
|
let unreadMessages = 0;
|
|
|
|
const sidePanelsContainerId = 'sideToolbarContainer';
|
|
|
|
const htmlStr = `
|
2016-10-25 13:16:15 +00:00
|
|
|
<div id="chat_container" class="sideToolbarContainer__inner">
|
|
|
|
<div id="nickname">
|
|
|
|
<span data-i18n="chat.nickname.title"></span>
|
|
|
|
<form>
|
2016-11-09 16:46:58 +00:00
|
|
|
<input type='text'
|
|
|
|
class="input-control" id="nickinput" autofocus
|
2016-10-25 13:16:15 +00:00
|
|
|
data-i18n="[placeholder]chat.nickname.popover">
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="chatconversation"></div>
|
|
|
|
<audio id="chatNotification" src="sounds/incomingMessage.wav"
|
|
|
|
preload="auto"></audio>
|
|
|
|
<textarea id="usermsg" autofocus
|
|
|
|
data-i18n="[placeholder]chat.messagebox"></textarea>
|
|
|
|
<div id="smileysarea">
|
|
|
|
<div id="smileys" id="toggle_smileys">
|
|
|
|
<img src="images/smile.svg"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2016-11-02 14:58:43 +00:00
|
|
|
</div>`;
|
|
|
|
|
2016-10-25 13:16:15 +00:00
|
|
|
function initHTML() {
|
2016-11-02 14:58:43 +00:00
|
|
|
$(`#${sidePanelsContainerId}`)
|
|
|
|
.append(htmlStr);
|
2016-10-25 13:16:15 +00:00
|
|
|
}
|
|
|
|
|
2016-09-14 20:13:15 +00:00
|
|
|
/**
|
|
|
|
* The container id, which is and the element id.
|
|
|
|
*/
|
|
|
|
var CHAT_CONTAINER_ID = "chat_container";
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
2016-09-14 20:18:14 +00:00
|
|
|
* Updates visual notification, indicating that a message has arrived.
|
2015-01-07 14:54:03 +00:00
|
|
|
*/
|
2016-09-14 20:18:14 +00:00
|
|
|
function updateVisualNotification() {
|
2015-01-07 14:54:03 +00:00
|
|
|
var unreadMsgElement = document.getElementById('unreadMessages');
|
|
|
|
|
|
|
|
if (unreadMessages) {
|
|
|
|
unreadMsgElement.innerHTML = unreadMessages.toString();
|
|
|
|
|
|
|
|
ToolbarToggler.dockToolbar(true);
|
|
|
|
|
|
|
|
var chatButtonElement
|
2015-08-05 21:56:08 +00:00
|
|
|
= document.getElementById('toolbar_button_chat');
|
2015-01-23 12:01:44 +00:00
|
|
|
var leftIndent = (UIUtil.getTextWidth(chatButtonElement) -
|
|
|
|
UIUtil.getTextWidth(unreadMsgElement)) / 2;
|
|
|
|
var topIndent = (UIUtil.getTextHeight(chatButtonElement) -
|
2016-03-24 17:17:58 +00:00
|
|
|
UIUtil.getTextHeight(unreadMsgElement)) / 2 - 5;
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
unreadMsgElement.setAttribute(
|
|
|
|
'style',
|
|
|
|
'top:' + topIndent +
|
|
|
|
'; left:' + leftIndent + ';');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
unreadMsgElement.innerHTML = '';
|
|
|
|
}
|
2016-09-20 02:22:41 +00:00
|
|
|
|
|
|
|
$(unreadMsgElement).parent()[unreadMessages > 0 ? 'show' : 'hide']();
|
2015-01-07 14:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current time in the format it is shown to the user
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
2015-06-12 21:14:31 +00:00
|
|
|
function getCurrentTime(stamp) {
|
|
|
|
var now = (stamp? new Date(stamp): new Date());
|
2015-01-07 14:54:03 +00:00
|
|
|
var hour = now.getHours();
|
|
|
|
var minute = now.getMinutes();
|
|
|
|
var second = now.getSeconds();
|
|
|
|
if(hour.toString().length === 1) {
|
|
|
|
hour = '0'+hour;
|
|
|
|
}
|
|
|
|
if(minute.toString().length === 1) {
|
|
|
|
minute = '0'+minute;
|
|
|
|
}
|
|
|
|
if(second.toString().length === 1) {
|
|
|
|
second = '0'+second;
|
|
|
|
}
|
|
|
|
return hour+':'+minute+':'+second;
|
|
|
|
}
|
|
|
|
|
2015-07-28 21:52:32 +00:00
|
|
|
function toggleSmileys() {
|
2015-01-07 14:54:03 +00:00
|
|
|
var smileys = $('#smileysContainer');
|
|
|
|
if(!smileys.is(':visible')) {
|
|
|
|
smileys.show("slide", { direction: "down", duration: 300});
|
|
|
|
} else {
|
|
|
|
smileys.hide("slide", { direction: "down", duration: 300});
|
|
|
|
}
|
|
|
|
$('#usermsg').focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
function addClickFunction(smiley, number) {
|
|
|
|
smiley.onclick = function addSmileyToMessage() {
|
|
|
|
var usermsg = $('#usermsg');
|
|
|
|
var message = usermsg.val();
|
|
|
|
message += smileys['smiley' + number];
|
|
|
|
usermsg.val(message);
|
|
|
|
usermsg.get(0).setSelectionRange(message.length, message.length);
|
|
|
|
toggleSmileys();
|
|
|
|
usermsg.focus();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the smileys container to the chat
|
|
|
|
*/
|
|
|
|
function addSmileys() {
|
|
|
|
var smileysContainer = document.createElement('div');
|
|
|
|
smileysContainer.id = 'smileysContainer';
|
|
|
|
for(var i = 1; i <= 21; i++) {
|
|
|
|
var smileyContainer = document.createElement('div');
|
|
|
|
smileyContainer.id = 'smiley' + i;
|
|
|
|
smileyContainer.className = 'smileyContainer';
|
|
|
|
var smiley = document.createElement('img');
|
|
|
|
smiley.src = 'images/smileys/smiley' + i + '.svg';
|
|
|
|
smiley.className = 'smiley';
|
|
|
|
addClickFunction(smiley, i);
|
|
|
|
smileyContainer.appendChild(smiley);
|
|
|
|
smileysContainer.appendChild(smileyContainer);
|
|
|
|
}
|
|
|
|
|
2016-09-08 22:34:16 +00:00
|
|
|
$("#chat_container").append(smileysContainer);
|
2015-01-07 14:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes the chat conversation.
|
|
|
|
*/
|
|
|
|
function resizeChatConversation() {
|
|
|
|
var msgareaHeight = $('#usermsg').outerHeight();
|
2016-09-14 20:13:15 +00:00
|
|
|
var chatspace = $('#' + CHAT_CONTAINER_ID);
|
2015-01-07 14:54:03 +00:00
|
|
|
var width = chatspace.width();
|
|
|
|
var chat = $('#chatconversation');
|
|
|
|
var smileys = $('#smileysarea');
|
|
|
|
|
|
|
|
smileys.height(msgareaHeight);
|
|
|
|
$("#smileys").css('bottom', (msgareaHeight - 26) / 2);
|
|
|
|
$('#smileysContainer').css('bottom', msgareaHeight);
|
|
|
|
chat.width(width - 10);
|
|
|
|
chat.height(window.innerHeight - 15 - msgareaHeight);
|
|
|
|
}
|
|
|
|
|
2016-11-16 12:09:22 +00:00
|
|
|
/**
|
|
|
|
* Focus input after 400 ms
|
|
|
|
* Found input by id
|
|
|
|
*
|
|
|
|
* @param id {string} input id
|
|
|
|
*/
|
2016-11-15 18:18:40 +00:00
|
|
|
function deferredFocus(id){
|
|
|
|
setTimeout(function (){
|
|
|
|
$(`#${id}`).focus();
|
|
|
|
}, 400);
|
|
|
|
}
|
2015-01-07 14:54:03 +00:00
|
|
|
/**
|
|
|
|
* Chat related user interface.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
var Chat = {
|
2015-01-07 14:54:03 +00:00
|
|
|
/**
|
|
|
|
* Initializes chat related interface.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
init (eventEmitter) {
|
2016-10-25 13:16:15 +00:00
|
|
|
initHTML();
|
2015-12-01 12:53:01 +00:00
|
|
|
if (APP.settings.getDisplayName()) {
|
2015-01-07 14:54:03 +00:00
|
|
|
Chat.setChatConversationMode(true);
|
2015-12-01 12:53:01 +00:00
|
|
|
}
|
2015-01-07 14:54:03 +00:00
|
|
|
|
2016-10-25 13:16:15 +00:00
|
|
|
$("#toggle_smileys").click(function() {
|
|
|
|
Chat.toggleSmileys();
|
|
|
|
});
|
|
|
|
|
2015-01-07 14:54:03 +00:00
|
|
|
$('#nickinput').keydown(function (event) {
|
|
|
|
if (event.keyCode === 13) {
|
|
|
|
event.preventDefault();
|
2016-02-12 12:48:57 +00:00
|
|
|
let val = this.value;
|
2015-01-07 14:54:03 +00:00
|
|
|
this.value = '';
|
2015-12-14 16:54:08 +00:00
|
|
|
eventEmitter.emit(UIEvents.NICKNAME_CHANGED, val);
|
2016-11-15 18:18:40 +00:00
|
|
|
deferredFocus('usermsg');
|
2015-01-07 14:54:03 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-07-28 21:52:32 +00:00
|
|
|
var usermsg = $('#usermsg');
|
|
|
|
usermsg.keydown(function (event) {
|
2015-01-07 14:54:03 +00:00
|
|
|
if (event.keyCode === 13) {
|
|
|
|
event.preventDefault();
|
|
|
|
var value = this.value;
|
2015-07-28 21:52:32 +00:00
|
|
|
usermsg.val('').trigger('autosize.resize');
|
2015-01-07 14:54:03 +00:00
|
|
|
this.focus();
|
2015-12-11 14:48:16 +00:00
|
|
|
var command = new CommandsProcessor(value, eventEmitter);
|
|
|
|
if (command.isCommand()) {
|
2015-01-07 14:54:03 +00:00
|
|
|
command.processCommand();
|
2015-12-11 14:48:16 +00:00
|
|
|
} else {
|
2015-01-23 12:01:44 +00:00
|
|
|
var message = UIUtil.escapeHtml(value);
|
2015-12-01 12:53:01 +00:00
|
|
|
eventEmitter.emit(UIEvents.MESSAGE_CREATED, message);
|
2015-01-07 14:54:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
var onTextAreaResize = function () {
|
|
|
|
resizeChatConversation();
|
|
|
|
Chat.scrollChatToBottom();
|
|
|
|
};
|
2015-07-28 21:52:32 +00:00
|
|
|
usermsg.autosize({callback: onTextAreaResize});
|
2015-01-07 14:54:03 +00:00
|
|
|
|
2016-09-14 20:22:36 +00:00
|
|
|
eventEmitter.on(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED,
|
|
|
|
function(containerId, isVisible) {
|
|
|
|
if (containerId !== CHAT_CONTAINER_ID || !isVisible)
|
|
|
|
return;
|
|
|
|
|
2015-01-07 14:54:03 +00:00
|
|
|
unreadMessages = 0;
|
2016-09-14 20:18:14 +00:00
|
|
|
updateVisualNotification();
|
2016-09-14 20:26:38 +00:00
|
|
|
|
2016-09-15 19:02:56 +00:00
|
|
|
// Undock the toolbar when the chat is shown and if we're in a
|
|
|
|
// video mode.
|
|
|
|
if (VideoLayout.isLargeVideoVisible()) {
|
|
|
|
ToolbarToggler.dockToolbar(false);
|
|
|
|
}
|
|
|
|
|
2016-09-14 20:26:38 +00:00
|
|
|
// if we are in conversation mode focus on the text input
|
|
|
|
// if we are not, focus on the display name input
|
|
|
|
if (APP.settings.getDisplayName())
|
2016-11-15 18:18:40 +00:00
|
|
|
deferredFocus('usermsg');
|
2016-09-14 20:26:38 +00:00
|
|
|
else
|
2016-11-15 18:18:40 +00:00
|
|
|
deferredFocus('nickinput');
|
2015-01-07 14:54:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
addSmileys();
|
2016-09-20 02:22:41 +00:00
|
|
|
updateVisualNotification();
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Appends the given message to the chat conversation.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
updateChatConversation (id, displayName, message, stamp) {
|
2015-01-07 14:54:03 +00:00
|
|
|
var divClassName = '';
|
|
|
|
|
2015-12-11 14:48:16 +00:00
|
|
|
if (APP.conference.isLocalId(id)) {
|
2015-01-07 14:54:03 +00:00
|
|
|
divClassName = "localuser";
|
2015-12-11 14:48:16 +00:00
|
|
|
} else {
|
2015-01-07 14:54:03 +00:00
|
|
|
divClassName = "remoteuser";
|
|
|
|
|
|
|
|
if (!Chat.isVisible()) {
|
|
|
|
unreadMessages++;
|
2015-01-23 12:01:44 +00:00
|
|
|
UIUtil.playSoundNotification('chatNotification');
|
2016-09-14 20:18:14 +00:00
|
|
|
updateVisualNotification();
|
2015-01-07 14:54:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// replace links and smileys
|
|
|
|
// Strophe already escapes special symbols on sending,
|
|
|
|
// so we escape here only tags to avoid double &
|
|
|
|
var escMessage = message.replace(/</g, '<').
|
|
|
|
replace(/>/g, '>').replace(/\n/g, '<br/>');
|
2015-01-23 12:01:44 +00:00
|
|
|
var escDisplayName = UIUtil.escapeHtml(displayName);
|
2015-12-11 14:48:16 +00:00
|
|
|
message = processReplacements(escMessage);
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
var messageContainer =
|
|
|
|
'<div class="chatmessage">'+
|
2016-05-27 15:45:38 +00:00
|
|
|
'<img src="images/chatArrow.svg" class="chatArrow">' +
|
2015-01-07 14:54:03 +00:00
|
|
|
'<div class="username ' + divClassName +'">' + escDisplayName +
|
2015-06-12 21:14:31 +00:00
|
|
|
'</div>' + '<div class="timestamp">' + getCurrentTime(stamp) +
|
2015-01-07 14:54:03 +00:00
|
|
|
'</div>' + '<div class="usermessage">' + message + '</div>' +
|
|
|
|
'</div>';
|
|
|
|
|
|
|
|
$('#chatconversation').append(messageContainer);
|
|
|
|
$('#chatconversation').animate(
|
|
|
|
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Appends error message to the conversation
|
|
|
|
* @param errorMessage the received error message.
|
|
|
|
* @param originalText the original message.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
chatAddError (errorMessage, originalText) {
|
2015-01-23 12:01:44 +00:00
|
|
|
errorMessage = UIUtil.escapeHtml(errorMessage);
|
|
|
|
originalText = UIUtil.escapeHtml(originalText);
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
$('#chatconversation').append(
|
|
|
|
'<div class="errorMessage"><b>Error: </b>' + 'Your message' +
|
|
|
|
(originalText? (' \"'+ originalText + '\"') : "") +
|
|
|
|
' was not sent.' +
|
|
|
|
(errorMessage? (' Reason: ' + errorMessage) : '') + '</div>');
|
|
|
|
$('#chatconversation').animate(
|
|
|
|
{ scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the subject to the UI
|
|
|
|
* @param subject the subject
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
setSubject (subject) {
|
2016-11-04 13:58:43 +00:00
|
|
|
let toggleFunction;
|
2015-12-11 14:48:16 +00:00
|
|
|
if (subject) {
|
2015-01-07 14:54:03 +00:00
|
|
|
subject = subject.trim();
|
|
|
|
}
|
2016-11-04 13:58:43 +00:00
|
|
|
|
2016-11-11 10:27:29 +00:00
|
|
|
toggleFunction = subject ? UIUtil.showElement : UIUtil.hideElement;
|
|
|
|
toggleFunction = toggleFunction.bind(UIUtil);
|
|
|
|
|
2016-11-04 13:58:43 +00:00
|
|
|
let subjectId = 'subject';
|
|
|
|
let html = linkify(UIUtil.escapeHtml(subject));
|
|
|
|
$(`#${subjectId}`).html(html);
|
|
|
|
toggleFunction(subjectId);
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the chat conversation mode.
|
2016-09-14 20:26:38 +00:00
|
|
|
* Conversation mode is the normal chat mode, non conversation mode is
|
|
|
|
* where we ask user to input its display name.
|
2016-02-12 14:15:34 +00:00
|
|
|
* @param {boolean} isConversationMode if chat should be in
|
|
|
|
* conversation mode or not.
|
2015-01-07 14:54:03 +00:00
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
setChatConversationMode (isConversationMode) {
|
2016-09-14 20:13:15 +00:00
|
|
|
$('#' + CHAT_CONTAINER_ID)
|
2016-09-08 22:34:16 +00:00
|
|
|
.toggleClass('is-conversation-mode', isConversationMode);
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes the chat area.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
resizeChat (width, height) {
|
2016-09-14 20:13:15 +00:00
|
|
|
$('#' + CHAT_CONTAINER_ID).width(width).height(height);
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
resizeChatConversation();
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates if the chat is currently visible.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
isVisible () {
|
2016-09-08 22:34:16 +00:00
|
|
|
return UIUtil.isVisible(
|
2016-09-14 20:13:15 +00:00
|
|
|
document.getElementById(CHAT_CONTAINER_ID));
|
2015-12-11 14:48:16 +00:00
|
|
|
},
|
2015-01-07 14:54:03 +00:00
|
|
|
/**
|
|
|
|
* Shows and hides the window with the smileys
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
toggleSmileys,
|
2015-01-07 14:54:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Scrolls chat to the bottom.
|
|
|
|
*/
|
2015-12-11 14:48:16 +00:00
|
|
|
scrollChatToBottom () {
|
2015-01-07 14:54:03 +00:00
|
|
|
setTimeout(function () {
|
|
|
|
$('#chatconversation').scrollTop(
|
|
|
|
$('#chatconversation')[0].scrollHeight);
|
|
|
|
}, 5);
|
2015-12-11 14:48:16 +00:00
|
|
|
}
|
|
|
|
};
|
2015-01-07 14:54:03 +00:00
|
|
|
|
2015-12-11 14:48:16 +00:00
|
|
|
export default Chat;
|