Commit Graph

195 Commits

Author SHA1 Message Date
Steve Howell baa691db7d narrow: Fix how we select ids for narrows.
This commit fixes a couple regression related to narrowing.

For a long time we've had bugs where we too aggressively
preserve the currrent selection on topic -> stream
re-narrows ("s" key) even when the wider narrow may
have unread messages before the selection.

Also, we recently introduced a bug so that when you used
a link from the "copy link to conversation" (aka a "near"
query), it would advance you to your first unread message
despite the near:999 specifier.  (The code would work for
subsequent "near" queries once you had fetched some of
your original messages).

This commit introduces a new data structure called id_info (replacing
the select_strategy data structure) in various functions and uses that
to track all the ids of relevance.

Significantly rewritten by tabbott to handle a few extra corner cases,
and add a ton of comments explaining why it works the way it does.

Fixes #2091.
Fixes #9606.
2018-06-01 12:45:02 -07:00
Steve Howell ab9e348fab dead code: Remove narrow.by_time_travel(). 2018-05-31 17:13:50 -07:00
Steve Howell d0ad6295fa Avoid unneeded call to can_apply_locally().
The "if" condition that was removed in this commit
is no longer needed, since the called code now
handles the cannot-apply-locally use case.  (We
wanted the called functions to be defensive, so
they already were effectively handling the conditions
anyway, and recent commits has them returning
appropriate values and doing the right things.)
2018-05-31 08:44:18 -07:00
Shubham Dhama e4e47a41d2 eslint: Enable "no-whitespace-before-property". 2018-05-31 08:11:57 -07:00
Shubham Padia d9b0ab2ae7 narrow: Show non-existing user message for invalid emails.
Also adds people.is_valid_bulk_emails_for_compose and refactors
narrow_state.set_compose_defaults to use it.
2018-05-28 10:45:42 -07:00
Steve Howell 034164945f Fix tracebacks related to direct use of msg_list._items.
We had debug code that was reaching into msg_list._items when
it could use msg_list.all_messages() instead.

When we split out MessageListData, using _items started
breaking this code.
2018-05-25 08:28:56 -07:00
Steve Howell 8cb383223d Defer creating messages lists in narrows.
We now work with MessageListData objects while populating
data from local narrows, before actually making the
wrapper MessageList object.

This change will simplify unit testing (less view stuff
to fake out) in certain situations.

It will also allow us to eliminate the delay_render flag.
2018-05-15 14:25:21 -07:00
Steve Howell ff009fadf9 refactor: Have MessageList take in a data object.
We now allow you to initialize a MessageList with
a MessageListData object that you build outside of
the initializer.
2018-05-15 14:25:21 -07:00
Steve Howell a3d3d08a80 refactor: Avoid positional params for MessageList.
We used to have positional parameters for table_name
and filter, but we don't use them for message_list.all
and we're about to replace filter in some cases.

Passing everything in on opts is more consistent and
self-documenting in the calling code, plus lots of
unit tests can get away with passing in `{}` now
for situations where table_name does not matter.

All of our callers pass in muting_enabled, so we
remove the default value for it.  And then the
collapse_messages variable doesn't have to live on
`this` as it's only being passed through down to the
view.
2018-05-15 14:25:21 -07:00
Steve Howell 08fd2027a1 Refine offset logic for narrows.
We now only preserve the offset for the previous
selection (pre-narrow) if that is still the id
we want selected after calling maybe_add_local_messages.

Right not this does not change any behavior, but
upcoming changes to maybe_add_local_messages will
change the selected id to the first unread message
in certain circumstances, in which case preserving
the offset will possibly be confusing, since you're
not on the same message.
2018-05-15 14:25:21 -07:00
Tim Abbott 7ab8a8e820 js: Fix a bunch of indentation issues found by eslint.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).

The one area that we do not attempt to work on here is the
"switch/case" indentation.
2018-05-06 16:25:02 -07:00
Steve Howell 0463bb2c5e Fix corner case with recent narrowing optimization.
For a commit that was just merged I had the "back-out" case
at the wrong nesting level.  It was a pretty obscure failure
scenario that never came up in practice, but basically if you
were starting at a message that was not in your narrow, but
we did have some messages in your narrow, we would try to
go near the old message instead of talking to the server to
find the next unread message in that narrow.
2018-05-04 17:34:34 -07:00
Steve Howell 4573bdd005 narrow: Load messages locally for most sidebar clicks.
Barring a few minor edge cases, when we now do a narrow
that is based on a sidebar-like search (e.g. stream/topic,
no extra conditions), we now go directly to either the
first unread message we know about locally or the last
message if we're all caught up.

