diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/node/handler/PadMessageHandler.js | 9 | ||||
-rw-r--r-- | src/node/utils/Settings.js | 5 | ||||
-rw-r--r-- | src/static/css/pad.css | 17 | ||||
-rw-r--r-- | src/static/js/pad_automatic_reconnect.js | 135 | ||||
-rw-r--r-- | src/static/js/pad_modals.js | 8 | ||||
-rw-r--r-- | src/templates/pad.html | 16 |
6 files changed, 176 insertions, 14 deletions
diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 279a44e1..20b262f4 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -936,7 +936,7 @@ function handleSwitchToPad(client, message) var currentSession = sessioninfos[client.id]; var padId = currentSession.padId; var roomClients = _getRoomClients(padId); - + async.forEach(roomClients, function(client, callback) { var sinfo = sessioninfos[client.id]; if(sinfo && sinfo.author == currentSession.author) { @@ -1115,7 +1115,7 @@ function handleClientReady(client, message) //Check if this author is already on the pad, if yes, kick the other sessions! var roomClients = _getRoomClients(pad.id); - + async.forEach(roomClients, function(client, callback) { var sinfo = sessioninfos[client.id]; if(sinfo && sinfo.author == author) { @@ -1176,6 +1176,7 @@ function handleClientReady(client, message) "accountPrivs": { "maxRevisions": 100 }, + "automaticReconnectionTimeout": settings.automaticReconnectionTimeout, "initialRevisionList": [], "initialOptions": { "guestPolicy": "deny" @@ -1676,13 +1677,13 @@ function composePadChangesets(padId, startNum, endNum, callback) function _getRoomClients(padID) { var roomClients = []; var room = socketio.sockets.adapter.rooms[padID]; - + if (room) { for (var id in room.sockets) { roomClients.push(socketio.sockets.sockets[id]); } } - + return roomClients; } diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js index 24bc25c3..a564501d 100644 --- a/src/node/utils/Settings.js +++ b/src/node/utils/Settings.js @@ -178,6 +178,11 @@ exports.loglevel = "INFO"; exports.disableIPlogging = false; /** + * Number of seconds to automatically reconnect pad + */ +exports.automaticReconnectionTimeout = 0; + +/** * Disable Load Testing */ exports.loadTest = false; diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 5764c5e4..0b881d78 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -517,6 +517,23 @@ table#otheruserstable { display: block; } +/* styles for the automatic reconnection timer: */ +#connectivity .visible.with_reconnect_timer button, +#connectivity .visible.with_reconnect_timer .reconnecttimer * { + display: inline-block; +} + +#connectivity .with_reconnect_timer .hidden, +#connectivity .with_reconnect_timer #defaulttext.hidden, +#connectivity .with_reconnect_timer button.hidden { + display: none; +} + +#connectivity .with_reconnect_timer #cancelreconnect { + margin-left: 10px; +} +/* end of styles for the automatic reconnection timer */ + #reconnect_form button { font-size: 12pt; padding: 5px; diff --git a/src/static/js/pad_automatic_reconnect.js b/src/static/js/pad_automatic_reconnect.js new file mode 100644 index 00000000..6474838c --- /dev/null +++ b/src/static/js/pad_automatic_reconnect.js @@ -0,0 +1,135 @@ + +exports.showCountDownTimerToReconnectOnModal = function($modal) { + if (clientVars.automaticReconnectionTimeout && $modal.is('.with_reconnect_timer')) { + createCountDownElementsIfNecessary($modal); + + var timer = createTimerForModal($modal); + + $modal.find('#cancelreconnect').one('click', function() { + timer.cancel(); + disableAutomaticReconnection($modal); + }); + + enableAutomaticReconnection($modal); + } +} + +var createCountDownElementsIfNecessary = function($modal) { + var elementsDoNotExist = $modal.find('#cancelreconnect').length === 0; + if (elementsDoNotExist) { + var $defaultMessage = $modal.find('#defaulttext'); + var $reconnectButton = $modal.find('#forcereconnect'); + + // create extra DOM elements, if they don't exist + var $reconnectTimerMessage = $('<p class="reconnecttimer"> \ + <span data-l10n-id="pad.modals.reconnecttimer">This window will automatically reconnect in </span> \ + <span class="timetoexpire"></span> \ + </p>'); + var $cancelReconnect = $('<button id="cancelreconnect" data-l10n-id="pad.modals.cancel">Cancel</button>'); + + $reconnectTimerMessage.insertAfter($defaultMessage); + $cancelReconnect.insertAfter($reconnectButton); + } +} + +var createTimerForModal = function($modal) { + var timer = new CountDownTimer(clientVars.automaticReconnectionTimeout); + + timer.onTick(function(minutes, seconds) { + updateCountDownTimerMessage($modal, minutes, seconds); + }).onExpire(function() { + reconnect($modal); + }).start(); + + return timer; +} + +var disableAutomaticReconnection = function($modal) { + toggleAutomaticReconnectionOption($modal, true); +} +var enableAutomaticReconnection = function($modal) { + toggleAutomaticReconnectionOption($modal, false); +} +var toggleAutomaticReconnectionOption = function($modal, disableAutomaticReconnect) { + $modal.find('#cancelreconnect, .reconnecttimer').toggleClass('hidden', disableAutomaticReconnect); + $modal.find('#defaulttext').toggleClass('hidden', !disableAutomaticReconnect); +} + +var reconnect = function($modal) { + $modal.find('#forcereconnect').click(); +} + +var updateCountDownTimerMessage = function($modal, minutes, seconds) { + minutes = minutes < 10 ? '0' + minutes : minutes; + seconds = seconds < 10 ? '0' + seconds : seconds; + + $modal.find('.timetoexpire').text(minutes + ':' + seconds); +} + +// Timer based on http://stackoverflow.com/a/20618517. +// duration: how many **seconds** until the timer ends +// granularity (optional): how many **milliseconds** between each 'tick' of timer. Default: 1000ms (1s) +var CountDownTimer = function(duration, granularity) { + this.duration = duration; + this.granularity = granularity || 1000; + this.running = false; + + this.onTickCallbacks = []; + this.onExpireCallbacks = []; +} + +CountDownTimer.prototype.start = function() { + if (this.running) { + return; + } + this.running = true; + var start = Date.now(), + that = this, + diff, obj; + + (function timer() { + diff = that.duration - Math.floor((Date.now() - start) / 1000); + + if (diff > 0) { + that.timeoutId = setTimeout(timer, that.granularity); + + obj = CountDownTimer.parse(diff); + that.onTickCallbacks.forEach(function(callback) { + callback.call(this, obj.minutes, obj.seconds); + }, that); + } else { + that.running = false; + + that.onExpireCallbacks.forEach(function(callback) { + callback.call(this); + }, that); + } + }()); +}; + +CountDownTimer.prototype.onTick = function(callback) { + if (typeof callback === 'function') { + this.onTickCallbacks.push(callback); + } + return this; +}; + +CountDownTimer.prototype.onExpire = function(callback) { + if (typeof callback === 'function') { + this.onExpireCallbacks.push(callback); + } + return this; +}; + +CountDownTimer.prototype.cancel = function() { + this.running = false; + clearTimeout(this.timeoutId); + return this; +}; + +CountDownTimer.parse = function(seconds) { + return { + 'minutes': (seconds / 60) | 0, + 'seconds': (seconds % 60) | 0 + }; +}; diff --git a/src/static/js/pad_modals.js b/src/static/js/pad_modals.js index 67b03662..af048875 100644 --- a/src/static/js/pad_modals.js +++ b/src/static/js/pad_modals.js @@ -1,5 +1,5 @@ /** - * This code is mostly from the old Etherpad. Please help us to comment this code. + * This code is mostly from the old Etherpad. Please help us to comment this code. * This helps other people to understand this code better and helps them to improve it. * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED */ @@ -19,8 +19,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + var padeditbar = require('./pad_editbar').padeditbar; +var automaticReconnect = require('./pad_automatic_reconnect'); var padmodals = (function() { @@ -35,6 +36,9 @@ var padmodals = (function() padeditbar.toggleDropDown("none", function() { $("#connectivity .visible").removeClass('visible'); $("#connectivity ."+messageId).addClass('visible'); + + automaticReconnect.showCountDownTimerToReconnectOnModal($('#connectivity .' + messageId)); + padeditbar.toggleDropDown("connectivity"); }); }, diff --git a/src/templates/pad.html b/src/templates/pad.html index 3d89f9d0..7c1f1fb1 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -249,12 +249,12 @@ <div class="userdup"> <h1 data-l10n-id="pad.modals.userdup"></h1> <h2 data-l10n-id="pad.modals.userdup.explanation"></h2> - <p data-l10n-id="pad.modals.userdup.advice"></p> + <p id="defaulttext" data-l10n-id="pad.modals.userdup.advice"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="unauth"> <h1 data-l10n-id="pad.modals.unauth"></h1> - <p data-l10n-id="pad.modals.unauth.explanation"></p> + <p id="defaulttext" data-l10n-id="pad.modals.unauth.explanation"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="looping"> @@ -267,16 +267,16 @@ <h2 data-l10n-id="pad.modals.initsocketfail.explanation"></h2> <p data-l10n-id="pad.modals.initsocketfail.cause"></p> </div> - <div class="slowcommit"> + <div class="slowcommit with_reconnect_timer"> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.slowcommit.explanation"></h2> - <p data-l10n-id="pad.modals.slowcommit.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.slowcommit.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> - <div class="badChangeset"> + <div class="badChangeset with_reconnect_timer"> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.badChangeset.explanation"></h2> - <p data-l10n-id="pad.modals.badChangeset.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.badChangeset.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="corruptPad"> @@ -288,11 +288,11 @@ <h1 data-l10n-id="pad.modals.deleted"></h1> <p data-l10n-id="pad.modals.deleted.explanation"></p> </div> - <div class="disconnected"> + <div class="disconnected with_reconnect_timer"> <% e.begin_block("disconnected"); %> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.disconnected.explanation"></h2> - <p data-l10n-id="pad.modals.disconnected.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.disconnected.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> <% e.end_block(); %> </div> |