PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/mod/chat/gui_ajax/module.js

https://github.com/arborrow/moodle
JavaScript | 259 lines | 209 code | 25 blank | 25 comment | 24 complexity | 41569c2a13ac750f96c26e877ee35617 MD5 | raw file
  1. /*
  2. * NOTE: the /mod/chat/gui_header_js/ is not a real plugin,
  3. * ideally this code should be in /mod/chat/module.js
  4. */
  5. /**
  6. * @namespace M.mod_chat_ajax
  7. */
  8. M.mod_chat_ajax = M.mod_chat_ajax || {};
  9. /**
  10. * Init ajax based Chat UI.
  11. * @namespace M.mod_chat_ajax
  12. * @function
  13. * @param {YUI} Y
  14. * @param {Object} cfg configuration data
  15. */
  16. M.mod_chat_ajax.init = function(Y, cfg) {
  17. var gui_ajax = {
  18. // Properties.
  19. api : M.cfg.wwwroot + '/mod/chat/chat_ajax.php?sesskey=' + M.cfg.sesskey, // The path to the ajax callback script.
  20. cfg : {}, // A configuration variable.
  21. interval : null, // The interval object for refreshes.
  22. layout : null, // A reference to the layout used in this module.
  23. messages : [], // An array of messages.
  24. scrollable : true, // True is scrolling should occur.
  25. thememenu : null, // A reference to the menu for changing themes.
  26. // Elements
  27. messageinput : null,
  28. sendbutton : null,
  29. messagebox : null,
  30. init : function(cfg) {
  31. this.cfg = cfg;
  32. this.cfg.req_count = this.cfg.req_count || 0;
  33. participantswidth = 180;
  34. if (Y.one('#input-message').get('docWidth') < 640) {
  35. participantswidth = 120;
  36. }
  37. this.layout = new Y.YUI2.widget.Layout({
  38. units : [
  39. {position: 'right', width: participantswidth, resize: true, gutter: '1px', scroll: true, body: 'chat-userlist', animate: false},
  40. {position: 'bottom', height: 42, resize: false, body: 'chat-input-area', gutter: '1px', collapse: false, resize: false},
  41. {position: 'center', body: 'chat-messages', gutter: '0px', scroll: true}
  42. ]
  43. });
  44. this.layout.on('render', function() {
  45. var unit = this.getUnitByPosition('right');
  46. if (unit) {
  47. unit.on('close', function() {
  48. closeLeft();
  49. });
  50. }
  51. }, this.layout);
  52. this.layout.render();
  53. // Gather the general elements.
  54. this.messageinput = Y.one('#input-message');
  55. this.sendbutton = Y.one('#button-send');
  56. this.messagebox = Y.one('#chat-messages');
  57. // Set aria attributes to messagebox and chat-userlist.
  58. this.messagebox.set('role', 'log');
  59. this.messagebox.set('aria-live', 'polite');
  60. var userlist = Y.one('#chat-userlist');
  61. userlist.set('aria-live', 'polite');
  62. userlist.set('aria-relevant', 'all');
  63. // Attach the default events for this module.
  64. this.sendbutton.on('click', this.send, this);
  65. this.messagebox.on('mouseenter', function() {
  66. this.scrollable = false;
  67. }, this);
  68. this.messagebox.on('mouseleave', function() {
  69. this.scrollable = true;
  70. }, this);
  71. // Send the message when the enter key is pressed.
  72. Y.on('key', this.send, this.messageinput, 'press:13', this);
  73. document.title = this.cfg.chatroom_name;
  74. // Prepare and execute the first AJAX request of information.
  75. Y.io(this.api,{
  76. method : 'POST',
  77. data : build_querystring({
  78. action : 'init',
  79. chat_init : 1,
  80. chat_sid : this.cfg.sid,
  81. theme : this.theme
  82. }),
  83. on : {
  84. success : function(tid, outcome) {
  85. this.messageinput.removeAttribute('disabled');
  86. this.messageinput.set('value', '');
  87. this.messageinput.focus();
  88. try {
  89. var data = Y.JSON.parse(outcome.responseText);
  90. } catch (ex) {
  91. return;
  92. }
  93. this.update_users(data.users);
  94. }
  95. },
  96. context : this
  97. });
  98. var scope = this;
  99. this.interval = setInterval(function() {
  100. scope.update_messages();
  101. }, this.cfg.timer, this);
  102. // Create and initalise theme changing menu.
  103. this.thememenu = new Y.YUI2.widget.Menu('basicmenu', {xy:[0,0]});
  104. this.thememenu.addItems([
  105. {text: M.util.get_string('bubble', 'mod_chat'), url: this.cfg.chaturl + '&theme=bubble'},
  106. {text: M.util.get_string('compact', 'mod_chat'), url: this.cfg.chaturl + '&theme=compact'}
  107. ]);
  108. if (this.cfg.showcoursetheme == 1) {
  109. this.thememenu.addItem({text: M.util.get_string('coursetheme', 'mod_chat'), url: this.cfg.chaturl + '&theme=course_theme'});
  110. }
  111. this.thememenu.render(document.body);
  112. Y.one('#choosetheme').on('click', function(e) {
  113. this.moveTo((e.pageX - 20), (e.pageY - 20));
  114. this.show();
  115. }, this.thememenu);
  116. },
  117. append_message : function(key, message, row) {
  118. var item = Y.Node.create('<li id="mdl-chat-entry-' + key + '">' + message.message + '</li>');
  119. item.addClass((message.mymessage) ? 'mdl-chat-my-entry' : 'mdl-chat-entry');
  120. Y.one('#messages-list').append(item);
  121. if (message.type && message.type == 'beep') {
  122. Y.one('#chat-notify').setContent('<embed src="../beep.wav" autostart="true" hidden="true" name="beep" />');
  123. }
  124. },
  125. send : function(e, beep) {
  126. if((this.messageinput.get('value') != '') || (typeof beep != 'undefined')) {
  127. this.sendbutton.set('value', M.str.chat.sending);
  128. var data = {
  129. chat_message : (!beep) ? this.messageinput.get('value') : '',
  130. chat_sid : this.cfg.sid,
  131. theme : this.cfg.theme
  132. };
  133. if (beep) {
  134. data.beep = beep
  135. }
  136. data.action = 'chat';
  137. Y.io(this.api, {
  138. method : 'POST',
  139. data : build_querystring(data),
  140. on : {
  141. success : this.send_callback
  142. },
  143. context : this
  144. });
  145. }
  146. },
  147. send_callback : function(tid, outcome, args) {
  148. try {
  149. var data = Y.JSON.parse(outcome.responseText);
  150. } catch (ex) {
  151. return;
  152. }
  153. this.sendbutton.set('value', M.str.chat.send);
  154. this.messageinput.set('value', '');
  155. clearInterval(this.interval);
  156. this.update_messages();
  157. var scope = this;
  158. this.interval = setInterval(function() {
  159. scope.update_messages();
  160. }, this.cfg.timer, this);
  161. },
  162. talkto: function (e, name) {
  163. this.messageinput.set('value', "To " + name + ": ");
  164. this.messageinput.focus();
  165. },
  166. update_messages : function() {
  167. this.cfg.req_count++;
  168. Y.io(this.api, {
  169. method : 'POST',
  170. data : build_querystring({
  171. action: 'update',
  172. chat_lastrow : this.cfg.chat_lastrow || false,
  173. chat_lasttime : this.cfg.chat_lasttime,
  174. chat_sid : this.cfg.sid,
  175. theme : this.cfg.theme
  176. }),
  177. on : {
  178. success : this.update_messages_callback
  179. },
  180. context : this
  181. });
  182. },
  183. update_messages_callback : function(tid, outcome) {
  184. try {
  185. var data = Y.JSON.parse(outcome.responseText);
  186. } catch (ex) {
  187. return;
  188. }
  189. if (data.error) {
  190. clearInterval(this.interval);
  191. alert(data.error);
  192. window.location = this.cfg.home;
  193. }
  194. this.cfg.chat_lasttime = data.lasttime;
  195. this.cfg.chat_lastrow = data.lastrow;
  196. // Update messages.
  197. for (var key in data.msgs){
  198. if (!M.util.in_array(key, this.messages)) {
  199. this.messages.push(key);
  200. this.append_message(key, data.msgs[key], data.lastrow);
  201. }
  202. }
  203. // Update users.
  204. this.update_users(data.users);
  205. // Scroll to the bottom of the message list
  206. if (this.scrollable) {
  207. Y.Node.getDOMNode(this.messagebox).parentNode.scrollTop += 500;
  208. }
  209. this.messageinput.focus();
  210. },
  211. update_users : function(users) {
  212. if (!users) {
  213. return;
  214. }
  215. var list = Y.one('#users-list');
  216. list.get('children').remove();
  217. for (var i in users) {
  218. var li = Y.Node.create('<li><table><tr><td>' + users[i].picture + '</td><td></td></tr></table></li>');
  219. if (users[i].id == this.cfg.userid) {
  220. li.all('td').item(1).append(Y.Node.create('<strong><a target="_blank" href="' + users[i].url + '">' + users[i].name + '</a></strong>'));
  221. } else {
  222. li.all('td').item(1).append(Y.Node.create('<div><a target="_blank" href="' + users[i].url + '">' + users[i].name + '</a></div>'));
  223. var talk = Y.Node.create('<a href="###">' + M.str.chat.talk + '</a>');
  224. talk.on('click', this.talkto, this, users[i].name);
  225. var beep = Y.Node.create('<a href="###">' + M.str.chat.beep + '</a>');
  226. beep.on('click', this.send, this, users[i].id);
  227. li.all('td').item(1).append(Y.Node.create('<div></div>').append(talk).append('&nbsp;').append(beep));
  228. }
  229. list.append(li);
  230. }
  231. }
  232. };
  233. gui_ajax.init(cfg);
  234. };