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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /* global $, Util, connection, nickname:true, getVideoSize, getVideoPosition, showToolbar, processReplacements */
  2. /**
  3. * Chat related user interface.
  4. */
  5. var Chat = (function (my) {
  6. var notificationInterval = false;
  7. var unreadMessages = 0;
  8. /**
  9. * Initializes chat related interface.
  10. */
  11. my.init = function () {
  12. var storedDisplayName = window.localStorage.displayname;
  13. if (storedDisplayName) {
  14. nickname = storedDisplayName;
  15. Chat.setChatConversationMode(true);
  16. }
  17. $('#nickinput').keydown(function (event) {
  18. if (event.keyCode === 13) {
  19. event.preventDefault();
  20. var val = Util.escapeHtml(this.value);
  21. this.value = '';
  22. if (!nickname) {
  23. nickname = val;
  24. window.localStorage.displayname = nickname;
  25. connection.emuc.addDisplayNameToPresence(nickname);
  26. connection.emuc.sendPresence();
  27. Chat.setChatConversationMode(true);
  28. return;
  29. }
  30. }
  31. });
  32. $('#usermsg').keydown(function (event) {
  33. if (event.keyCode === 13) {
  34. event.preventDefault();
  35. var value = this.value;
  36. $('#usermsg').val('').trigger('autosize.resize');
  37. this.focus();
  38. var command = new CommandsProcessor(value);
  39. if(command.isCommand())
  40. {
  41. command.processCommand();
  42. }
  43. else
  44. {
  45. var message = Util.escapeHtml(value);
  46. connection.emuc.sendMessage(message, nickname);
  47. }
  48. }
  49. });
  50. var onTextAreaResize = function () {
  51. resizeChatConversation();
  52. scrollChatToBottom();
  53. };
  54. $('#usermsg').autosize({callback: onTextAreaResize});
  55. $("#chatspace").bind("shown",
  56. function () {
  57. unreadMessages = 0;
  58. setVisualNotification(false);
  59. });
  60. };
  61. /**
  62. * Appends the given message to the chat conversation.
  63. */
  64. my.updateChatConversation = function (from, displayName, message) {
  65. var divClassName = '';
  66. if (connection.emuc.myroomjid === from) {
  67. divClassName = "localuser";
  68. }
  69. else {
  70. divClassName = "remoteuser";
  71. if (!$('#chatspace').is(":visible")) {
  72. unreadMessages++;
  73. Util.playSoundNotification('chatNotification');
  74. setVisualNotification(true);
  75. }
  76. }
  77. //replace links and smileys
  78. var escMessage = Util.escapeHtml(message);
  79. var escDisplayName = Util.escapeHtml(displayName);
  80. message = processReplacements(escMessage);
  81. $('#chatconversation').append('<div class="' + divClassName + '"><b>' +
  82. escDisplayName + ': </b>' +
  83. message + '</div>');
  84. $('#chatconversation').animate(
  85. { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
  86. };
  87. /**
  88. * Appends error message to the conversation
  89. * @param errorMessage the received error message.
  90. * @param originalText the original message.
  91. */
  92. my.chatAddError = function(errorMessage, originalText)
  93. {
  94. errorMessage = Util.escapeHtml(errorMessage);
  95. originalText = Util.escapeHtml(originalText);
  96. $('#chatconversation').append('<div class="errorMessage"><b>Error: </b>'
  97. + 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
  98. + ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
  99. + '</div>');
  100. $('#chatconversation').animate(
  101. { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
  102. }
  103. /**
  104. * Sets the subject to the UI
  105. * @param subject the subject
  106. */
  107. my.chatSetSubject = function(subject)
  108. {
  109. if(subject)
  110. subject = subject.trim();
  111. $('#subject').html(linkify(Util.escapeHtml(subject)));
  112. if(subject == "")
  113. {
  114. $("#subject").css({display: "none"});
  115. }
  116. else
  117. {
  118. $("#subject").css({display: "block"});
  119. }
  120. }
  121. /**
  122. * Opens / closes the chat area.
  123. */
  124. my.toggleChat = function () {
  125. var chatspace = $('#chatspace');
  126. var videospace = $('#videospace');
  127. var chatSize = (chatspace.is(":visible")) ? [0, 0] : Chat.getChatSize();
  128. var videospaceWidth = window.innerWidth - chatSize[0];
  129. var videospaceHeight = window.innerHeight;
  130. var videoSize
  131. = getVideoSize(null, null, videospaceWidth, videospaceHeight);
  132. var videoWidth = videoSize[0];
  133. var videoHeight = videoSize[1];
  134. var videoPosition = getVideoPosition(videoWidth,
  135. videoHeight,
  136. videospaceWidth,
  137. videospaceHeight);
  138. var horizontalIndent = videoPosition[0];
  139. var verticalIndent = videoPosition[1];
  140. if (chatspace.is(":visible")) {
  141. videospace.animate({right: chatSize[0],
  142. width: videospaceWidth,
  143. height: videospaceHeight},
  144. {queue: false,
  145. duration: 500});
  146. $('#largeVideoContainer').animate({ width: videospaceWidth,
  147. height: videospaceHeight},
  148. {queue: false,
  149. duration: 500
  150. });
  151. $('#largeVideo').animate({ width: videoWidth,
  152. height: videoHeight,
  153. top: verticalIndent,
  154. bottom: verticalIndent,
  155. left: horizontalIndent,
  156. right: horizontalIndent},
  157. { queue: false,
  158. duration: 500
  159. });
  160. $('#chatspace').hide("slide", { direction: "right",
  161. queue: false,
  162. duration: 500});
  163. }
  164. else {
  165. videospace.animate({right: chatSize[0],
  166. width: videospaceWidth,
  167. height: videospaceHeight},
  168. {queue: false,
  169. duration: 500,
  170. complete: function () {
  171. scrollChatToBottom();
  172. chatspace.trigger('shown');
  173. }
  174. });
  175. $('#largeVideoContainer').animate({ width: videospaceWidth,
  176. height: videospaceHeight},
  177. {queue: false,
  178. duration: 500
  179. });
  180. $('#largeVideo').animate({ width: videoWidth,
  181. height: videoHeight,
  182. top: verticalIndent,
  183. bottom: verticalIndent,
  184. left: horizontalIndent,
  185. right: horizontalIndent},
  186. {queue: false,
  187. duration: 500
  188. });
  189. $('#chatspace').show("slide", { direction: "right",
  190. queue: false,
  191. duration: 500});
  192. }
  193. // Request the focus in the nickname field or the chat input field.
  194. if ($('#nickname').css('visibility') === 'visible')
  195. $('#nickinput').focus();
  196. else {
  197. $('#usermsg').focus();
  198. }
  199. };
  200. /**
  201. * Sets the chat conversation mode.
  202. */
  203. my.setChatConversationMode = function (isConversationMode) {
  204. if (isConversationMode) {
  205. $('#nickname').css({visibility: 'hidden'});
  206. $('#chatconversation').css({visibility: 'visible'});
  207. $('#usermsg').css({visibility: 'visible'});
  208. $('#usermsg').focus();
  209. }
  210. };
  211. /**
  212. * Resizes the chat area.
  213. */
  214. my.resizeChat = function () {
  215. var chatSize = Chat.getChatSize();
  216. $('#chatspace').width(chatSize[0]);
  217. $('#chatspace').height(chatSize[1]);
  218. resizeChatConversation();
  219. };
  220. /**
  221. * Returns the size of the chat.
  222. */
  223. my.getChatSize = function () {
  224. var availableHeight = window.innerHeight;
  225. var availableWidth = window.innerWidth;
  226. var chatWidth = 200;
  227. if (availableWidth * 0.2 < 200)
  228. chatWidth = availableWidth * 0.2;
  229. return [chatWidth, availableHeight];
  230. };
  231. /**
  232. * Resizes the chat conversation.
  233. */
  234. function resizeChatConversation() {
  235. var usermsgStyleHeight = document.getElementById("usermsg").style.height;
  236. var usermsgHeight = usermsgStyleHeight
  237. .substring(0, usermsgStyleHeight.indexOf('px'));
  238. $('#usermsg').width($('#chatspace').width() - 10);
  239. $('#chatconversation').width($('#chatspace').width() - 10);
  240. $('#chatconversation')
  241. .height(window.innerHeight - 10 - parseInt(usermsgHeight));
  242. }
  243. /**
  244. * Shows/hides a visual notification, indicating that a message has arrived.
  245. */
  246. function setVisualNotification(show) {
  247. var unreadMsgElement = document.getElementById('unreadMessages');
  248. var glower = $('#chatButton');
  249. if (unreadMessages) {
  250. unreadMsgElement.innerHTML = unreadMessages.toString();
  251. Toolbar.showToolbar();
  252. var chatButtonElement
  253. = document.getElementById('chatButton').parentNode;
  254. var leftIndent = (Util.getTextWidth(chatButtonElement) -
  255. Util.getTextWidth(unreadMsgElement)) / 2;
  256. var topIndent = (Util.getTextHeight(chatButtonElement) -
  257. Util.getTextHeight(unreadMsgElement)) / 2 - 3;
  258. unreadMsgElement.setAttribute(
  259. 'style',
  260. 'top:' + topIndent +
  261. '; left:' + leftIndent + ';');
  262. if (!glower.hasClass('icon-chat-simple')) {
  263. glower.removeClass('icon-chat');
  264. glower.addClass('icon-chat-simple');
  265. }
  266. }
  267. else {
  268. unreadMsgElement.innerHTML = '';
  269. glower.removeClass('icon-chat-simple');
  270. glower.addClass('icon-chat');
  271. }
  272. if (show && !notificationInterval) {
  273. notificationInterval = window.setInterval(function () {
  274. glower.toggleClass('active');
  275. }, 800);
  276. }
  277. else if (!show && notificationInterval) {
  278. window.clearInterval(notificationInterval);
  279. notificationInterval = false;
  280. glower.removeClass('active');
  281. }
  282. }
  283. /**
  284. * Scrolls chat to the bottom.
  285. */
  286. function scrollChatToBottom() {
  287. setTimeout(function () {
  288. $('#chatconversation').scrollTop(
  289. $('#chatconversation')[0].scrollHeight);
  290. }, 5);
  291. }
  292. return my;
  293. }(Chat || {}));