PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/chat/gui_ajax/module.js

https://github.com/telematika/moodle
JavaScript | 274 lines | 204 code | 27 blank | 43 comment | 18 complexity | 7e84fb5bbbb2ef387bb197c08e433efc 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. /*
  104. this.thememenu = new Y.Overlay({
  105. bodyContent : '<div class="menuitem"><a href="'+this.cfg.chaturl+'&theme=bubble">Bubble</a></div><div class="menuitem"><a href="'+this.cfg.chaturl+'&theme=compact">Compact</a></div>',
  106. visible : false,
  107. zIndex : 2,
  108. align : {
  109. node : '#choosetheme',
  110. points : [Y.WidgetPositionExt.BL, Y.WidgetPositionExt.BR]
  111. }
  112. });
  113. this.thememenu.render(document.body);
  114. Y.one('#choosetheme').on('click', function(e){
  115. this.show();
  116. this.get('boundingBox').setStyle('visibility', 'visible');
  117. }, this.thememenu);
  118. return;
  119. */
  120. this.thememenu = new Y.YUI2.widget.Menu('basicmenu', {xy:[0,0]});
  121. this.thememenu.addItems([
  122. {text: "Bubble", url: this.cfg.chaturl+'&theme=bubble'},
  123. {text: "Compact", url: this.cfg.chaturl+'&theme=compact'}
  124. ]);
  125. this.thememenu.render(document.body);
  126. Y.one('#choosetheme').on('click', function(e){
  127. this.moveTo((e.pageX-20), (e.pageY-20));
  128. this.show();
  129. }, this.thememenu);
  130. },
  131. append_message : function(key, message, row) {
  132. var item = Y.Node.create('<li id="mdl-chat-entry-'+key+'">'+message.message+'</li>');
  133. item.addClass((message.mymessage)?'mdl-chat-my-entry':'mdl-chat-entry');
  134. Y.one('#messages-list').append(item);
  135. if (message.type && message.type == 'beep') {
  136. Y.one('#chat-notify').setContent('<embed src="../beep.wav" autostart="true" hidden="true" name="beep" />');
  137. }
  138. },
  139. send : function(e, beep) {
  140. this.sendbutton.set('value', M.str.chat.sending);
  141. var data = {
  142. chat_message : (!beep)?this.messageinput.get('value'):'',
  143. chat_sid : this.cfg.sid,
  144. theme : this.cfg.theme
  145. };
  146. if (beep) {
  147. data.beep = beep
  148. }
  149. data.action = 'chat';
  150. Y.io(this.api, {
  151. method : 'POST',
  152. data : build_querystring(data),
  153. on : {
  154. success : this.send_callback
  155. },
  156. context : this
  157. });
  158. },
  159. send_callback : function(tid, outcome, args) {
  160. try {
  161. var data = Y.JSON.parse(outcome.responseText);
  162. } catch (ex) {
  163. return;
  164. }
  165. this.sendbutton.set('value', M.str.chat.send);
  166. this.messageinput.set('value', '');
  167. clearInterval(this.interval);
  168. this.update_messages();
  169. var scope = this;
  170. this.interval = setInterval(function() {
  171. scope.update_messages();
  172. }, this.cfg.timer, this);
  173. },
  174. talkto: function (e, name) {
  175. this.messageinput.set('value', "To "+name+": ");
  176. this.messageinput.focus();
  177. },
  178. update_messages : function() {
  179. this.cfg.req_count++;
  180. Y.io(this.api, {
  181. method : 'POST',
  182. data : build_querystring({
  183. action: 'update',
  184. chat_lastrow : this.cfg.chat_lastrow || false,
  185. chat_lasttime : this.cfg.chat_lasttime,
  186. chat_sid : this.cfg.sid,
  187. theme : this.cfg.theme
  188. }),
  189. on : {
  190. success : this.update_messages_callback
  191. },
  192. context : this
  193. });
  194. },
  195. update_messages_callback : function(tid, outcome) {
  196. try {
  197. var data = Y.JSON.parse(outcome.responseText);
  198. } catch (ex) {
  199. return;
  200. }
  201. if (data.error) {
  202. clearInterval(this.interval);
  203. alert(data.error);
  204. window.location = this.cfg.home;
  205. }
  206. this.cfg.chat_lasttime = data.lasttime;
  207. this.cfg.chat_lastrow = data.lastrow;
  208. // Update messages
  209. for (var key in data.msgs){
  210. if (!M.util.in_array(key, this.messages)) {
  211. this.messages.push(key);
  212. this.append_message(key, data.msgs[key], data.lastrow);
  213. }
  214. }
  215. // Update users
  216. this.update_users(data.users);
  217. // Scroll to the bottom of the message list
  218. if (this.scrollable) {
  219. Y.Node.getDOMNode(this.messagebox).parentNode.scrollTop+=500;
  220. }
  221. this.messageinput.focus();
  222. },
  223. update_users : function(users) {
  224. if (!users) {
  225. return;
  226. }
  227. var list = Y.one('#users-list');
  228. list.get('children').remove();
  229. for (var i in users) {
  230. var li = Y.Node.create('<li><table><tr><td>'+users[i].picture+'</td><td></td></tr></table></li>');
  231. if (users[i].id == this.cfg.userid) {
  232. li.all('td').item(1).append(Y.Node.create('<strong><a target="_blank" href="'+users[i].url+'">'+ users[i].name+'</a></strong>'));
  233. } else {
  234. li.all('td').item(1).append(Y.Node.create('<div><a target="_blank" href="'+users[i].url+'">'+users[i].name+'</a></div>'));
  235. var talk = Y.Node.create('<a href="###">'+M.str.chat.talk+'</a>');
  236. talk.on('click', this.talkto, this, users[i].name);
  237. var beep = Y.Node.create('<a href="###">'+M.str.chat.beep+'</a>');
  238. beep.on('click', this.send, this, users[i].id);
  239. li.all('td').item(1).append(Y.Node.create('<div></div>').append(talk).append('&nbsp;').append(beep));
  240. }
  241. list.append(li);
  242. }
  243. }
  244. };
  245. gui_ajax.init(cfg);
  246. };