zulip/static/js
Steve Howell 6dba3f2420 local echo: Avoid echo until "newest" are found.
We now no longer do local echo if a user has logged in or visited a
narrow so recently that we are still fetching new messages for them in
their current message list.

Since we want any message list we're displaying to show only
contiguous sequences of messages within that view, it's not correct to
append messages that were just sent at the end unless
fetch_status.has_found_newest shows that we are up to date with the
latest messages from the server.

While we have some logic aimed at correcting our-of-order message IDs
in Zulip, even a brief (few seconds) temporary display of that is a
bug that we should avoid.

This means that we should disable local echo when the user's current
narrow is not up to date.  We can be sure that we'll get the message
the user sent from the server either during the catch-up process or
when we receive it back from th server via the events system.

That particular race window can be several seconds in situations where
somebody is in a narrow where their pointer (or equivalent) is far
behind the latest messages.

This commit only fixes the local echo race condition.  There's a
related bug where new messages sent by (potentially other) users
delivered to the client via server_events might race with our fetching
until we get the latest messages in a given narrow, which we'll need
to deal with separately.

See https://github.com/zulip/zulip/issues/8989 for more details.  It's
possible that we'll close the issue after this fix, since any
additional fixes would add a lot of complexity, and I'm not sure how
much of a problem this will really be in practice after this fix.

Note that we don't have great automated testing for
`try_deliver_locally` (or really `echo.js` in general).  For
`try_deliver_locally` the node tests would probably be 8x more complex
than the code itself, since that function is basically "glue" code
touching several external dependencies.  It's also kind of hard to
screw up this code without getting pretty obvious failures early in
the QA process.