We of course used to do this in master until recently; this behavior
was broken by Tim's narrowing refactor branch (ending with
26ac1d237b) which moved us to always
using the select_first_unread flag, by default (fixing issues where if
you clicked around while your pointer was behind, you'd land in the
wrong place).

We now have arguably the best of both worlds:
* The pointer is not considered when computing narrowing positioning
* We only go to the server for sidebar clicks if the data isn't
  available in the browser.
2018-05-04 16:36:51 -07:00
Steve Howell c00a054893 minor: Update comment in narrow.activate(). 2018-05-03 07:52:15 -07:00
Steve Howell 93ce1fa95c refactor: Extract save_pre_narrow_offset_for_reload().
This is purely to make it easier to read narrow.activate()
without having to page past lots of unnecessary detail when
you're trying to understand things like how we set the
selection.
2018-05-03 07:52:15 -07:00
Steve Howell e0557046f3 refactor: Extract narrow.update_selection().
The maybe_select_closest helper, when first introduced, was
tiny and close to its callers.

As it's grown, it's become kind of a big hurdle to reading
narrow.activate(), because it's out of chronological order
and it's hard to tell at a glance which variables it's closing
on.

Now we just move it out to module scope.

It's mostly moving code, with these minor changes:

        * we pass in opts for the old closure vars
        * we rename then_select_offset -> select_offset
        * we early-exit on empty lists
2018-05-03 07:52:15 -07:00
Steve Howell d359c89b0c refactor: Introduce select_strategy in narrow.activate.
We replace these variables in narrow.activate:

        then_select_id (int w/-1 as a sentinel)
        select_first_unread (boolean)

The main goal here is to get away from the boolean, since
we are about to introduce a third select strategy.

The new var is select_strategy and it has a union
type with these flavors:

        "exact" (was select_first_unread === false)
        "first_unread" (was select_first_unread === true)

The new flavor will be something like "last_id".

Eliminating then_select_id is also nice, since the -1
sentinel value could be a pitfall, and it's semantically
cleaner to encapsulate behind a check for
select_strategy.flavor.
2018-05-03 07:52:15 -07:00
Steve Howell b046b158d9 refactor: Add a fetch_message IIFE in narrow.activate.
We use an IIFE (immediately invoked function expression)
to fetch messages.  This will allow us to introduce some
local vars in a subsequent commit without creating an ugly
diff and without cluttering an already crowded namespace.
2018-05-03 07:52:15 -07:00
Steve Howell 0bbbdb65b4 minor: Introduce msg_id in maybe_select_closest().
This cleans up a subsequent diff.  Within the context of
`maybe_select_closest`, there's only one `msg_id` we care about,
so the more convoluted name `then_select_id` makes much less
sense than it does in the enclosing scope, and it will make
even less sense after some future changes.

There's also some cosmetic cleanup here.
2018-05-03 07:52:15 -07:00
Steve Howell df0e4a73fa refactor: Remove brittle check for !select_first_unread.
When we are deciding whether to preserve scroll position, we
mainly care that then_select_offset is set to a value.  If
we had no intention of preserving scroll offset, we would have
never bothered to set it.  The check for !select_first_unread
is always redundant, as verified by lots of clicking around
with some print debugging.  And it's a brittle check,
because it couples the decision of scrolling destination to
the mechanism by which we decide our selection.  While those
things are closely related, it's possible in the future that
we'll decide to advance to an unread message and still want
to set then_select_offset, but we might forget to mutate
select_first_unread.

Long story short, the code is simpler and safer now.
2018-05-03 07:52:15 -07:00
Steve Howell 3e08270d48 refactor: Simplify then_select_offset calculation.
We move the var declaration of then_select_offset closer to
where it gets calculated, and we avoid code duplication in
calling current_msg_list.get_row().
2018-05-03 07:52:15 -07:00
Steve Howell d021a51047 Avoid brittle attempt to get messages with id === -1.
Even when then_select_id has the sentinel value of -1, we were
trying to look it up in our message_list.all object.  This would
have returned undefined, which is fine, but it's more explicit
to just bypass the check.
2018-05-03 07:52:15 -07:00
Steve Howell 1941a0eb51 refactor: Swap conditions for pre-filling narrows.
This mostly sets up the next commit.  The two conditions here
are both inexpensive to check, but we want to bypass an upcoming
expensive operation if can_apply_locally() returns false.
2018-05-02 13:34:54 -07:00
Tim Abbott 26ac1d237b narrow: Remove now-unnecessary use_initial_narrow_pointer option.
We replace it with the much more intuitive then_select_offset option.
2018-04-22 21:33:34 -07:00
Tim Abbott ccd546cc75 narrow: Migrate code for use_initial_narrow_pointer. 2018-04-22 21:33:33 -07:00
Tim Abbott a0c6930ca9 narrow: Remove confusing code to unset use_initial_narrow_pointer.
Nothing reads that variable after this point, so we don't need to mutate it.
2018-04-22 21:33:33 -07:00
Tim Abbott 35585f75d9 narrow: Move select_first_unread to be a local variable.
This makes the API more obvious that this is not a parameter to be
passed into narrow.activate.
2018-04-22 21:33:33 -07:00
Tim Abbott e4c50ff4fd narrow: Remove unnecessary select_first_unread option.
We consistently either pass a `then_select_id` into narrow.activate,
or were using the select_first_unread option.  Now, we just compute
select_first_unread based on the value of then_select_id.
2018-04-22 21:33:33 -07:00
Tim Abbott 6bab4e0aad narrow: Fix narrowing behavior when loading a new tab.
In the very early days of Zulip, we didn't have unread counts; just
the pointer, and the correct behavior when opening a new tab was to
place you near the pointer.  That doesn't make any sense now that we
do have unread counts, and this corner case has been a wart for a long
time.

