spacedeck_websockets.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. SpacedeckWebsockets = {
  2. data: {
  3. users_online: {}
  4. },
  5. methods: {
  6. handle_live_updates: function(msg) {
  7. if (msg.model == "Space" && msg.object) {
  8. if (msg.object.space_type == "space") {
  9. if (this.active_space) {
  10. if (this.active_space._id == msg.object._id) {
  11. this.active_space = _.merge(this.active_space, msg.object);
  12. }
  13. }
  14. }
  15. }
  16. if (msg.model == "Message") {
  17. if (msg.action == "create" && msg.object) {
  18. var new_message = msg.object;
  19. if(this.active_space && this.active_space._id == new_message.space._id) {
  20. this.active_space_messages.push(new_message);
  21. this.refresh_space_comments();
  22. } else console.log("message created in another space.");
  23. }
  24. }
  25. if (msg.model == "Artifact") {
  26. if (msg.action == "create" && msg.object) {
  27. var new_artifact = msg.object;
  28. if (this.active_space && this.active_space._id == new_artifact.space_id) {
  29. var o = new_artifact;
  30. if (o._id && !this.find_artifact_by_id(o._id)) {
  31. this.update_board_artifact_viewmodel(new_artifact);
  32. this.active_space_artifacts.push(new_artifact)
  33. } else {
  34. console.log("warning: got create on existing artifact.");
  35. msg.action = "update"; // hackety hack!
  36. }
  37. } else console.log("artifact created in another space.");
  38. }
  39. else if (msg.action == "update" && msg.object) {
  40. if (this.active_space) {
  41. var o = msg.object;
  42. if (o && o._id) {
  43. var existing_artifact = this.find_artifact_by_id(o._id);
  44. if (!existing_artifact) {
  45. existing_artifact = o;
  46. } else {
  47. for (key in o) {
  48. existing_artifact[key] = o[key];
  49. this.update_board_artifact_viewmodel(existing_artifact);
  50. }
  51. }
  52. }
  53. }
  54. }
  55. else if (msg.action == "delete" && msg.object) {
  56. if (this.active_space) {
  57. var o = msg.object;
  58. if (o._id){
  59. var existing_artifact = this.find_artifact_by_id(o._id);
  60. if (existing_artifact) {
  61. var idx = this.active_space_artifacts.indexOf(existing_artifact);
  62. this.active_space_artifacts.splice(idx, 1);
  63. } else console.log("existing artifact to delete not found");
  64. } else console.error("object without _id");
  65. }
  66. }
  67. }
  68. },
  69. subscribe: function(space) {
  70. if (this.websocket && this.websocket.readyState==1) {
  71. this.websocket.send(JSON.stringify({action: "subscribe", space_id: space._id}));
  72. } else {
  73. console.error("socket not ready yet. (subscribe)");
  74. }
  75. },
  76. is_member_online: function(space, member) {
  77. if (!member.user) {
  78. return false;
  79. }
  80. if (!this.users_online[space._id]) {
  81. return false;
  82. }
  83. var isOnline = _.find(this.users_online[space._id], function(u) {
  84. return (u._id == member.user._id);
  85. });
  86. return isOnline;
  87. },
  88. auth_websocket: function(space){
  89. if (!this.websocket) {
  90. this.init_websocket();
  91. }
  92. if (this.websocket && this.websocket.readyState==1) {
  93. var token = "";
  94. if (this.user) token = this.user.token;
  95. var auth_params = {
  96. action: "auth",
  97. editor_auth: space_auth,
  98. editor_name: this.guest_nickname,
  99. auth_token: token,
  100. space_id: space._id
  101. };
  102. console.log("[websocket] auth space");
  103. this.websocket.send(JSON.stringify(auth_params));
  104. }
  105. },
  106. websocket_send: function(msg) {
  107. if (!this.websocket) return;
  108. if (this.websocket.readyState!=1) return;
  109. try {
  110. this.websocket.send(JSON.stringify(msg));
  111. } catch (e) {
  112. // catch NS problems
  113. }
  114. },
  115. init_websocket: function() {
  116. if (this.websocket) this.websocket = null;
  117. if (this.current_timeout) {
  118. clearTimeout(this.current_timeout);
  119. this.current_timeout = null;
  120. }
  121. try {
  122. this.websocket = new WebSocket(ENV.websocketsEndpoint + "/socket");
  123. } catch (e) {
  124. console.log("[websocket] cannot establish websocket connection: ",e);
  125. this.current_timeout = setTimeout(function() {
  126. console.log("[websocket] reconnecting", e);
  127. this.init_websocket();
  128. }.bind(this),5000);
  129. }
  130. if (!this.websocket) {
  131. console.log("[websocket] no websocket support?");
  132. return;
  133. }
  134. this.websocket.onopen = function(evt) {
  135. if (this.current_timeout) {
  136. clearTimeout(this.current_timeout);
  137. this.current_timeout = null;
  138. }
  139. if (this.active_space_loaded) {
  140. this.auth_websocket(this.active_space);
  141. }
  142. this.online = true;
  143. }.bind(this);
  144. this.websocket.onclose = function(evt) {
  145. if (!window._spacedeck_location_change) {
  146. this.online = false;
  147. }
  148. if (!this.current_timeout) {
  149. this.current_timeout = setTimeout(function() {
  150. console.log("[websocket] onclose: reconnecting", evt);
  151. this.init_websocket();
  152. }.bind(this),5000);
  153. }
  154. }.bind(this);
  155. this.websocket.onmessage = function(evt) {
  156. this.online = true;
  157. try {
  158. var msg = JSON.parse(evt.data);
  159. } catch (e) {
  160. console.log("[websocket] malformed message: ",evt.data);
  161. return;
  162. }
  163. if (msg.channel_id == channel_id) {
  164. return;
  165. }
  166. if (msg.action == "cursor") {
  167. this.handle_user_cursor_update(msg);
  168. }
  169. else if (msg.action == "viewport") {
  170. this.handle_presenter_viewport_update(msg);
  171. }
  172. else if (msg.action == "media") {
  173. this.handle_presenter_media_update(msg);
  174. }
  175. if (msg.action == "update" || msg.action == "create" || msg.action == "delete"){
  176. this.handle_live_updates(msg);
  177. }
  178. if (msg.action == "init") {
  179. channel_id = msg.channel_id;
  180. }
  181. if (msg.action == "auth_valid") {
  182. if (this.active_space) {
  183. this.subscribe(this.active_space);
  184. if (this.unsaved_transactions()) {
  185. console.log("[websockets-saver] found unsaved transactions, triggering save.");
  186. this.process_artifact_save_queue();
  187. }
  188. }
  189. }
  190. if (msg.action == "subscription_valid") {
  191. console.log("subscription_valid");
  192. }
  193. if (msg.action == "status_update") {
  194. var spaceId = msg.space_id;
  195. var users = msg.users;
  196. // filter ourselves
  197. if (this.user && this.user._id) {
  198. users = _.filter(users, function(u) {
  199. return (u && (u._id != this.user._id));
  200. }.bind(this));
  201. }
  202. users = _.filter(users, function(u) {
  203. return (u && (u._id || u.nickname));
  204. });
  205. this.users_online[spaceId] = users;
  206. if (this.active_space) {
  207. if (this.active_space._id == spaceId) {
  208. this.active_space_users = users;
  209. }
  210. }
  211. }
  212. }.bind(this);
  213. this.websocket.onerror = function(evt) {
  214. console.log("websocket.onerror:", evt);
  215. if (!window._spacedeck_location_change) {
  216. this.online = false;
  217. this.was_offline = true;
  218. }
  219. if (!this.current_timeout) {
  220. this.current_timeout = setTimeout(function() {
  221. console.log("websocket.onerror: reconnecting", evt);
  222. this.init_websocket();
  223. }.bind(this),5000);
  224. }
  225. }.bind(this);
  226. }
  227. }
  228. }