You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Chat.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /* global APP, $ */
  2. import {processReplacements, linkify} from './Replacement';
  3. import CommandsProcessor from './Commands';
  4. import ToolbarToggler from '../../toolbars/ToolbarToggler';
  5. import UIUtil from '../../util/UIUtil';
  6. import UIEvents from '../../../../service/UI/UIEvents';
  7. var smileys = require("./smileys.json").smileys;
  8. var notificationInterval = false;
  9. var unreadMessages = 0;
  10. /**
  11. * Shows/hides a visual notification, indicating that a message has arrived.
  12. */
  13. function setVisualNotification(show) {
  14. var unreadMsgElement = document.getElementById('unreadMessages');
  15. var unreadMsgBottomElement
  16. = document.getElementById('bottomUnreadMessages');
  17. var glower = $('#toolbar_button_chat');
  18. var bottomGlower = $('#chatBottomButton');
  19. if (unreadMessages) {
  20. unreadMsgElement.innerHTML = unreadMessages.toString();
  21. unreadMsgBottomElement.innerHTML = unreadMessages.toString();
  22. ToolbarToggler.dockToolbar(true);
  23. var chatButtonElement
  24. = document.getElementById('toolbar_button_chat');
  25. var leftIndent = (UIUtil.getTextWidth(chatButtonElement) -
  26. UIUtil.getTextWidth(unreadMsgElement)) / 2;
  27. var topIndent = (UIUtil.getTextHeight(chatButtonElement) -
  28. UIUtil.getTextHeight(unreadMsgElement)) / 2 - 3;
  29. unreadMsgElement.setAttribute(
  30. 'style',
  31. 'top:' + topIndent +
  32. '; left:' + leftIndent + ';');
  33. var chatBottomButtonElement
  34. = document.getElementById('chatBottomButton').parentNode;
  35. var bottomLeftIndent = (UIUtil.getTextWidth(chatBottomButtonElement) -
  36. UIUtil.getTextWidth(unreadMsgBottomElement)) / 2;
  37. var bottomTopIndent = (UIUtil.getTextHeight(chatBottomButtonElement) -
  38. UIUtil.getTextHeight(unreadMsgBottomElement)) / 2 - 2;
  39. unreadMsgBottomElement.setAttribute(
  40. 'style',
  41. 'top:' + bottomTopIndent +
  42. '; left:' + bottomLeftIndent + ';');
  43. if (!glower.hasClass('icon-chat-simple')) {
  44. glower.removeClass('icon-chat');
  45. glower.addClass('icon-chat-simple');
  46. }
  47. }
  48. else {
  49. unreadMsgElement.innerHTML = '';
  50. unreadMsgBottomElement.innerHTML = '';
  51. glower.removeClass('icon-chat-simple');
  52. glower.addClass('icon-chat');
  53. }
  54. if (show && !notificationInterval) {
  55. notificationInterval = window.setInterval(function () {
  56. glower.toggleClass('active');
  57. bottomGlower.toggleClass('active glowing');
  58. }, 800);
  59. }
  60. else if (!show && notificationInterval) {
  61. window.clearInterval(notificationInterval);
  62. notificationInterval = false;
  63. glower.removeClass('active');
  64. bottomGlower.removeClass('glowing');
  65. bottomGlower.addClass('active');
  66. }
  67. }
  68. /**
  69. * Returns the current time in the format it is shown to the user
  70. * @returns {string}
  71. */
  72. function getCurrentTime(stamp) {
  73. var now = (stamp? new Date(stamp): new Date());
  74. var hour = now.getHours();
  75. var minute = now.getMinutes();
  76. var second = now.getSeconds();
  77. if(hour.toString().length === 1) {
  78. hour = '0'+hour;
  79. }
  80. if(minute.toString().length === 1) {
  81. minute = '0'+minute;
  82. }
  83. if(second.toString().length === 1) {
  84. second = '0'+second;
  85. }
  86. return hour+':'+minute+':'+second;
  87. }
  88. function toggleSmileys() {
  89. var smileys = $('#smileysContainer');
  90. if(!smileys.is(':visible')) {
  91. smileys.show("slide", { direction: "down", duration: 300});
  92. } else {
  93. smileys.hide("slide", { direction: "down", duration: 300});
  94. }
  95. $('#usermsg').focus();
  96. }
  97. function addClickFunction(smiley, number) {
  98. smiley.onclick = function addSmileyToMessage() {
  99. var usermsg = $('#usermsg');
  100. var message = usermsg.val();
  101. message += smileys['smiley' + number];
  102. usermsg.val(message);
  103. usermsg.get(0).setSelectionRange(message.length, message.length);
  104. toggleSmileys();
  105. usermsg.focus();
  106. };
  107. }
  108. /**
  109. * Adds the smileys container to the chat
  110. */
  111. function addSmileys() {
  112. var smileysContainer = document.createElement('div');
  113. smileysContainer.id = 'smileysContainer';
  114. for(var i = 1; i <= 21; i++) {
  115. var smileyContainer = document.createElement('div');
  116. smileyContainer.id = 'smiley' + i;
  117. smileyContainer.className = 'smileyContainer';
  118. var smiley = document.createElement('img');
  119. smiley.src = 'images/smileys/smiley' + i + '.svg';
  120. smiley.className = 'smiley';
  121. addClickFunction(smiley, i);
  122. smileyContainer.appendChild(smiley);
  123. smileysContainer.appendChild(smileyContainer);
  124. }
  125. $("#chatspace").append(smileysContainer);
  126. }
  127. /**
  128. * Resizes the chat conversation.
  129. */
  130. function resizeChatConversation() {
  131. var msgareaHeight = $('#usermsg').outerHeight();
  132. var chatspace = $('#chatspace');
  133. var width = chatspace.width();
  134. var chat = $('#chatconversation');
  135. var smileys = $('#smileysarea');
  136. smileys.height(msgareaHeight);
  137. $("#smileys").css('bottom', (msgareaHeight - 26) / 2);
  138. $('#smileysContainer').css('bottom', msgareaHeight);
  139. chat.width(width - 10);
  140. chat.height(window.innerHeight - 15 - msgareaHeight);
  141. }
  142. /**
  143. * Chat related user interface.
  144. */
  145. var Chat = {
  146. /**
  147. * Initializes chat related interface.
  148. */
  149. init (eventEmitter) {
  150. if (APP.settings.getDisplayName()) {
  151. Chat.setChatConversationMode(true);
  152. }
  153. $('#nickinput').keydown(function (event) {
  154. if (event.keyCode === 13) {
  155. event.preventDefault();
  156. let val = this.value;
  157. this.value = '';
  158. eventEmitter.emit(UIEvents.NICKNAME_CHANGED, val);
  159. }
  160. });
  161. var usermsg = $('#usermsg');
  162. usermsg.keydown(function (event) {
  163. if (event.keyCode === 13) {
  164. event.preventDefault();
  165. var value = this.value;
  166. usermsg.val('').trigger('autosize.resize');
  167. this.focus();
  168. var command = new CommandsProcessor(value, eventEmitter);
  169. if (command.isCommand()) {
  170. command.processCommand();
  171. } else {
  172. var message = UIUtil.escapeHtml(value);
  173. eventEmitter.emit(UIEvents.MESSAGE_CREATED, message);
  174. }
  175. }
  176. });
  177. var onTextAreaResize = function () {
  178. resizeChatConversation();
  179. Chat.scrollChatToBottom();
  180. };
  181. usermsg.autosize({callback: onTextAreaResize});
  182. $("#chatspace").bind("shown",
  183. function () {
  184. unreadMessages = 0;
  185. setVisualNotification(false);
  186. });
  187. addSmileys();
  188. },
  189. /**
  190. * Appends the given message to the chat conversation.
  191. */
  192. updateChatConversation (id, displayName, message, stamp) {
  193. var divClassName = '';
  194. if (APP.conference.isLocalId(id)) {
  195. divClassName = "localuser";
  196. } else {
  197. divClassName = "remoteuser";
  198. if (!Chat.isVisible()) {
  199. unreadMessages++;
  200. UIUtil.playSoundNotification('chatNotification');
  201. setVisualNotification(true);
  202. }
  203. }
  204. // replace links and smileys
  205. // Strophe already escapes special symbols on sending,
  206. // so we escape here only tags to avoid double &amp;
  207. var escMessage = message.replace(/</g, '&lt;').
  208. replace(/>/g, '&gt;').replace(/\n/g, '<br/>');
  209. var escDisplayName = UIUtil.escapeHtml(displayName);
  210. message = processReplacements(escMessage);
  211. var messageContainer =
  212. '<div class="chatmessage">'+
  213. '<img src="../images/chatArrow.svg" class="chatArrow">' +
  214. '<div class="username ' + divClassName +'">' + escDisplayName +
  215. '</div>' + '<div class="timestamp">' + getCurrentTime(stamp) +
  216. '</div>' + '<div class="usermessage">' + message + '</div>' +
  217. '</div>';
  218. $('#chatconversation').append(messageContainer);
  219. $('#chatconversation').animate(
  220. { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
  221. },
  222. /**
  223. * Appends error message to the conversation
  224. * @param errorMessage the received error message.
  225. * @param originalText the original message.
  226. */
  227. chatAddError (errorMessage, originalText) {
  228. errorMessage = UIUtil.escapeHtml(errorMessage);
  229. originalText = UIUtil.escapeHtml(originalText);
  230. $('#chatconversation').append(
  231. '<div class="errorMessage"><b>Error: </b>' + 'Your message' +
  232. (originalText? (' \"'+ originalText + '\"') : "") +
  233. ' was not sent.' +
  234. (errorMessage? (' Reason: ' + errorMessage) : '') + '</div>');
  235. $('#chatconversation').animate(
  236. { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
  237. },
  238. /**
  239. * Sets the subject to the UI
  240. * @param subject the subject
  241. */
  242. setSubject (subject) {
  243. if (subject) {
  244. subject = subject.trim();
  245. }
  246. $('#subject').html(linkify(UIUtil.escapeHtml(subject)));
  247. if (subject) {
  248. $("#subject").css({display: "block"});
  249. } else {
  250. $("#subject").css({display: "none"});
  251. }
  252. },
  253. /**
  254. * Sets the chat conversation mode.
  255. */
  256. setChatConversationMode (isConversationMode) {
  257. if (isConversationMode) {
  258. $('#nickname').css({visibility: 'hidden'});
  259. $('#chatconversation').css({visibility: 'visible'});
  260. $('#usermsg').css({visibility: 'visible'});
  261. $('#smileysarea').css({visibility: 'visible'});
  262. $('#usermsg').focus();
  263. }
  264. },
  265. /**
  266. * Resizes the chat area.
  267. */
  268. resizeChat (width, height) {
  269. $('#chatspace').width(width).height(height);
  270. resizeChatConversation();
  271. },
  272. /**
  273. * Indicates if the chat is currently visible.
  274. */
  275. isVisible () {
  276. return $('#chatspace').is(":visible");
  277. },
  278. /**
  279. * Shows and hides the window with the smileys
  280. */
  281. toggleSmileys,
  282. /**
  283. * Scrolls chat to the bottom.
  284. */
  285. scrollChatToBottom () {
  286. setTimeout(function () {
  287. $('#chatconversation').scrollTop(
  288. $('#chatconversation')[0].scrollHeight);
  289. }, 5);
  290. }
  291. };
  292. export default Chat;