summaryrefslogtreecommitdiff
path: root/src/static/js/pad_automatic_reconnect.js
blob: 6474838c96bf93fea57de372afb1095d760fbc09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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
  };
};