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 11KB

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