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) {