This commit does the main behavior change here.  However, there's a
bug we need to fix, where we might end up trying to pre-render a view
of the narrow based on the `all_msg_list` data before `all_msg_list`
is caught up).  We need to fix that bug before we can merge this; it
should be possible to determine that using `FetchStatus` on
`all_msg_list`, or with better performance by using the `unread_msgs`
structure to determine whether the message we should be selecting is
present locally.

Fixes #789.
Fixes #9070.
2018-04-22 21:33:17 -07:00
Tim Abbott 1d5204c82b narrow: Fix incorrect values for use_first_unread_anchor.
Apparently, we were incorrectly passing through something related to
opts.use_initial_narrow_pointer as the value for `use_first_anchor`.

If you read the logic in narrow.js carefully,
use_initial_narrow_pointer was unconditionally false.

The correct value for this attribute is when we're trying to narrow to
the first unread message in a given context.  There are two things to
check:

* then_select_id is -1; i.e. we don't have a specific message ID we're
  trying to narrow around.
* select_first_unread is True, i.e. we're trying to narrow to the
  first unread message.

A bit more work should allow us to get rid of the second condition,
but I'm not quite confident enough to do that yet.
2018-04-22 21:33:14 -07:00
Tim Abbott 5ae9505fdc message_list: Move set_message_offset into message_list_view.
The refactor in 12509515ae had a subtle
bug, which is that we switched from accessing the message list "this"
(aka the message list being rerendered) to current_msg_list.  This
meant that when the narrowed_msg_list was in view and code needed to
modify home_msg_list, we accessed the wrong `selected_row` to preserve
the scroll position of (namely, the one in current_msg_list, not the
one in home_msg_list).

Fix this, by moving the function to be a property of the
message_list_view object, which makes more sense structurally, anyway.

We may, in the future, want to do a similar migration for more of
message_viewport.js.

Fixes #8854.
2018-04-13 16:31:18 -07:00
Shubham Padia 6262460773 refactor: Rename mark_message(s)_as_read to notify_server_message(s)_read.
Fixes #8965.
Mark_message(s)_as_read is used in marking a message as having been
read by the browser, rename it to notify_server_message(s)_read to
avoid any confusion.
2018-04-05 09:54:48 -07:00
Tim Abbott 43ec04dcff narrow: Fix a buggy condense_and_collapse call.
Previously, when unnarrowing, we were calling this on the wrong
selector (this was missed years ago when we refactored Zulip to use
divs rather than table rows in the main message feed).

Noticed while debugging #5312.
2018-03-27 09:53:45 -07:00
Steve Howell 616a06e5b2 Use msg_list.fetch_status instead of load_enabled.
We now attach a fetch_status to message lists, so that they
can track their fetch status individually.  When you go
back in a narrow and get all the older messages, we turn
off future fetches.

The narrow.js code no longer needs to orchestrate anything
here.  The "home" message list won't have as many redundant
fetches after this commit, because we don't need to reset
flags every time we do `narrow.deactivate`.

