diff --git a/templates/zephyr/index.html b/templates/zephyr/index.html
index 20fbe8f053..3fca2e82bf 100644
--- a/templates/zephyr/index.html
+++ b/templates/zephyr/index.html
@@ -36,6 +36,7 @@
+
diff --git a/tools/jslint/check-all.js b/tools/jslint/check-all.js
index ba3171339b..5b259d047f 100644
--- a/tools/jslint/check-all.js
+++ b/tools/jslint/check-all.js
@@ -23,6 +23,9 @@ var globals =
// narrow.js
+ ' narrow'
+ // reload.js
+ + ' reload'
+
// search.js
+ ' search_button_handler something_is_highlighted update_highlight_on_narrow'
diff --git a/zephyr/static-access-control/4nrjx8cwce2bka8r/js/reload.js b/zephyr/static-access-control/4nrjx8cwce2bka8r/js/reload.js
new file mode 120000
index 0000000000..91ab8d5705
--- /dev/null
+++ b/zephyr/static-access-control/4nrjx8cwce2bka8r/js/reload.js
@@ -0,0 +1 @@
+../../../static/js/reload.js
\ No newline at end of file
diff --git a/zephyr/static/js/compose.js b/zephyr/static/js/compose.js
index 2724721c0a..9f72d9930f 100644
--- a/zephyr/static/js/compose.js
+++ b/zephyr/static/js/compose.js
@@ -67,7 +67,7 @@ $(function () {
error: function (xhr, error_type) {
if (error_type !== 'timeout' && get_updates_params.reload_pending) {
// The error might be due to the server changing
- do_reload_app_preserving_compose(true);
+ reload.initiate({immediate: true, send_after_reload: true});
return;
}
var response = "Error sending message";
@@ -105,7 +105,7 @@ $(function () {
});
exports.show = function (tabname, focus_area) {
- if (reloading_app) {
+ if (reload.is_in_progress()) {
return;
}
$("#send-status").removeClass(status_classes).hide();
diff --git a/zephyr/static/js/reload.js b/zephyr/static/js/reload.js
new file mode 100644
index 0000000000..201e476002
--- /dev/null
+++ b/zephyr/static/js/reload.js
@@ -0,0 +1,131 @@
+var reload = (function () {
+
+var exports = {};
+
+var reload_in_progress = false;
+var reload_pending = false;
+
+exports.is_pending = function () {
+ return reload_pending;
+};
+
+exports.is_in_progress = function () {
+ return reload_in_progress;
+};
+
+function preserve_compose(send_after_reload) {
+ if (send_after_reload === undefined) {
+ send_after_reload = 0;
+ }
+ var url = "#reload:send_after_reload=" + Number(send_after_reload);
+ if (compose.composing() === 'stream') {
+ url += "+msg_type=stream";
+ url += "+stream=" + encodeURIComponent(compose.stream_name());
+ url += "+subject=" + encodeURIComponent(compose.subject());
+ } else {
+ url += "+msg_type=huddle";
+ url += "+recipient=" + encodeURIComponent(compose.recipient());
+ }
+ url += "+msg="+ encodeURIComponent(compose.message_content());
+
+ window.location.replace(url);
+}
+
+// Check if we're doing a compose-preserving reload. This must be
+// done before the first call to get_updates
+$(function () {
+ var location = window.location.toString();
+ window.location = '#';
+ var fragment = location.substring(location.indexOf('#') + 1);
+ if (fragment.search("reload:") !== 0) {
+ return;
+ }
+
+ fragment = fragment.replace(/^reload:/, "");
+ var keyvals = fragment.split("+");
+ var vars = {};
+ $.each(keyvals, function (idx, str) {
+ var pair = str.split("=");
+ vars[pair[0]] = decodeURIComponent(pair[1]);
+ });
+
+ var tab;
+ var send_now = parseInt(vars.send_after_reload, 10);
+
+ // TODO: preserve focus
+ compose.start(vars.msg_type, {stream: vars.stream,
+ subject: vars.subject,
+ huddle_recipient: vars.recipient,
+ message: vars.msg});
+ if (send_now) {
+ compose.finish();
+ }
+});
+
+function do_reload_app(send_after_reload) {
+ // TODO: we should completely disable the UI here
+ if (compose.composing()) {
+ preserve_compose(send_after_reload);
+ }
+ // TODO: We need a better API for showing messages.
+ report_message("The application has been updated; reloading!", $("#reloading-application"));
+ reload_in_progress = true;
+ window.location.reload(true);
+}
+
+exports.initiate = function (options) {
+ var defaults = {immediate: false,
+ send_after_reload: false};
+ options = $.extend(defaults, options);
+
+ if (options.immediate) {
+ do_reload_app(options.send_after_reload);
+ }
+
+ if (reload_pending) {
+ return;
+ }
+ reload_pending = true;
+
+ // Always reload after 30 minutes
+ setTimeout(function () { do_reload_app(false); }, 1000 * 60 * 30);
+
+ // If the user is composing a message, reload if they become idle
+ // while composing. If they finish or cancel the compose, wait
+ // until they're idle again
+ var idle_control;
+ var composing_timeout = 1000*60*5;
+ var home_timeout = 1000*60;
+ var compose_done_handler, compose_started_handler;
+
+ compose_done_handler = function () {
+ idle_control.cancel();
+ idle_control = $(document).idle({'idle': home_timeout,
+ 'onIdle': do_reload_app});
+ $(document).off('compose_canceled.zephyr compose_finished.zephyr',
+ compose_done_handler);
+ $(document).on('compose_started.zephyr', compose_started_handler);
+ };
+ compose_started_handler = function () {
+ idle_control.cancel();
+ idle_control = $(document).idle({'idle': composing_timeout,
+ 'onIdle': do_reload_app});
+ $(document).off('compose_started.zephyr', compose_started_handler);
+ $(document).on('compose_canceled.zephyr compose_finished.zephyr',
+ compose_done_handler);
+ };
+
+ if (compose.composing()) {
+ idle_control = $(document).idle({'idle': composing_timeout,
+ 'onIdle': do_reload_app});
+ $(document).on('compose_canceled.zephyr compose_finished.zephyr',
+ compose_done_handler);
+ } else {
+ idle_control = $(document).idle({'idle': home_timeout,
+ 'onIdle': do_reload_app});
+ $(document).on('compose_started.zephyr', compose_started_handler);
+ }
+};
+
+return exports;
+}());
\ No newline at end of file
diff --git a/zephyr/static/js/zephyr.js b/zephyr/static/js/zephyr.js
index 516397531f..bb869a29b9 100644
--- a/zephyr/static/js/zephyr.js
+++ b/zephyr/static/js/zephyr.js
@@ -4,7 +4,6 @@ var subject_dict = {};
var people_hash = {};
var viewport = $(window);
-var reloading_app = false;
var selected_message_id = -1; /* to be filled in on document.ready */
var selected_message; // = rows.get(selected_message_id)
@@ -473,116 +472,11 @@ function add_messages(messages, where) {
update_autocomplete();
}
-function do_reload_app() {
- // TODO: We need a better API for showing messages.
- report_message("The application has been updated; reloading!", $("#reloading-application"));
- reloading_app = true;
- window.location.reload(true);
-}
-
-function start_reload_app() {
- if (get_updates_params.reload_pending) {
- return;
- }
- get_updates_params.reload_pending = 1;
-
- // Always reload after 30 minutes
- setTimeout(function () { do_reload_app_preserving_compose(false); },
- 1000 * 60 * 30);
-
- // If the user is composing a message, reload if they become
- // idle while composing. If they finish composing, the
- // submit code will reload the app. If they cancel the
- // compose, wait until they're idle again
-
- // If the user is not composing, reload if the user becomes idle.
- // If they start composing, postpone reloading
-
- var idle_control;
- var composing_timeout = 1000*60*10;
- var home_timeout = 1000*60;
- var compose_done_handler, compose_started_handler;
-
- compose_done_handler = function () {
- idle_control.cancel();
- idle_control = $(document).idle({'idle': home_timeout,
- 'onIdle': do_reload_app});
- $(document).off('compose_canceled.zephyr compose_finished.zephyr',
- compose_done_handler);
- $(document).on('compose_started.zephyr', compose_started_handler);
- };
- compose_started_handler = function () {
- idle_control.cancel();
- idle_control = $(document).idle({'idle': composing_timeout,
- 'onIdle': do_reload_app_preserving_compose});
- $(document).off('compose_started.zephyr', compose_started_handler);
- $(document).on('compose_canceled.zephyr compose_finished.zephyr',
- compose_done_handler);
- };
-
- if (compose.composing()) {
- idle_control = $(document).idle({'idle': composing_timeout,
- 'onIdle': do_reload_app_preserving_compose});
- $(document).on('compose_canceled.zephyr compose_finished.zephyr',
- compose_done_handler);
- } else {
- idle_control = $(document).idle({'idle': home_timeout,
- 'onIdle': do_reload_app});
- $(document).on('compose_started.zephyr', compose_started_handler);
- }
-}
-
-function do_reload_app_preserving_compose(send_after_reload) {
- var url = "#reload:send_after_reload=" + Number(send_after_reload);
- if (compose.composing() === 'stream') {
- url += "+msg_type=stream";
- url += "+stream=" + encodeURIComponent(compose.stream_name());
- url += "+subject=" + encodeURIComponent(compose.subject());
- } else {
- url += "+msg_type=huddle";
- url += "+recipient=" + encodeURIComponent(compose.recipient());
- }
- url += "+msg="+ encodeURIComponent(compose.message_content());
-
- window.location.replace(url);
- do_reload_app();
-}
-
-// Check if we're doing a compose-preserving reload. This must be
-// done before the first call to get_updates
-$(function () {
- var location = window.location.toString();
- window.location = '#';
- var fragment = location.substring(location.indexOf('#') + 1);
- if (fragment.search("reload:") !== 0) {
- return;
- }
-
- fragment = fragment.replace(/^reload:/, "");
- var keyvals = fragment.split("+");
- var vars = {};
- $.each(keyvals, function (idx, str) {
- var pair = str.split("=");
- vars[pair[0]] = decodeURIComponent(pair[1]);
- });
-
- var tab;
- var send_now = parseInt(vars.send_after_reload, 10);
-
- // TODO: preserve focus
- compose.start(vars.msg_type, {stream: vars.stream,
- subject: vars.subject,
- huddle_recipient: vars.recipient,
- message: vars.msg});
- if (send_now) {
- compose.finish();
- }
-});
-
var get_updates_xhr;
var get_updates_timeout;
function get_updates() {
get_updates_params.pointer = selected_message_id;
+ get_updates_params.reload_pending = Number(reload.is_pending());
get_updates_xhr = $.ajax({
type: 'POST',
@@ -607,7 +501,7 @@ function get_updates() {
if (get_updates_params.server_generation === -1) {
get_updates_params.server_generation = data.server_generation;
} else if (data.server_generation !== get_updates_params.server_generation) {
- start_reload_app();
+ reload.initiate();
}
if (data.messages.length !== 0) {