Fixes #8989.
2020-02-24 11:45:00 -08:00
..
analytics js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
billing js: Convert _.contains(a, …) to a.includes(…). 2020-02-10 14:08:12 -08:00
bundles util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
portico integrations_dev_panel: Convert loaded_fixtures from object to Map. 2020-02-12 10:39:01 -08:00
stats stats: Convert data from object to Map. 2020-02-12 10:39:01 -08:00
types dependencies: Upgrade stacktrace-gps from 3.0.3 to 3.0.4. 2020-02-04 22:13:33 -08:00
activity.js channel: Don't send outgoing HTTP requests during a reload. 2020-02-13 15:45:39 -08:00
admin.js refactor: Extract settings_config. 2020-02-21 12:06:31 -08:00
alert_words.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
alert_words_ui.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
archive.js js: Use modern spread arguments syntax. 2020-02-11 17:43:35 -08:00
attachments_ui.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
avatar.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
blueslip.js channel: Don't send outgoing HTTP requests during a reload. 2020-02-13 15:45:39 -08:00
blueslip_stacktrace.ts dependencies: Upgrade stacktrace-gps from 3.0.3 to 3.0.4. 2020-02-04 22:13:33 -08:00
bot_data.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
buddy_data.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
buddy_list.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
channel.js channel: Don't send outgoing HTTP requests during a reload. 2020-02-13 15:45:39 -08:00
click_handlers.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
color_data.js streams: Simplify claim_colors. 2019-12-30 09:50:22 -08:00
colorspace.js zjsunit: Use assert in strict mode. 2020-02-12 08:16:26 -05:00
common.js common: Account for string.match returning null. 2020-02-13 16:37:52 -08:00
components.js js: Convert _.find(a, …) to a.find(…). 2020-02-10 14:08:12 -08:00
compose.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
compose_actions.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
compose_fade.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
compose_pm_pill.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
compose_state.js util: Kill off rtrim() helper. 2020-02-15 12:20:20 -08:00
compose_ui.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
composebox_typeahead.js pygments_data: Replace JS module with JSON module. 2020-02-12 10:09:12 -08:00
condense.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
confirm_dialog.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
copy_and_paste.js upload: Replace jQuery filedrop with Uppy. 2020-02-13 16:43:19 -08:00
csrf.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
debug.js debug: Convert sections from object to Map. 2020-02-12 10:39:01 -08:00
dict.ts dict: Remove each method. 2020-02-04 12:22:03 -08:00
drafts.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
echo.js local echo: Avoid echo until "newest" are found. 2020-02-24 11:45:00 -08:00
emoji.js markdown: Extract emoji helpers. 2020-02-18 16:04:04 -08:00
emoji_picker.js emoji_picker: Convert intermediate complete_emoji_catalog to Map. 2020-02-12 10:39:01 -08:00
favicon.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
feature_flags.js js: Purge useless IIFEs. 2019-10-25 13:51:21 -07:00
feedback_widget.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
fenced_code.js util: Kill off rtrim() helper. 2020-02-15 12:20:20 -08:00
fetch_status.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
filter.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
floating_recipient_bar.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
fold_dict.ts dict: Remove each method. 2020-02-04 12:22:03 -08:00
gear_menu.js gear_menu: Convert scroll_positions from object to Map. 2020-02-12 10:39:01 -08:00
global.d.ts util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
hash_util.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
hashchange.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
hbs.d.ts blueslip: Make stack trace more readable. 2019-10-31 13:47:54 -07:00
hotkey.js emoji_codes: Replace JS module with JSON module. 2020-02-12 10:09:12 -08:00
hotspots.js hotspots: Convert HOTSPOT_LOCATIONS from object to Map. 2020-02-10 15:57:20 -08:00
info_overlay.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
input_pill.js js: Convert _.find(a, …) to a.find(…). 2020-02-10 14:08:12 -08:00
int_dict.ts dict: Remove each method. 2020-02-04 12:22:03 -08:00
integration_bot_widget.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
invite.js invitations: Avoid adding to notifications stream unconditionally. 2020-01-27 15:36:59 -08:00
keydown_util.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
lazy_set.js dict, lazy_set: Return an iterator from keys method. 2020-02-04 12:22:03 -08:00
lightbox.js lightbox: Convert asset_map from object to Map. 2020-02-12 10:39:01 -08:00
lightbox_canvas.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
list_cursor.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
list_render.js list_render: Remove unused listRenders object. 2020-02-12 10:39:01 -08:00
list_util.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
loading.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
local_message.js local_message: Convert already_used from object to Set. 2020-02-12 10:39:01 -08:00
localstorage.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
markdown.js markdown: Add helper configuration for mobile. 2020-02-18 16:13:38 -08:00
markdown_config.js markdown: Add helper configuration for mobile. 2020-02-18 16:13:38 -08:00
message_edit.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
message_events.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
message_fetch.js js: Convert remaining _.each(a, …) to a.forEach(…). 2020-02-10 14:08:12 -08:00
message_flags.js js: Convert _.filter(a, …) to a.filter(…). 2020-02-10 14:08:12 -08:00
message_list.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
message_list_data.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
message_list_view.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
message_live_update.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
message_scroll.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
message_store.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
message_util.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
message_viewport.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
muting.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
muting_ui.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
narrow.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
narrow_state.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
navigate.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
night_mode.js js: Purge useless IIFEs. 2019-10-25 13:51:21 -07:00
notifications.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
overlays.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
padded_widget.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
page_params.js page_params: Record page_params_parse_time. 2020-01-15 12:01:14 -08:00
panels.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
people.js markdown: Clean up userMentionHandler(). 2020-02-18 16:04:12 -08:00
pm_conversations.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
pm_list.js js: Convert _.contains(a, …) to a.includes(…). 2020-02-10 14:08:12 -08:00
pm_list_dom.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
pointer.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
poll_widget.js js: Convert _.any(a, …), _.some(a, …) to a.some(…). 2020-02-10 14:08:12 -08:00
popovers.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
presence.js presence: Re-introduce data filtering when offline. 2020-02-13 15:45:39 -08:00
reactions.js emoji_codes: Replace JS module with JSON module. 2020-02-12 10:09:12 -08:00
ready.js templates: Make the Loading… message more robust. 2019-09-20 10:34:44 -07:00
realm_icon.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
realm_logo.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
recent_senders.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
reload.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
reload_state.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
reminder.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
resize.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
rows.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
rtl.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
schema.js js: Convert _.isString to typeof. 2020-02-10 15:57:20 -08:00
scroll_bar.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
scroll_util.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
search.js search_suggestions: Convert lookup_table from object to Map. 2020-02-12 10:39:01 -08:00
search_pill.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
search_pill_widget.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
search_suggestion.js search_suggestion: Convert prev from object to Set. 2020-02-12 10:39:01 -08:00
search_util.js js: Convert _.any(a, …), _.some(a, …) to a.some(…). 2020-02-10 14:08:12 -08:00
sent_messages.js sent_messages: Convert messages from object to Map. 2020-02-12 10:39:01 -08:00
server_events.js channel: Don't send outgoing HTTP requests during a reload. 2020-02-13 15:45:39 -08:00
server_events_dispatch.js refactor: Rename set_realm_filters(). 2020-02-18 15:52:34 -08:00
settings.js refactor: Extract settings_config. 2020-02-21 12:06:31 -08:00
settings_account.js settings_account: Convert all_field_template_types from object to Map. 2020-02-12 10:39:01 -08:00
settings_bots.js js: Convert _.find(a, …) to a.find(…). 2020-02-10 14:08:12 -08:00
settings_config.js refactor: Extract settings_config. 2020-02-21 12:06:31 -08:00
settings_display.js refactor: Extract settings_config. 2020-02-21 12:06:31 -08:00
settings_emoji.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
settings_exports.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
settings_invites.js settings_invites: Convert invited_as_values from object to Map. 2020-02-10 15:57:20 -08:00
settings_linkifiers.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
settings_muting.js js: Clean up stream_id type confusion. 2020-01-16 13:23:47 -08:00
settings_notifications.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
settings_org.js org settings: Convert for…of loop to .some. 2020-02-18 14:28:19 -08:00
settings_panel_menu.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
settings_profile_fields.js settings_profile_fields: Iterate over field_types with Object.values. 2020-02-10 14:08:12 -08:00
settings_sections.js settings_sections: Replace is_loaded Dict with loaded_groups Set. 2020-02-02 20:37:41 -08:00
settings_streams.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
settings_toggle.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
settings_ui.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
settings_user_groups.js zjsunit: Use assert in strict mode. 2020-02-12 08:16:26 -05:00
settings_users.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
setup.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
starred_messages.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
stream_color.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
stream_create.js refactor: Inline ajaxSubscribeForCreation. 2020-02-18 11:02:14 -08:00
stream_data.js refactor: Extract settings_config. 2020-02-21 12:06:31 -08:00
stream_edit.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
stream_events.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
stream_list.js js: Convert remaining _.each(a, …) to a.forEach(…). 2020-02-10 14:08:12 -08:00
stream_muting.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
stream_popover.js Convert more stream_ids to ints. 2020-01-12 11:27:26 -08:00
stream_sort.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
stream_ui_updates.js settings: Migrate to stream_post_policy structure. 2020-02-04 17:08:08 -08:00
submessage.js js: Convert _.find(a, …) to a.find(…). 2020-02-10 14:08:12 -08:00
subs.js subs: Convert hidden_ids from object to Map. 2020-02-12 10:39:01 -08:00
tab_bar.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
templates.js js: Use modern spread arguments syntax. 2020-02-11 17:43:35 -08:00
tictactoe_widget.js tictactoe: Fix type confusion. 2020-02-21 20:01:21 -05:00
timerender.js zjsunit: Use assert in strict mode. 2020-02-12 08:16:26 -05:00
todo_widget.js js: Convert _.any(a, …), _.some(a, …) to a.some(…). 2020-02-10 14:08:12 -08:00
top_left_corner.js top_left_corner: Don't export `should_expand_pm_list()`. 2020-02-11 14:14:59 -08:00
topic_data.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
topic_generator.js js: Convert _.reject(a, … => …) to a.filter(… => !…). 2020-02-10 14:08:12 -08:00
topic_list.js js: Convert _.map(a, …) to a.map(…). 2020-02-10 14:08:12 -08:00
topic_list_data.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
topic_zoom.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
translations.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
transmit.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
tslint.json typescript: Move TS files into JS directory. 2019-03-25 12:11:37 -07:00
tutorial.js js: Purge useless IIFEs. 2019-10-25 13:51:21 -07:00
typeahead_helper.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
typing.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
typing_data.js util.js: Remove util from window. 2020-02-15 12:20:20 -08:00
typing_events.js people: Rename method to get_by_user_id(). 2020-02-05 12:04:56 -08:00
ui.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
ui_init.js markdown: Add helper configuration for mobile. 2020-02-18 16:13:38 -08:00
ui_report.js ui_report: Fix HTML escaping of &. 2020-02-13 17:50:59 -08:00
ui_util.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
unread.js util: Replace util.get_message_topic(). 2020-02-21 09:53:45 -05:00
unread_ops.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
unread_ui.js topic list: Use vdom techniques. 2020-02-05 13:04:16 -08:00
upload.js upload: Replace jQuery filedrop with Uppy. 2020-02-13 16:43:19 -08:00
upload_widget.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
user_events.js people: Rename method to get_by_user_id(). 2020-02-05 12:04:56 -08:00
user_groups.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
user_pill.js js: Convert _.any(a, …), _.some(a, …) to a.some(…). 2020-02-10 14:08:12 -08:00
user_search.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
user_status.js user_status: Iterate over page_params.user_status with Object.entries. 2020-02-07 14:09:47 -08:00
user_status_ui.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00
util.js util: Replace util.set_message_topic(). 2020-02-21 09:53:45 -05:00
vdom.js vdom: Use _.escape for correct HTML escaping. 2020-02-13 17:50:59 -08:00
widgetize.js widgetize: Convert widget_contents from object to Map. 2020-02-06 17:24:43 -08:00
zcommand.js js: Convert a.indexOf(…) !== -1 to a.includes(…). 2020-02-10 14:08:12 -08:00
zform.js js: Automatically convert _.each to for…of. 2020-02-07 14:09:47 -08:00
zulip.js js: Automatically convert var to let and const in most files. 2019-11-03 12:42:39 -08:00