And then actual narrows get a new message list every time
you narrow, so their fetch status gets reset implicitly
as part of constructing the MessageList object.
2018-03-09 14:20:58 -08:00
Steve Howell 1e446fcb1a refactor: Call message_scroll.hide_indicators() directly.
We are going to remove message_fetch.reset_for_narrow() soon,
but its callers probably still want to hide any scrolling
indicators, and we just let them do that directly.
2018-03-09 14:20:58 -08:00
Steve Howell ec305149be Extract message_fetch.load_messages_for_narrow().
This helps us consolidate the fetching constants without
having to export them.  It will also remove some
responsibility for narrow.js to track fetching state.
2018-03-09 14:20:58 -08:00
Steve Howell 22162a02a8 Remove unused cont_will_add_messages flag.
(It was always false.)
2018-03-09 14:20:58 -08:00
Steve Howell 7bbdf79b78 Rename functions to show_loading_older/hide_loading_older. 2018-03-09 11:04:29 -08:00
Steve Howell 389421d9c2 Rename reset_load_more_status to reset_for_new_narrow.
We are about to make this logic a little more specific to
what happens when you make a new narrow.
2018-03-09 11:04:29 -08:00
Steve Howell 68d3441de1 Rename load_old_messages to load_messages.
This function will eventually sometimes load messages that
are "new" relative to the messages that have already been
loaded.
2018-03-09 11:04:29 -08:00
Steve Howell 8063f73f6d Extract message_scroll.js.
This mostly moves code from ui.js.

We change the arguments to `message_fetch.load_more_messages()`
to be `opts` with callbacks for `show_loading` and `hide_loading`.

We also defer starting the scroll handler until `message_fetch.js`
has been initialized.
2018-03-08 15:03:47 -08:00
Abhigyan Khaund a75f0aa594 hotkeys: Add "p" to narrow to next unread PM thread.
This works simimlar to the "n" key for next topics.

This commit does a few things:

    * It wires up the hotkey to an existing function
      that could change narrows.
    * It adds documentation.
    * It adds logic to make sure the compose box does
      not open.

@showell helped a bit with the wording of comments here.

Fixes #4874
2018-02-27 07:20:31 -05:00
Steve Howell 46a49777c4 Add stream ids to urls for stream-related narrows.
This commit prefixes stream names in urls with stream ids,
so that the urls don't break when we rename streams.

strean name: foo bar.com%
before: #narrow/stream/foo.20bar.2Ecom.25
after: #narrow/stream/20-foo-bar.2Ecom.25

For new realms, everything is simple under the new scheme, since
we just parse out the stream id every time to figure out where
to narrow.

For old realms, any old URLs will still work under the new scheme,
assuming the stream hasn't been renamed (and of course old urls
wouldn't have survived stream renaming in the first place).  The one
exception is the hopefully rare case of a stream name starting with
something like "99-" and colliding with another stream whose id is 99.

The way that we enocde the stream name portion of the URL is kind
of unimportant now, since we really only look at the stream id, but
we still want a safe encoding of the name that is mostly human
readable, so we now convert spaces to dashes in the stream name.  Also,
we try to ensure more code on both sides (frontend and backend) calls
common functions to do the encoding.

Fixes #4713
2018-02-19 09:03:11 -08:00
Steve Howell 35cc206dcc Add narrow.narrow_to_next_pm_string().
This helper function will allow us to cycle through PM narrows
that are unread, once we map it to a hotkey and/or other UI.

(We intend to make something like the "n" key for topics, but
that works on PM narrows instead.)
2018-02-12 09:34:59 -08:00
YJDave de13dd41c2 stream narrow: Set message if narrows to never-subscribed private stream.
If user narrows to never-subscribed private stream, display
nonsubbed_private_nonexistent_stream_narrow_message.
2018-01-04 16:52:54 -05:00
Rishi Gupta 191f8f1b39 left sidebar: Change Home to All messages.
We made this change because users often unnecessarily click "Home"
first in their use of Zulip, because it seems appealing.  While "All
messages" isn't quite precise (it doesn't include muted streams), it
does describe relatively simply the interleaved view that this
represents.

This commit leaves everything as "home" in the code, and only changes
user-visible strings and docs. Changing the code will be a big project;
there are hundreds of relevant occurrences in variable names, etc.

Further, we'll probably want to convert those various variable names
in different ways.

Tweaked by tabbott to extend the commit message and update a few comments.
2017-11-28 15:42:58 -08:00
Alena Volkova 5515a075ec urls: Move the report endpoints to be API-style routes. 2017-10-17 22:05:56 -07:00
Tim Abbott 82b708b721 eslint: Add and enforce space-in-parens lint rule. 2017-10-06 12:36:59 -07:00
Cory Lynch 1c0043ea47 Add empty narrow msg for group-pm-with.
Also added test case.
2017-09-24 15:13:58 -04:00
Abhijeet Kaur 2bf3324395 frontend: Add ability to search by "group-pm-with" search operator.
This allows user to view all group private conversation messages
with a specific user. That is, it views all the the group private
messages from groups which include the given user.

Add search suggestion for group-pm-with. Add operator name
and description in "Search operators" tab.

Add change in tab name to "Group Messages" when using this operator.
Add frontend_tests for group-pm-with search operator.

Fixes: #3882.
2017-09-24 11:58:48 -04:00