您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

chat.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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. var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth);
  141. var thumbnailsWidth = thumbnailSize[0];
  142. var thumbnailsHeight = thumbnailSize[1];
  143. if (chatspace.is(":visible")) {
  144. videospace.animate({right: chatSize[0],
  145. width: videospaceWidth,
  146. height: videospaceHeight},
  147. {queue: false,
  148. duration: 500});
  149. $('#remoteVideos').animate({height: thumbnailsHeight},
  150. {queue: false,
  151. duration: 500});
  152. $('#remoteVideos>span').animate({height: thumbnailsHeight,
  153. width: thumbnailsWidth},
  154. {queue: false,
  155. duration: 500,
  156. complete: function() {
  157. $(document).trigger(
  158. "remotevideo.resized",
  159. [thumbnailsWidth,
  160. thumbnailsHeight]);
  161. }});
  162. $('#largeVideoContainer').animate({ width: videospaceWidth,
  163. height: videospaceHeight},
  164. {queue: false,
  165. duration: 500
  166. });
  167. $('#largeVideo').animate({ width: videoWidth,
  168. height: videoHeight,
  169. top: verticalIndent,
  170. bottom: verticalIndent,
  171. left: horizontalIndent,
  172. right: horizontalIndent},
  173. { queue: false,
  174. duration: 500
  175. });
  176. $('#chatspace').hide("slide", { direction: "right",
  177. queue: false,
  178. duration: 500});
  179. }
  180. else {
  181. // Undock the toolbar when the chat is shown.
  182. Toolbar.dockToolbar(false);
  183. videospace.animate({right: chatSize[0],
  184. width: videospaceWidth,
  185. height: videospaceHeight},
  186. {queue: false,
  187. duration: 500,
  188. complete: function () {
  189. scrollChatToBottom();
  190. chatspace.trigger('shown');
  191. }
  192. });
  193. $('#remoteVideos').animate({height: thumbnailsHeight},
  194. {queue: false,
  195. duration: 500});
  196. $('#remoteVideos>span').animate({height: thumbnailsHeight,
  197. width: thumbnailsWidth},
  198. {queue: false,
  199. duration: 500,
  200. complete: function() {
  201. $(document).trigger(
  202. "remotevideo.resized",
  203. [thumbnailsWidth, thumbnailsHeight]);
  204. }});
  205. $('#largeVideoContainer').animate({ width: videospaceWidth,
  206. height: videospaceHeight},
  207. {queue: false,
  208. duration: 500
  209. });
  210. $('#largeVideo').animate({ width: videoWidth,
  211. height: videoHeight,
  212. top: verticalIndent,
  213. bottom: verticalIndent,
  214. left: horizontalIndent,
  215. right: horizontalIndent},
  216. {queue: false,
  217. duration: 500
  218. });
  219. $('#chatspace').show("slide", { direction: "right",
  220. queue: false,
  221. duration: 500});
  222. }
  223. // Request the focus in the nickname field or the chat input field.
  224. if ($('#nickname').css('visibility') === 'visible')
  225. $('#nickinput').focus();
  226. else {
  227. $('#usermsg').focus();
  228. }
  229. };
  230. /**
  231. * Sets the chat conversation mode.
  232. */
  233. my.setChatConversationMode = function (isConversationMode) {
  234. if (isConversationMode) {
  235. $('#nickname').css({visibility: 'hidden'});
  236. $('#chatconversation').css({visibility: 'visible'});
  237. $('#usermsg').css({visibility: 'visible'});
  238. $('#usermsg').focus();
  239. }
  240. };
  241. /**
  242. * Resizes the chat area.
  243. */
  244. my.resizeChat = function () {
  245. var chatSize = Chat.getChatSize();
  246. $('#chatspace').width(chatSize[0]);
  247. $('#chatspace').height(chatSize[1]);
  248. resizeChatConversation();
  249. };
  250. /**
  251. * Returns the size of the chat.
  252. */
  253. my.getChatSize = function () {
  254. var availableHeight = window.innerHeight;
  255. var availableWidth = window.innerWidth;
  256. var chatWidth = 200;
  257. if (availableWidth * 0.2 < 200)
  258. chatWidth = availableWidth * 0.2;
  259. return [chatWidth, availableHeight];
  260. };
  261. /**
  262. * Resizes the chat conversation.
  263. */
  264. function resizeChatConversation() {
  265. var usermsgStyleHeight = document.getElementById("usermsg").style.height;
  266. var usermsgHeight = usermsgStyleHeight
  267. .substring(0, usermsgStyleHeight.indexOf('px'));
  268. $('#usermsg').width($('#chatspace').width() - 10);
  269. $('#chatconversation').width($('#chatspace').width() - 10);
  270. $('#chatconversation')
  271. .height(window.innerHeight - 10 - parseInt(usermsgHeight));
  272. }
  273. /**
  274. * Shows/hides a visual notification, indicating that a message has arrived.
  275. */
  276. function setVisualNotification(show) {
  277. var unreadMsgElement = document.getElementById('unreadMessages');
  278. var glower = $('#chatButton');
  279. if (unreadMessages) {
  280. unreadMsgElement.innerHTML = unreadMessages.toString();
  281. Toolbar.dockToolbar(true);
  282. var chatButtonElement
  283. = document.getElementById('chatButton').parentNode;
  284. var leftIndent = (Util.getTextWidth(chatButtonElement) -
  285. Util.getTextWidth(unreadMsgElement)) / 2;
  286. var topIndent = (Util.getTextHeight(chatButtonElement) -
  287. Util.getTextHeight(unreadMsgElement)) / 2 - 3;
  288. unreadMsgElement.setAttribute(
  289. 'style',
  290. 'top:' + topIndent +
  291. '; left:' + leftIndent + ';');
  292. if (!glower.hasClass('icon-chat-simple')) {
  293. glower.removeClass('icon-chat');
  294. glower.addClass('icon-chat-simple');
  295. }
  296. }
  297. else {
  298. unreadMsgElement.innerHTML = '';
  299. glower.removeClass('icon-chat-simple');
  300. glower.addClass('icon-chat');
  301. }
  302. if (show && !notificationInterval) {
  303. notificationInterval = window.setInterval(function () {
  304. glower.toggleClass('active');
  305. }, 800);
  306. }
  307. else if (!show && notificationInterval) {
  308. window.clearInterval(notificationInterval);
  309. notificationInterval = false;
  310. glower.removeClass('active');
  311. }
  312. }
  313. /**
  314. * Scrolls chat to the bottom.
  315. */
  316. function scrollChatToBottom() {
  317. setTimeout(function () {
  318. $('#chatconversation').scrollTop(
  319. $('#chatconversation')[0].scrollHeight);
  320. }, 5);
  321. }
  322. return my;
  323. }(Chat || {}));