diff --git a/templates/zephyr/index.html b/templates/zephyr/index.html index ac65b1f752..3c0d909cd9 100644 --- a/templates/zephyr/index.html +++ b/templates/zephyr/index.html @@ -50,6 +50,7 @@ {# Not escaped, because it's guaranteed by the model to be an integer. #} var initial_pointer = {{ user_profile.pointer }}; +var server_generation = {{ server_generation }}; var email = "{{ user_profile.user.email|escapejs }}"; var have_initial_messages = {{ have_initial_messages|escapejs }}; diff --git a/tools/jslint/check-all.js b/tools/jslint/check-all.js index 4c8113fbf4..04e6c75da8 100644 --- a/tools/jslint/check-all.js +++ b/tools/jslint/check-all.js @@ -7,6 +7,7 @@ var globals = // index.html + ' initial_pointer email stream_list people_list have_initial_messages' + + ' server_generation' // compose.js + ' show_compose hide_compose toggle_compose clear_compose_box compose_button' diff --git a/zephyr/static/js/zephyr.js b/zephyr/static/js/zephyr.js index eea4dfd053..b062495e19 100644 --- a/zephyr/static/js/zephyr.js +++ b/zephyr/static/js/zephyr.js @@ -57,9 +57,12 @@ var selected_message; // = get_message_row(selected_message_id) var received = { first: -1, last: -1, - failures: 0 + failures: 0, + server_generation: -1 /* to be filled in on document.ready */ }; +$(function () { received.server_generation = server_generation; }); + // The "message groups", i.e. blocks of messages collapsed by recipient. // Each message table has a list of lists. var message_groups = { diff --git a/zephyr/views.py b/zephyr/views.py index 85084394f3..a416a9afbf 100644 --- a/zephyr/views.py +++ b/zephyr/views.py @@ -28,6 +28,9 @@ import socket import re import hashlib import urllib +import time + +SERVER_GENERATION = int(time.time()) def require_post(view_func): def _wrapped_view_func(request, *args, **kwargs): @@ -174,7 +177,8 @@ def home(request): 'have_initial_messages': 'true' if num_messages > 0 else 'false', 'show_debug': - settings.DEBUG and ('show_debug' in request.GET) }, + settings.DEBUG and ('show_debug' in request.GET), + 'server_generation': SERVER_GENERATION}, context_instance=RequestContext(request)) @login_required @@ -203,12 +207,14 @@ def format_updates_response(messages, mit_sync_bot=False, apply_markdown=False, return {'messages': [message.to_dict(apply_markdown) for message in messages], "result": "success", "msg": "", - 'where': where} + 'where': where, + 'server_generation': SERVER_GENERATION} def return_messages_immediately(request, handler, user_profile, **kwargs): first = request.POST.get("first") last = request.POST.get("last") failures = request.POST.get("failures") + client_server_generation = request.POST.get("server_generation") if first is None or last is None: # When an API user is first querying the server to subscribe, # there's no reason to reply immediately. @@ -251,6 +257,12 @@ def return_messages_immediately(request, handler, user_profile, **kwargs): handler.finish(format_updates_response([], where="bottom", **kwargs)) return True + if client_server_generation is not None and int(client_server_generation) != SERVER_GENERATION: + # No messages, but still return immediately to inform the + # client that they should reload + handler.finish(format_updates_response([], where="bottom", **kwargs)) + return True + return False def get_updates_backend(request, user_profile, handler, **kwargs):