2020-11-23 19:24:19 +01:00
|
|
|
exports.showCountDownTimerToReconnectOnModal = function ($modal, pad) {
|
2017-04-04 16:09:24 +02:00
|
|
|
if (clientVars.automaticReconnectionTimeout && $modal.is('.with_reconnect_timer')) {
|
|
|
|
createCountDownElementsIfNecessary($modal);
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
const timer = createTimerForModal($modal, pad);
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
$modal.find('#cancelreconnect').one('click', () => {
|
2017-04-04 16:09:24 +02:00
|
|
|
timer.cancel();
|
|
|
|
disableAutomaticReconnection($modal);
|
|
|
|
});
|
|
|
|
|
|
|
|
enableAutomaticReconnection($modal);
|
|
|
|
}
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var createCountDownElementsIfNecessary = function ($modal) {
|
|
|
|
const elementsDoNotExist = $modal.find('#cancelreconnect').length === 0;
|
2017-04-04 16:09:24 +02:00
|
|
|
if (elementsDoNotExist) {
|
2020-11-23 19:24:19 +01:00
|
|
|
const $defaultMessage = $modal.find('#defaulttext');
|
|
|
|
const $reconnectButton = $modal.find('#forcereconnect');
|
2017-04-04 16:09:24 +02:00
|
|
|
|
|
|
|
// create extra DOM elements, if they don't exist
|
2020-10-19 18:43:49 +02:00
|
|
|
const $reconnectTimerMessage =
|
|
|
|
$('<p>')
|
|
|
|
.addClass('reconnecttimer')
|
|
|
|
.append(
|
|
|
|
$('<span>')
|
|
|
|
.attr('data-l10n-id', 'pad.modals.reconnecttimer')
|
2020-10-19 18:47:08 +02:00
|
|
|
.text('Trying to reconnect in'))
|
|
|
|
.append(' ')
|
2020-10-19 18:43:49 +02:00
|
|
|
.append(
|
|
|
|
$('<span>')
|
|
|
|
.addClass('timetoexpire'));
|
|
|
|
const $cancelReconnect =
|
|
|
|
$('<button>')
|
|
|
|
.attr('id', 'cancelreconnect')
|
|
|
|
.attr('data-l10n-id', 'pad.modals.cancel')
|
|
|
|
.text('Cancel');
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2017-04-04 23:09:33 +02:00
|
|
|
localize($reconnectTimerMessage);
|
|
|
|
localize($cancelReconnect);
|
|
|
|
|
2017-04-04 16:09:24 +02:00
|
|
|
$reconnectTimerMessage.insertAfter($defaultMessage);
|
|
|
|
$cancelReconnect.insertAfter($reconnectButton);
|
|
|
|
}
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var localize = function ($element) {
|
2017-04-04 23:09:33 +02:00
|
|
|
html10n.translateElement(html10n.translations, $element.get(0));
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var createTimerForModal = function ($modal, pad) {
|
|
|
|
const timeUntilReconnection = clientVars.automaticReconnectionTimeout * reconnectionTries.nextTry();
|
|
|
|
const timer = new CountDownTimer(timeUntilReconnection);
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
timer.onTick((minutes, seconds) => {
|
2017-04-04 16:09:24 +02:00
|
|
|
updateCountDownTimerMessage($modal, minutes, seconds);
|
2020-11-23 19:24:19 +01:00
|
|
|
}).onExpire(() => {
|
|
|
|
const wasANetworkError = $modal.is('.disconnected');
|
2017-04-05 20:07:37 +02:00
|
|
|
if (wasANetworkError) {
|
|
|
|
// cannot simply reconnect, client is having issues to establish connection to server
|
2020-11-23 19:24:19 +01:00
|
|
|
waitUntilClientCanConnectToServerAndThen(() => { forceReconnection($modal); }, pad);
|
2017-04-05 20:07:37 +02:00
|
|
|
} else {
|
|
|
|
forceReconnection($modal);
|
|
|
|
}
|
2017-04-04 16:09:24 +02:00
|
|
|
}).start();
|
|
|
|
|
|
|
|
return timer;
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var disableAutomaticReconnection = function ($modal) {
|
2017-04-04 16:09:24 +02:00
|
|
|
toggleAutomaticReconnectionOption($modal, true);
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
|
|
|
var enableAutomaticReconnection = function ($modal) {
|
2017-04-04 16:09:24 +02:00
|
|
|
toggleAutomaticReconnectionOption($modal, false);
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
|
|
|
var toggleAutomaticReconnectionOption = function ($modal, disableAutomaticReconnect) {
|
2017-04-04 16:09:24 +02:00
|
|
|
$modal.find('#cancelreconnect, .reconnecttimer').toggleClass('hidden', disableAutomaticReconnect);
|
|
|
|
$modal.find('#defaulttext').toggleClass('hidden', !disableAutomaticReconnect);
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var waitUntilClientCanConnectToServerAndThen = function (callback, pad) {
|
2017-04-05 20:07:37 +02:00
|
|
|
whenConnectionIsRestablishedWithServer(callback, pad);
|
|
|
|
pad.socket.connect();
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-05 20:07:37 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var whenConnectionIsRestablishedWithServer = function (callback, pad) {
|
2017-04-05 20:07:37 +02:00
|
|
|
// only add listener for the first try, don't need to add another listener
|
|
|
|
// on every unsuccessful try
|
|
|
|
if (reconnectionTries.counter === 1) {
|
|
|
|
pad.socket.once('connect', callback);
|
|
|
|
}
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-05 20:07:37 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var forceReconnection = function ($modal) {
|
2017-04-04 16:09:24 +02:00
|
|
|
$modal.find('#forcereconnect').click();
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
var updateCountDownTimerMessage = function ($modal, minutes, seconds) {
|
|
|
|
minutes = minutes < 10 ? `0${minutes}` : minutes;
|
|
|
|
seconds = seconds < 10 ? `0${seconds}` : seconds;
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
$modal.find('.timetoexpire').text(`${minutes}:${seconds}`);
|
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2017-04-05 20:07:37 +02:00
|
|
|
// store number of tries to reconnect to server, in order to increase time to wait
|
|
|
|
// until next try
|
|
|
|
var reconnectionTries = {
|
|
|
|
counter: 0,
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
nextTry() {
|
2017-04-05 20:07:37 +02:00
|
|
|
// double the time to try to reconnect on every time reconnection fails
|
2020-11-23 19:24:19 +01:00
|
|
|
const nextCounterFactor = Math.pow(2, this.counter);
|
2017-04-05 20:07:37 +02:00
|
|
|
this.counter++;
|
|
|
|
|
|
|
|
return nextCounterFactor;
|
2020-11-23 19:24:19 +01:00
|
|
|
},
|
|
|
|
};
|
2017-04-05 20:07:37 +02:00
|
|
|
|
2017-04-04 16:09:24 +02:00
|
|
|
// 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)
|
2020-11-23 19:24:19 +01:00
|
|
|
var CountDownTimer = function (duration, granularity) {
|
|
|
|
this.duration = duration;
|
2017-04-04 16:09:24 +02:00
|
|
|
this.granularity = granularity || 1000;
|
2020-11-23 19:24:19 +01:00
|
|
|
this.running = false;
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
this.onTickCallbacks = [];
|
2017-04-04 16:09:24 +02:00
|
|
|
this.onExpireCallbacks = [];
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-04 16:09:24 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.prototype.start = function () {
|
2017-04-04 16:09:24 +02:00
|
|
|
if (this.running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.running = true;
|
2020-11-23 19:24:19 +01:00
|
|
|
const start = Date.now();
|
|
|
|
const that = this;
|
|
|
|
let diff;
|
2017-04-04 16:09:24 +02:00
|
|
|
|
|
|
|
(function timer() {
|
|
|
|
diff = that.duration - Math.floor((Date.now() - start) / 1000);
|
|
|
|
|
|
|
|
if (diff > 0) {
|
|
|
|
that.timeoutId = setTimeout(timer, that.granularity);
|
2017-04-05 20:07:37 +02:00
|
|
|
that.tick(diff);
|
2017-04-04 16:09:24 +02:00
|
|
|
} else {
|
|
|
|
that.running = false;
|
2017-04-05 20:07:37 +02:00
|
|
|
that.tick(0);
|
|
|
|
that.expire();
|
2017-04-04 16:09:24 +02:00
|
|
|
}
|
|
|
|
}());
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.prototype.tick = function (diff) {
|
|
|
|
const obj = CountDownTimer.parse(diff);
|
|
|
|
this.onTickCallbacks.forEach(function (callback) {
|
2017-04-05 20:07:37 +02:00
|
|
|
callback.call(this, obj.minutes, obj.seconds);
|
|
|
|
}, this);
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
|
|
|
CountDownTimer.prototype.expire = function () {
|
|
|
|
this.onExpireCallbacks.forEach(function (callback) {
|
2017-04-05 20:07:37 +02:00
|
|
|
callback.call(this);
|
|
|
|
}, this);
|
2020-11-23 19:24:19 +01:00
|
|
|
};
|
2017-04-05 20:07:37 +02:00
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.prototype.onTick = function (callback) {
|
2017-04-04 16:09:24 +02:00
|
|
|
if (typeof callback === 'function') {
|
|
|
|
this.onTickCallbacks.push(callback);
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.prototype.onExpire = function (callback) {
|
2017-04-04 16:09:24 +02:00
|
|
|
if (typeof callback === 'function') {
|
|
|
|
this.onExpireCallbacks.push(callback);
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.prototype.cancel = function () {
|
2017-04-04 16:09:24 +02:00
|
|
|
this.running = false;
|
|
|
|
clearTimeout(this.timeoutId);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2020-11-23 19:24:19 +01:00
|
|
|
CountDownTimer.parse = function (seconds) {
|
2017-04-04 16:09:24 +02:00
|
|
|
return {
|
2020-11-23 19:24:19 +01:00
|
|
|
minutes: (seconds / 60) | 0,
|
|
|
|
seconds: (seconds % 60) | 0,
|
2017-04-04 16:09:24 +02:00
|
|
|
};
|
|
|
|
};
|