選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

chat.js 12KB

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