From 4ccd7131d31d931007f0606173bf212fefa30d79 Mon Sep 17 00:00:00 2001 From: Mike DeRosa Date: Sat, 14 Jun 2014 14:24:54 -0400 Subject: [PATCH 1/4] Added function to switch to a different pad without having to reload the whole page. --- src/node/handler/PadMessageHandler.js | 28 +++++++ src/static/js/chat.js | 4 + src/static/js/collab_client.js | 4 + src/static/js/pad.js | 114 +++++++++++++++++--------- 4 files changed, 109 insertions(+), 41 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 26eb17a6d..fbf43599d 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -217,6 +217,8 @@ exports.handleMessage = function(client, message) } else { messageLogger.warn("Dropped message, unknown COLLABROOM Data Type " + message.data.type); } + } else if(message.type == "CLEAR_SESSION_INFO") { + handleClearSessionInfo(client, message); } else { messageLogger.warn("Dropped message, unknown Message Type " + message.type); } @@ -872,6 +874,32 @@ function _correctMarkersInPad(atext, apool) { return builder.toString(); } +function handleClearSessionInfo(client, message) +{ + var infoMsg = { + type: "COLLABROOM", + data: { + type: "CLEAR_CHAT_MESSAGES" + } + }; + + // send the messages back to the client to clear the chat messages + client.json.send(infoMsg); + + // clear the session and leave the room + var currentSession = sessioninfos[client.id]; + var padId = currentSession.padId; + var roomClients = socketio.sockets.clients(padId); + for(var i = 0; i < roomClients.length; i++) { + var sinfo = sessioninfos[roomClients[i].id]; + if(sinfo && sinfo == currentSession) { + // fix user's counter, works on page refresh or if user closes browser window and then rejoins + sessioninfos[roomClients[i].id] = {}; + roomClients[i].leave(padId); + } + } +} + /** * Handles a CLIENT_READY. A CLIENT_READY is the first message from the client to the server. The Client sends his token * and the pad it wants to enter. The Server answers with the inital values (clientVars) of the pad diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 65fc8dd94..764446908 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -79,6 +79,10 @@ var chat = (function() this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text}); $("#chatinput").val(""); }, + clearChatMessages: function() + { + $('#chattext p').remove(); + }, addMessage: function(msg, increment, isHistoryAdd) { //correct the time diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 146ec51b5..420a6d4cf 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -388,6 +388,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) { chat.addMessage(msg, true, false); } + else if (msg.type == "CLEAR_CHAT_MESSAGES") + { + chat.clearChatMessages(); + } else if (msg.type == "CHAT_MESSAGES") { for(var i = msg.messages.length - 1; i >= 0; i--) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 73fcd3d6b..994d78450 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -51,6 +51,8 @@ var gritter = require('./gritter').gritter; var hooks = require('./pluginfw/hooks'); +var receivedClientVars = false; + function createCookie(name, value, days, path){ /* Warning Internet Explorer doesn't use this it uses the one from pad_utils.js */ if (days) { @@ -160,6 +162,59 @@ function savePassword() return false; } +function sendClearSessionInfo() +{ + var msg = { + "component": "pad", + "type": "CLEAR_SESSION_INFO", + "protocolVersion": 2 + }; + + socket.json.send(msg); +} + +function sendClientReady(isReconnect) +{ + var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1); + padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces + + if(!isReconnect) + { + var titleArray = document.title.split('|'); + var title = titleArray[titleArray.length - 1]; + document.title = padId.replace(/_+/g, ' ') + " | " + title; + } + + var token = readCookie("token"); + if (token == null) + { + token = "t." + randomString(); + createCookie("token", token, 60); + } + + var sessionID = decodeURIComponent(readCookie("sessionID")); + var password = readCookie("password"); + + var msg = { + "component": "pad", + "type": "CLIENT_READY", + "padId": padId, + "sessionID": sessionID, + "password": password, + "token": token, + "protocolVersion": 2 + }; + + //this is a reconnect, lets tell the server our revisionnumber + if(isReconnect == true) + { + msg.client_rev=pad.collabClient.getCurrentRevisionNumber(); + msg.reconnect=true; + } + + socket.json.send(msg); +} + function handshake() { var loc = document.location; @@ -176,44 +231,6 @@ function handshake() 'sync disconnect on unload' : false }); - function sendClientReady(isReconnect) - { - var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1); - padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces - - if(!isReconnect) - document.title = padId.replace(/_+/g, ' ') + " | " + document.title; - - var token = readCookie("token"); - if (token == null) - { - token = "t." + randomString(); - createCookie("token", token, 60); - } - - var sessionID = decodeURIComponent(readCookie("sessionID")); - var password = readCookie("password"); - - var msg = { - "component": "pad", - "type": "CLIENT_READY", - "padId": padId, - "sessionID": sessionID, - "password": password, - "token": token, - "protocolVersion": 2 - }; - - //this is a reconnect, lets tell the server our revisionnumber - if(isReconnect == true) - { - msg.client_rev=pad.collabClient.getCurrentRevisionNumber(); - msg.reconnect=true; - } - - socket.json.send(msg); - }; - var disconnectTimeout; socket.once('connect', function () { @@ -228,7 +245,7 @@ function handshake() } pad.collabClient.setChannelState("CONNECTED"); - sendClientReady(true); + pad.sendClientReady(true); }); socket.on('disconnect', function (reason) { @@ -246,7 +263,6 @@ function handshake() } }); - var receivedClientVars = false; var initalized = false; socket.on('message', function(obj) @@ -286,7 +302,7 @@ function handshake() } //if we haven't recieved the clientVars yet, then this message should it be - else if (!receivedClientVars) + else if (!receivedClientVars && obj.type == "CLIENT_VARS") { //log the message if (window.console) console.log(obj); @@ -426,6 +442,22 @@ var pad = { { return pad.myUserInfo.name; }, + sendClientReady: function(isReconnect) + { + sendClientReady(isReconnect); + }, + switchToPad: function(padId) + { + var options = document.location.href.split('?')[1]; + if(options != null) + window.history.pushState("", "", "/p/" + padId + '?' + options); + else + window.history.pushState("", "", "/p/" + padId); + + sendClearSessionInfo(); + receivedClientVars = false; + sendClientReady(false); + }, sendClientMessage: function(msg) { pad.collabClient.sendClientMessage(msg); From 070ba40f4f7c64f1ed14df13749f94b59b9ce961 Mon Sep 17 00:00:00 2001 From: Mike DeRosa Date: Sun, 6 Jul 2014 18:22:24 -0400 Subject: [PATCH 2/4] Fallback for browsers that don't support window.history.pushstate --- src/static/js/pad.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 994d78450..7d487b1cb 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -449,14 +449,21 @@ var pad = { switchToPad: function(padId) { var options = document.location.href.split('?')[1]; - if(options != null) - window.history.pushState("", "", "/p/" + padId + '?' + options); - else - window.history.pushState("", "", "/p/" + padId); - - sendClearSessionInfo(); - receivedClientVars = false; - sendClientReady(false); + var newHref = "/p/" + padId; + if (options != null) + newHref = newHref + '?' + options; + + if(window.history && window.history.pushState) + { + window.history.pushState("", "", newHref); + sendClearSessionInfo(); + receivedClientVars = false; + sendClientReady(false); + } + else // fallback + { + window.location.href = newHref; + } }, sendClientMessage: function(msg) { From 7861cae76325c4fbc07876d95a264310a5bdc574 Mon Sep 17 00:00:00 2001 From: Mike DeRosa Date: Sat, 12 Jul 2014 16:27:00 -0400 Subject: [PATCH 3/4] Cleaning up switchToPad functionality so that we only need one call to the server("SWITCH_TO_PAD") instead of two (cleaning session info and client ready). Also Clearing chat messages when switchToPad is called in pad.js instead of having the server tell the client to clear the chat messages. --- src/node/handler/PadMessageHandler.js | 49 +++++++++++++-------------- src/static/js/chat.js | 4 --- src/static/js/collab_client.js | 4 --- src/static/js/pad.js | 25 +++++--------- 4 files changed, 32 insertions(+), 50 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index fbf43599d..d0184bc2c 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -217,8 +217,8 @@ exports.handleMessage = function(client, message) } else { messageLogger.warn("Dropped message, unknown COLLABROOM Data Type " + message.data.type); } - } else if(message.type == "CLEAR_SESSION_INFO") { - handleClearSessionInfo(client, message); + } else if(message.type == "SWITCH_TO_PAD") { + handleSwitchToPad(client, message); } else { messageLogger.warn("Dropped message, unknown Message Type " + message.type); } @@ -232,18 +232,7 @@ exports.handleMessage = function(client, message) { // client tried to auth for the first time (first msg from the client) if(message.type == "CLIENT_READY") { - // Remember this information since we won't - // have the cookie in further socket.io messages. - // This information will be used to check if - // the sessionId of this connection is still valid - // since it could have been deleted by the API. - sessioninfos[client.id].auth = - { - sessionID: message.sessionID, - padID: message.padId, - token : message.token, - password: message.password - }; + createSessionInfo(client, message); } // Note: message.sessionID is an entirely different kind of @@ -874,18 +863,8 @@ function _correctMarkersInPad(atext, apool) { return builder.toString(); } -function handleClearSessionInfo(client, message) +function handleSwitchToPad(client, message) { - var infoMsg = { - type: "COLLABROOM", - data: { - type: "CLEAR_CHAT_MESSAGES" - } - }; - - // send the messages back to the client to clear the chat messages - client.json.send(infoMsg); - // clear the session and leave the room var currentSession = sessioninfos[client.id]; var padId = currentSession.padId; @@ -898,6 +877,26 @@ function handleClearSessionInfo(client, message) roomClients[i].leave(padId); } } + + // start up the new pad + createSessionInfo(client, message); + handleClientReady(client, message); +} + +function createSessionInfo(client, message) +{ + // Remember this information since we won't + // have the cookie in further socket.io messages. + // This information will be used to check if + // the sessionId of this connection is still valid + // since it could have been deleted by the API. + sessioninfos[client.id].auth = + { + sessionID: message.sessionID, + padID: message.padId, + token : message.token, + password: message.password + }; } /** diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 764446908..65fc8dd94 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -79,10 +79,6 @@ var chat = (function() this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text}); $("#chatinput").val(""); }, - clearChatMessages: function() - { - $('#chattext p').remove(); - }, addMessage: function(msg, increment, isHistoryAdd) { //correct the time diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 420a6d4cf..146ec51b5 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -388,10 +388,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) { chat.addMessage(msg, true, false); } - else if (msg.type == "CLEAR_CHAT_MESSAGES") - { - chat.clearChatMessages(); - } else if (msg.type == "CHAT_MESSAGES") { for(var i = msg.messages.length - 1; i >= 0; i--) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 7d487b1cb..5d1f10670 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -162,19 +162,9 @@ function savePassword() return false; } -function sendClearSessionInfo() -{ - var msg = { - "component": "pad", - "type": "CLEAR_SESSION_INFO", - "protocolVersion": 2 - }; - - socket.json.send(msg); -} - -function sendClientReady(isReconnect) +function sendClientReady(isReconnect, messageType) { + messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY'; var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1); padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces @@ -197,7 +187,7 @@ function sendClientReady(isReconnect) var msg = { "component": "pad", - "type": "CLIENT_READY", + "type": messageType, "padId": padId, "sessionID": sessionID, "password": password, @@ -442,9 +432,10 @@ var pad = { { return pad.myUserInfo.name; }, - sendClientReady: function(isReconnect) + sendClientReady: function(isReconnect, messageType) { - sendClientReady(isReconnect); + messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY'; + sendClientReady(isReconnect, messageType); }, switchToPad: function(padId) { @@ -455,10 +446,10 @@ var pad = { if(window.history && window.history.pushState) { + $('#chattext p').remove(); //clear the chat messages window.history.pushState("", "", newHref); - sendClearSessionInfo(); receivedClientVars = false; - sendClientReady(false); + sendClientReady(false, 'SWITCH_TO_PAD'); } else // fallback { From 25f6c9bf9a6edb50dba5e8d6060364b3f7d1ceda Mon Sep 17 00:00:00 2001 From: Mike DeRosa Date: Sat, 12 Jul 2014 16:40:59 -0400 Subject: [PATCH 4/4] Checking if the author for the sessions match instead of comparing the entire session. --- src/node/handler/PadMessageHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index d0184bc2c..7a82e4b10 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -871,7 +871,7 @@ function handleSwitchToPad(client, message) var roomClients = socketio.sockets.clients(padId); for(var i = 0; i < roomClients.length; i++) { var sinfo = sessioninfos[roomClients[i].id]; - if(sinfo && sinfo == currentSession) { + if(sinfo && sinfo.author == currentSession.author) { // fix user's counter, works on page refresh or if user closes browser window and then rejoins sessioninfos[roomClients[i].id] = {}; roomClients[i].leave(padId);