Commit Graph

2179 Commits

Author SHA1 Message Date
Anders Kaseorg 52765796c2 dict: Remove Dict.from.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-04 12:22:02 -08:00
Anders Kaseorg 5b824702b4 unread: Replace key_to_bucket Map with Dict/FoldDict/IntDict.
This reverts commit d84646f091 (which
incorrectly assumed in unread_topic_counter that the messages were
present in the message store), while fixing the type confusion problem
by using IntDict for stream_id keys.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-04 12:21:29 -08:00
shubhamgupta2956 aaa30df94c Hotkeys: Change hotkeys behaviour on dropdown open.
Disables message_view_only hotkeys when dropdown menu is opened.

Fixes: #11990
2020-02-03 13:45:07 -08:00
Anders Kaseorg e4259d48a5 dict: Assert that Dict is only used with string keys.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg ad06810501 tests: Replace stream_count, topic_count, html_dict with IntDict.
stream_count and topic_count in the actual code have been IntDict
since commit 9ba1829243 (#13569).

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg ceb37edb55 tests: Avoid _.uniqueId when a number is needed.
_.uniqueId returns a string.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg 052497de1c muting: Replace muted_topics Dict with IntDict.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg 6a0de3bb74 unread: Replace unread_mentions_counter with Set.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg d84646f091 unread: Replace key_to_bucket Dict/FoldDict with Map.
Fixes type confusion in unread_topic_counter, which uses stream IDs as
keys.

Since unread_topic_counter calls message_store.get now, update the
mocks so that message_store.get knows about our mocked messages.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Anders Kaseorg fd9557aa0c unread: Fix {get_msg_ids,num_unread}_for_person type confusion.
These methods take a comma-separated string of user IDs; don’t pass a
number.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-02 20:37:41 -08:00
Tim Abbott df6b90db3c settings: Fix copy-from-clipboard behavior for bot tokens.
We do this by cleaning up the API for generate_zuliprc_content,
allowing us to deduplicate the previously incorrect code.
2020-01-31 15:11:20 -08:00
Vishnu KS d7107f47cd echo: Include sender in display_recipient during PM local insert.
Previously the sender was not included in display_recipient when
a private message was locally echoed. This broke the copy conversation
link functionality, if the user try to copy the link immedeatly after
sending the message. This issue is present only during local echo.
This was fixed by including the recipient of the user during
local echo.

Fixes #13547.
2020-01-31 12:45:14 -08:00
Vishnu KS c0f5915df2 tests: Don't mock people module in echo tests. 2020-01-31 12:45:14 -08:00
Vishnu Ks dde5d1cd4d echo: Extract emails_to_display_recipient function. 2020-01-31 12:45:14 -08:00
Vishnu KS fbd697ee70 tests: Add test for insert_local_message in echo.js. 2020-01-31 12:45:14 -08:00
Vaibhav Raj Singh 1fa46b1963 compose: Improved warning for wildcard mentions.
Edited the warning to clearly state that most members/most stream members
will be notified on using wildcard mentions, along with the specific
mention (e.g. @ALL, @everyone and @stream).

Did a separate check for all wildcard mentions in util.js and stored the
corresponding mention in wildcard_mention inside compose.js.

Fixes: #13636
2020-01-31 12:24:35 -08:00
Pragati Agrawal ffc8042b59 settings_org: Use actual value for value attribute of invite stream policy.
This change is in series of de-duplication of code in "Other permission"
section for various dropdowns.
2020-01-31 12:42:26 +05:30
Pragati Agrawal 1420922705 settings_org: Use actual value for value attribute of create-stream-policy.
For few settings like `waiting_period_threshold` it makes sense to have the
"value" attribute of option to have a value other than the actual setting
value because multiple settings are depending upon this dropdown, so
handling them in JS code makes more sense. But for many settings (which has
integer values), we have followed a wrong trend over the time of
representing every new dropdown with human-readable values and manually
handling them in JS Code, where it makes more sense to use actual setting
value. The result of which is code has become less concise, sensible and
less likely to be mistaken.
2020-01-31 12:42:26 +05:30
Steve Howell 391e08f629 vdom: Support attribute updates.
We don't really need these yet, but we'll want them if we
carry this over to other widgets.  (The PM list never
changes attributes for its `ul`.)
2020-01-30 13:11:32 -08:00
Steve Howell eeee6edf41 pm_list: Simplify redraws for Private Messages.
We now use vdom-ish techniques to track the
list items for the pm list.  When we go to update
the list, we only re-render nodes whose data
has changed, with two exceptions:

    - Obviously, the first time we do a full render.
    - If the keys for the items have changed (i.e.
      a new node has come in or the order has changed),
      we just re-render the whole list.

If the keys are the same since the last re-render, we
only re-render individual items if their data has
changed.

Most of the new code is in these two modules:

    - pm_list_dom.js
    - vdom.js

We remove all of the code in pm_list.js that is
related to updating DOM with unread counts.

For presence updates, we are now *never*
re-rendering the whole list, since presence
updates only change individual line items and
don't affect the keys.  Instead, we just update
any changed elements in place.

The main thing that makes this all work is the
`update` method in `vdom`, which is totally generic
and essentially does a few simple jobs:

    - detect if keys are different
    - just render the whole ul as needed
    - for items that change, do the appropriate
      jQuery to update the item in place

Note that this code seems to play nice with simplebar.

Also, this code continues to use templates to render
the individual list items.

FWIW this code isn't radically different than list_render,
but it's got some key differences:

    - There are fewer bells and whistles in this code.
      Some of the stuff that list_render does is overkill
      for the PM list.

    - This code detects data changes.

Note that the vdom scheme is agnostic about templates;
it simply requires the child nodes to provide a render
method.  (This is similar to list_render, which is also
technically agnostic about rendering, but which also
does use templates in most cases.)

These fixes are somewhat related to #13605, but we
haven't gotten a solid repro on that issue, and
the scrolling issues there may be orthogonal to the
redraws.  But having fewer moving parts here should
help, and we won't get the rug pulled out from under
us on every presence update.

There are two possible extensions to this that are
somewhat overlapping in nature, but can be done
one a time.

    * We can do a deeper vdom approach here that
      gets us away from templates, and just have
      nodes write to an AST.  I have this on another
      branch, but it might be overkill.

    * We can avoid some redraws by detecting where
      keys are moving up and down.  I'm not completely
      sure we need it for the PM list.

If this gets merged, we may want to try similar
things for the stream list, which also does a fairly
complicated mixture of big-hammer re-renders and
surgical updates-in-place (with custom code).

BTW we have 100% line coverage for vdom.js.
2020-01-30 13:11:32 -08:00
Steve Howell a0712ab798 minor: Consolidate vars for max topics.
The two vars here got split apart for temporary
logistical reasons during a recent refactoring.

Now they're just both at the top of
topic_list_data.
2020-01-30 12:15:40 -08:00
Tim Abbott b25fea24e7 messages: Simplify API for use_first_unread_anchor.
Now that we have the type situation of having anchor support passing a
string, this is a much more natural way to implement
use_first_unread_anchor.

We still support the old interface to avoid breaking compatibility
with legacy versions of the mobile apps.
2020-01-29 12:17:03 -08:00
Tim Abbott bf2f36e6b4 message_fetch: Fix load_messages_for_narrow anchor parameter.
This makes the code more readable, by just passing the anchor through
without changing its field name back and forth.

There's no reason for this parameter to involve parsing and integer --
it should be a number in all incoming code paths.
2020-01-29 11:24:58 -08:00
Tim Abbott 6b79448e01 hotkey: Rename confusingly named is_editing_stream_name.
The feature is used for editing stream descriptions as well, and in
any case, what's important is that it's a content-editable widget (aka
a form of input box).
2020-01-29 11:24:58 -08:00
Steve Howell 67a3af4d88 emojis: Make it easier to type smiley icons.
We now give "slight smile" precedence over
"small airplane" if you type "sm".

More generally, we favor popularity over prefix
matches for emoji matches, as long as the popular
emoji matches on any of its pieces.
2020-01-28 12:48:02 -08:00
Steve Howell 345fcd3a69 mobile sharing: Move sort_emojis into typeahead. 2020-01-28 12:48:02 -08:00
Steve Howell 16ae53890b refactor: Move util.prefix_sort to typeahead.triage. 2020-01-28 12:48:02 -08:00
Steve Howell c968be9667 node tests: Add more direct tests for typeahead.
Our legacy unit tests do kind of deep testing; we
want to test get_emoji_matcher more directly.
2020-01-27 16:32:11 -08:00
Steve Howell 4125eb28fd mobile sharing: Extract shared/js/typeahead.js.
This extracts get_emoji_matcher and all the
functions it depended on, most of which were
in composebox_typeahead.js.

We also move remove_diacritics out of the people
module.

This is the first major step for #13728.
2020-01-27 16:32:11 -08:00
Tim Abbott b80f8babcc node tests: Fix test failure in templates.js.
The partially merged code in #13703 was missing required test changes
in the first commit.
2020-01-26 22:52:59 -08:00
Vishnu KS 05b4610381 bots: Remove feedback cross realm bot.
This completes the remaining pieces of removing this missed in
d70e799466 (mostly in tests).
2020-01-25 22:54:44 -08:00
Steve Howell 7d0082f5c2 topic history: Avoid duplicate server fetches.
We now only go the server if both of these
conditions are true:

    - our message data seems incomplete for
      the stream
    - we haven't already fetched history
2020-01-23 13:28:52 -08:00
Steve Howell e812dd60d6 Extract topic_data.is_complete_for_stream_id().
This function will make more sense when we start
tracking api calls that retrieve topic history.

The unit tests here are kinda duplicating what we
have in the stream_data tests.  If we move the
function out of stream_data, we can kill off the
tests there, but for now I think a bit of duplicate
testing is fine here.
2020-01-23 13:28:52 -08:00
Steve Howell f24de074d4 node tests: Get 100% coverage on topic_list_data. 2020-01-22 14:31:33 -08:00
Steve Howell fa82d12525 topic list: Extract topic_list_data.js.
This is mostly for tactical reasons.  It's hard to
get 100% test coverage on topic_list.js, but it
should be easy to get 100% test coverage on this
very important function.

I considered just moving this code into topic_data.js,
but it just didn't feel quite right.  I feel like
this is a pretty core piece of code that's nice
to be by itself and not be near other complicated
code that does stuff like build widgets or talk
to servers.  (And, again, it's not just the actual
code here, which is pretty small, it's the unit
tests, which are inherently verbose to exercise
all the edge cases.)
2020-01-22 14:31:33 -08:00
Steve Howell 588f34e02f node tests: Remove complicated topic_list test.
This test mostly tests how we glue everything
together, but I want to change that in an upcoming
commit.

Also, the data stuff that it tests is now better
covered by the test recent tests I added.
2020-01-22 14:31:33 -08:00
Steve Howell a7a47fc730 node tests: Test muting-related changes.
This test exercises some code from Tim's recent
patch to exclude muted topics from the topic
list.
2020-01-22 14:31:33 -08:00
Steve Howell 6d4c16c8d7 tests: Add coverage for topic_list.get_list_info(). 2020-01-22 14:31:33 -08:00
Steve Howell 613b8ade20 topic list: Add is_active_topic to template.
The only place we ever set active-sub-filter is
right after we build the template, so there is
no reason to have it be a separate step.

(I made a similar fix to pm_list recently, and
this helps set the stage for doing vdom-like
stuff.)
2020-01-22 14:28:50 -08:00
Anders Kaseorg 4341b7b252 user_groups: Convert members from Dict to Set.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-01-16 13:23:47 -08:00
Tim Abbott ef1f6b1c33 filter: Allow marking is:mentioned messages as read.
We may revisit this in the future, but similar to is:private, the
current Zulip user experience makes users expect that in the
is:mentioned view, they should really be able to mark messages as
read.

Further, the practice use case for not marking them as read is very
low, since it's rare for someone to have so many mentions that
revisiting the mentions view isn't sufficient to see everything that
needs their attention.
2020-01-16 11:10:36 -08:00
Tim Abbott 409e320d9d filter: Add streams:public to sorted_term_types.
This is for consistency with in:, has:, and similar values where
there's a fixed set of RHS entries.
2020-01-16 11:05:07 -08:00
Rohitt Vashishtha d4ef50634c filter: Remove is_exactly().
Previously, is_exactly() had already been repalced with can_bucket_by().
This commit removes is_exactly() and replaces its usage in our tests
with can_bucket_by().
2020-01-16 10:54:59 -08:00
Rohitt Vashishtha 8a1299d076 filter: Add 'in:*' to sorted_term_types.
This simplifies our handling of in-home and in-all cases in
can_mark_messages_read().
2020-01-16 10:54:59 -08:00
Steve Howell 316eda071d refactor: Clean up can_mark_messages_read.
We now explicitly enumerate various cases, which
should make it easier to change this code.
2020-01-16 10:54:59 -08:00
Rohitt Vashishtha bb579f8823 unreads: Remove is_reading_mode().
This was a part of an experiment we ran on chat.zulip.org in Jul 2018
and surrounding code that used it never got merged to master.

See: https://chat.zulip.org/#narrow/stream/2-general/topic/un-narrow.20view/near/609506
and c407ba5175.
2020-01-16 10:54:59 -08:00
Steve Howell 741da61407 node: Flatten pm_list testing code a bit.
The `messages` part of the data is going away in
the next commits.  This pre-factoring just makes
the next diff a bit more clean.
2020-01-16 10:32:36 -08:00
Steve Howell aea369f878 Refine user-related typeahead results for large realms.
We now incorporate people.get_message_people() in our
logic for compose/PM typeaheads.  This not only gives
users better results in some cases, but it will also
improve performance for large realms in some cases.
2020-01-15 12:22:23 -08:00
Steve Howell 9ed5545abb Add test coverage for filter_and_sort_mentions.
A recent commit removed test coverage for the
actual filtering/sorting of mention typeaheads
when you did a non-silent method.  This commit
now tests that important step again.

Note that we also had (and still have) tests
that make sure the is_silent flag is set
correctly by get_candidates.

We don't have a true full-stack test, but those
can be quite tricky to set up and maintain.
2020-01-15 12:22:23 -08:00
Steve Howell e1213ca30a minor: Add person/group to composebox_typeahead tests. 2020-01-15 12:22:23 -08:00
Steve Howell 0aa9decd86 blueslip: Add feature to time common operations.
This is relatively unobtrusive, and we don't send
anything to the server.

But any user can now enter blueslip.timings in the
console to see a map of how long things take in
milliseconds.  We only record one timing per
event label (i.e. the most recent).

It's pretty easy to test this by just clicking
around.  For 300 users/streams most things are
fast except for:

    - initialize_everything
    - manage streams (render_subscriptions)

Both do lots of nontrivial work, although
"manage streams" is a bit surprising, since
we're only measuring how long to build the
HTML from the templates (whereas the real
time is probably browser rendering costs).
2020-01-15 12:01:16 -08:00
Steve Howell 890a4b1247 refactor: Add filterer for user settings.
This change sets us up to optimize how we
filter users in the admin user settings.
See #13554 for more context on the user
facing issues.

This fix is basically three related things:

    - Add filterer options to list_render.
    - Add helper method to people.js.
    - Use filterer in settings_users.js.
2020-01-14 22:43:08 -08:00
Steve Howell 110c15737f Rename filter.callback to filter.predicate.
The filter "callback" was only a "callback" in the
most general sense of the word.

It's just a filter predicate that returns a bool.

This is to prepare for another filtering option,
where the caller can filter the whole list
themselves.  I haven't figured out what I will name
the new option yet, but I know I want to make the
two options have specific names.
2020-01-14 22:43:08 -08:00
Steve Howell 3f3b9c3b70 list_render: Make callbacks required.
We are already providing callbacks everywhere, so
it would be nice to eliminate some dead code.

This also speeds things up ever so slightly (no
longer type-checking the option every time through
the loop).

We also split out exports.filter to make unit testing
easier.  The function seems kinda silly now, being so
small, but I hope to add another filtering option soon.
2020-01-14 22:43:08 -08:00
Anders Kaseorg ea6934c26d dependencies: Remove WebSockets system for sending messages.
Zulip has had a small use of WebSockets (specifically, for the code
path of sending messages, via the webapp only) since ~2013.  We
originally added this use of WebSockets in the hope that the latency
benefits of doing so would allow us to avoid implementing a markdown
local echo; they were not.  Further, HTTP/2 may have eliminated the
latency difference we hoped to exploit by using WebSockets in any
case.

While we’d originally imagined using WebSockets for other endpoints,
there was never a good justification for moving more components to the
WebSockets system.

This WebSockets code path had a lot of downsides/complexity,
including:

* The messy hack involving constructing an emulated request object to
  hook into doing Django requests.
* The `message_senders` queue processor system, which increases RAM
  needs and must be provisioned independently from the rest of the
  server).
* A duplicate check_send_receive_time Nagios test specific to
  WebSockets.
* The requirement for users to have their firewalls/NATs allow
  WebSocket connections, and a setting to disable them for networks
  where WebSockets don’t work.
* Dependencies on the SockJS family of libraries, which has at times
  been poorly maintained, and periodically throws random JavaScript
  exceptions in our production environments without a deep enough
  traceback to effectively investigate.
* A total of about 1600 lines of our code related to the feature.
* Increased load on the Tornado system, especially around a Zulip
  server restart, and especially for large installations like
  zulipchat.com, resulting in extra delay before messages can be sent
  again.

As detailed in
https://github.com/zulip/zulip/pull/12862#issuecomment-536152397, it
appears that removing WebSockets moderately increases the time it
takes for the `send_message` API query to return from the server, but
does not significantly change the time between when a message is sent
and when it is received by clients.  We don’t understand the reason
for that change (suggesting the possibility of a measurement error),
and even if it is a real change, we consider that potential small
latency regression to be acceptable.

If we later want WebSockets, we’ll likely want to just use Django
Channels.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-01-14 22:34:00 -08:00
Pragati Agrawal 48b6734b73 org settings: Minor refactor to add notification stream id data in widget.
As the part of making notification stream settings to change using
"save/discard" widget instead of immediate saving, we need to access the
stream id which is being selected at the moment.
2020-01-14 17:16:23 -08:00
Pragati Agrawal e7c40f69de org settings: Remove old method of success status for notification streams.
For "New stream notifications" and "New user notifications" it is more
intuitive to just use the new system for showing success/saving status
feedback.
2020-01-14 17:16:23 -08:00
Steve Howell 29e63c0417 Fix type errors in LazySet.
I think the only place that was broken is where
we copy users from streams.
2020-01-14 15:40:40 -08:00
Steve Howell c2af2c1fd1 refactor: Extract is_subscriber_subset().
Extracting the function makes it a bit easier to
test and use in a generic way.

Also, I wanted this to live in stream_data, so that
it's easier to find if we change how we model
subscriber data.

Finally, I use _.every to do the subset check
instead of `_.difference`, since _.difference
is actually N-squared:

  _.difference = restArguments(function(array, rest) {
    rest = flatten(rest, true, true);
    return _.filter(array, function(value){
      return !_.contains(rest, value);
    });
  });

And we don't actually want to build a list only
to check that it's zero vs. nonzero length.

We now do this, which short circuits as soon
as it finds any key that is only in sub1:

    return _.every(sub1.subscribers.keys(), (key) => {
        return sub2_set.has(key);
    });
2020-01-14 13:19:49 -08:00
Steve Howell 34b21bc0ee refactor: Use is_broadcast flag for mention check.
I also clean up the noop tests here, which were
actually redundant (all three cases were short
circuiting on the "everyone" mention).
2020-01-14 13:19:49 -08:00
Steve Howell e638361728 minor: Move unit test to module scope.
This test is really no longer an "event" test.
2020-01-14 13:19:49 -08:00
Steve Howell 593049d551 compose: Extract warn_if_mentioning_unsubscribed_user.
First, there are no more convoluted signals.

We also simplify the parameter to just the "mentioned"
object corresponding to either a user or a broadcast
mention.

For the user group scenario, this has always been dead
code, which you only realized when you got to the comment
at the bottom.  Now we actually do nothing.
And I moved the relevant commment to the
the typeahead code (with new wording).

I also moved the is_silent check to the caller.  I don't
feel too strongly about that either way. It's kind of silly
to call a function only to give that function an additional
responsibility to worry about.  On the other hand, I see
the logic of that function enforcing everything.  I went
with the former for now.

Arguably we should have a warning for silent mentions,
since doing a silent mention of somebody not on a stream
is a good indication of a typo.  I do understand the use
case, but the user can always ignore the warning.  Anyway,
we have decent test coverage on this.
2020-01-14 13:19:45 -08:00
Steve Howell b91a19df43 refactor: Extract warn_if_private_stream_is_linked.
This isn't really an extraction; it's more giving
a name to an anonymous function and moving it to
higher module scope.

We convert this to an ordinary function call, which
allows us to move it out of intialize().

Since there's just one simple parameter now (linked_stream),
we can avoid some error checking.

We also avoid the comment that describes the function,
since it now has a name.

And then one minor tweak is to do the inexpensive
`invite_only` higher in the function.  This will be
a nice speedup when you link to really large public
streams.

The unit tests are also a bit easier to read now--less
setup and more explicit names.
2020-01-14 13:13:48 -08:00
Steve Howell 9f590889b7 refactor: Use a Set for away_user_ids. 2020-01-14 17:52:25 +00:00
Tlazypanda 30ee0c2a49 invitations: Improve experience around reactivating users.
Previously, if you tried to invite a user whose account had been
deactivated, we didn't provide a clear path forward for reactivating
the users, which was confusing.

We fix this by plumbing through to the frontend the information that
there is an existing user account with that email address in this
organization, but that it's deactivated.  For administrators, we
provide a link for how to reactivate the user.

Fixes #8144.
2020-01-13 18:30:51 -08:00
Steve Howell 15e7f5828b performance: Improve sort_recipients.
The sort_recipients helper is used for many different
typeaheads, such as compose PMs, compose mentions,
and some settings-related code.

We now avoid unnecessary sorting steps in cases
where we have plenty of results in the top buckets
(such as users who match on prefix).

This change should not have any user-facing
implications.
2020-01-12 20:53:03 -08:00
Steve Howell 9830d0a4c7 typeahead: Remove get_person_or_user_group_matcher.
We no longer need this, because we now filter
persons and groups separately.
2020-01-12 20:52:59 -08:00
Steve Howell bbb8abf4c5 typeahead: Extract composebox_typeahead.get_person_suggestions.
This method is a bit complex, but I think it's
worthwhile to force PM autocompletes and mention
autocompletes through the same code path.

We also kill off this method:

    typeahead_helper.sort_people_and_user_groups
2020-01-12 20:52:57 -08:00
Steve Howell 8fb9820b40 typeahead: Extract filter_and_sort_mentions.
We want a bit more control over the logic here.

The end game here is to converge a bit with
the code for autocompleting PM recipients.
2020-01-12 20:52:53 -08:00
Steve Howell 95daa50954 pm_list: Simplify is_all_privates logic.
For historical reasons pm_list was handling just
one possible edge case of where is:private was
combined with other search terms, namely the
pm-with operator.

The code was correct in realizing the is:private
was redundant there, but now we handle that
upstream in Filter.fix_operators (see previous
commit).

Now we just look for any is:private term.
2020-01-09 17:46:03 -08:00
Steve Howell 1af41dd954 filter: Remove redundant is:private operators.
If we have a pm-with, then is:private is redundant
and just forces us to write confusing/verbose code
in various places.
2020-01-09 17:46:03 -08:00
Steve Howell 4a03f91daa search: Retrofit recent changes to pills code.
This change makes these two functions more alike:

    - get_search_result
    - get_search_result_legacy

To test the UI modify zerver/views/home.py by
replacing `settings.SEARCH_PILLS_ENABLED` with
`True`.  I only did a quick sanity check, since
any bugs with the new system are more likely due
to bitrot than any changes I have made here.

The history is this:

    Tim cloned the code (before the smaller
    helpers were extracted):

        db4f6e278f

    In 8b153f6452
    Shubham removed get_operator_subset_suggestions but
    accidentally left a `concat` statement in that got
    misapplied to the previous suggestions:

    -    suggestions = get_operator_subset_suggestions(operators);
         result = result.concat(suggestions);

    The error there was carried over in some recent changes,
    but this commit fixes that strangeness.

    In 73e4f3b3fa
    Shubham made this change, which makes sense only for
    pills, and this code remains intact.

        -    if (operators.length > 0) {
        -        last = operators.slice(-1)[0];
        +    if (query_operators.length > 0) {
        +        last = query_operators.slice(-1)[0];
        +    } else {
        +        // If query_operators = [] then last will remain
        +        // {operator: '', operand: '', negated: false}; from above.
        +        // `last` has not yet been added to operators/query_operators.
        +        // The code below adds last to operators/query_operators
        +        operators.push(last);
        +        query_operators.push(last);
             }

    Mohit made a couple changes to both old and new.

    Anders made a couple non-substantive changes related to
    the ES6 migration.

    Steve (me) made several structural changes to the code.  For
    some of them I only changed the legacy code, not the pills
    code.  I didn't fix Shubham's mistake until this change.

Now the two functions should look similar except in the places
where they are intentionally different.  I also added a comment
explaining the get_operator_subset_suggestions difference.

Fixes #13609
2020-01-08 14:02:34 -08:00
Steve Howell f47f27d110 refactor: Use filter_taken_users in compose typeahead.
The composebox_typeahead code now gets people directly,
which will allow us to do some optimizations upcoming.
2020-01-08 12:55:42 -08:00
Steve Howell 94761b806c node tests: Restore 100% coverage to pm_list. 2020-01-06 10:21:23 -08:00
Steve Howell c22c796f1d refactor: Extract is_all_privates().
I want to be able to easily test this without
having to simulate all the jQuery side effects.

This simply preserves the old logic, which seems
to handle one edge case without handling every
possible edge case.  The edge cases aren't super
important here, though, since the only thing it affects
is bolding "Private Messages", and when to do that
is somewhat up to personal tastes.

Having said that, we could definitely improve
this code and possibly should move some of this
logic to either narrow_state.js or filter.js.
2020-01-06 10:21:23 -08:00
Steve Howell 5b168d0530 pm_list: Set active-sub-filter in template.
Instead of doing various ad-hoc calculations of
which PM is "active" and plumbing it through various
functions and then updating it via jQuery instead of
just the template, we now just calculate `is_active`
in `_build_private_messages_list` with a little
helper function.
2020-01-06 10:21:23 -08:00
Steve Howell da1392efd2 node test: Remove complicated pm_list test.
This test mostly tests logic that I'm about
to remove in subsequent commits, and it's a bit
messy.

This commit removes 100% line coverage, but I
will restore that a few commits later.
2020-01-06 10:21:23 -08:00
Steve Howell 066a02a987 pm_list: Remove obsolete active_conversation parameter.
In 3cfc3ca24b I removed
the feature that limited PM conversations to five or
less (including the active conversation), but I
didn't clean up this parameter.  I think lint was
confused by the fact that we did mutate it.

I am wondering if this started out as an experiment
and was never fully polished before the push?  Or
maybe I was just careless.  Anyway, I don't
think were any symptoms here--it was just dead code
that we didn't need.
2020-01-06 10:21:23 -08:00
Tim Abbott 9f72e5fc87 int_dict: Move filter_values helper to dict.
This fixes a rebase issue between the int_dict introduction and use
for people.js with the introduce of filter_values on dict.js and use
inside people.js.
2020-01-05 13:18:34 -08:00
Steve Howell 493afcb9f0 zjsquery: Add data support.
Before this we just noop'ed it, since at one time
we were trying to deprecate this is in favor
of attr calls.
2020-01-05 12:28:37 -08:00
Steve Howell 9ba1829243 streams: Use IntDict for stream/topic unread counts.
Note that we haven't fully swept this for Dict,
since some dicts are keyed by strings.  For
example PM counts can have a huddle like
"101,102,103" as a key.
2020-01-05 12:28:34 -08:00
Steve Howell 9f7be51ce8 streams: Replace Dict with IntDict in stream_data.
There's another Dict that we'll convert to a Set
in a subsequent commit.
2020-01-05 12:28:28 -08:00
Steve Howell 73d0350a24 people: Use ints in is_my_user_id().
This should be slightly more performant, and we
often call this function N times, such as when
rendering the buddy list.

There's a minor change to pm_list to avoid
an unnecessary computation on huddles that would
otherwise trigger a blueslip warning for the
huddles case.
2020-01-05 12:28:23 -08:00
Steve Howell bc5589c2a7 people: Clean up recip.id code.
When we are pulling data from message.display_recipient
for private messages, the user_id field is always
called 'id', not 'user_id', so we can simplify
some defensive code.
2020-01-05 12:27:30 -08:00
Steve Howell 7630b859c3 js: Use IntDict in people.js.
This required lots of manual testing:

    - search/navigate user presence
    - send PM and mention user
    - pay attention to compose fade
    - send stream msg and mention user
    - open Private Messages in top-left and click
    - test unread counts
    - invite user who already has account
    - search for users in search bar
    - check user settings
        - User Groups
        - Users
        - Deactivated Users
        - Bots
    - create a bot
    - mention user groups
    - send group PM then click on lower right
    - view/edit/create streams

If there are still pieces of code that don't convert
ids to ints, the code should still work but report
blueslip errors.

I try to mostly convert user_ids to ints in the callers,
since often the callers are dealing with small amounts
of data, like user ids from huddles.
2020-01-05 12:27:28 -08:00
Steve Howell 4e59937632 js: Add IntDict class.
We don't use this yet, but we will soon.

We report errors if users pass in strings instead of
ints, but we try to still use the key.
2020-01-05 12:27:26 -08:00
Steve Howell 26168eaa98 search: Optimize search bar suggestions for large realms.
We only ever show 3 or 4 people in search suggestions
(possibly w/a couple variations, like pm-with/sender/etc.),
so we can try to search a smaller subset of people
before going through the entire realm.

We use message_store.user_ids() for this, since you
typically want to search messages for people that
have sent messages recently, and we already sort
based on PM conversations.
2020-01-04 12:58:00 -08:00
Steve Howell 7016292558 search: Track user_ids in message_store.
We'll use this for search.
2020-01-04 12:57:58 -08:00
Steve Howell d87c5d7b1f search: Use people.filter_all_persons() in search.
This should avoid some memory allocations.

We also use build_person_matcher to avoid
repeating the same logic over and over
again to process the query into termlets.

We also remove people.get_all_persons() and
people.person_matches_query().
2020-01-04 12:53:32 -08:00
Steve Howell 7d7028b7d0 performance: Speed up PM lookaheads.
This looks like simple code cleanup, but it's more
than that.

The code cleanup here is that we don't have three
callbacks to get a list of typeaheads for bootstrap.
Instead, we just have one function that does all the
main work.

And then the speedup comes from the fact we no longer
need to remove diacritics from the query for every
time through our loop of seeing if a person matches
the query.

It's a bit subtle to see in the diff, but these are
the relevant lines:

    const matcher = exports.get_person_or_user_group_matcher(query);
    const filtered_results = _.filter(people_and_groups, matcher);

Before this, bootstrap was doing $.grep, and we'd have
to reinitialize the matcher for every person.

If you profile this before and after, you'll see that
remove_diacritics gets called fewer times.

To profile this, you want to loads lots of users into
your DB and try to autocomplete "Extra", as in "Extra1 User".

If you try to autocomplete something else, then my patch
won't really help, and `remove_diacritics` will still
show up as expensive.  Because it is that expensive a function.
2020-01-03 17:42:29 -08:00
Steve Howell ccf6640660 refactor: Have compose_content_matcher return a function.
This may seem silly now, since we are returning a function
that still dispatches over all flavors of search for
every item, but subsequent commits will make it obvious
why I'm doing this.
2020-01-03 17:39:50 -08:00
Steve Howell b65da7cbe9 compose typeahead: Do matching/sorting without callbacks.
We want to do our own matching of items, rather than
just giving a callback to bootstrap, which does $.grep
on all the items.

Doing our own matching gives us flexibility for future
improvements like custom data structures for searching
through big amounts of data.  Even in the short term
we can speed up searches by pulling expensive operations
outside the grep/filter call.

This architecture has been in place for our search
bar since ~2014.
2020-01-03 17:39:48 -08:00
Steve Howell 9afad9e054 node tests: Add commented-out benchmarks for Dict.
The benchmark is commented out.  It takes only a few
milliseconds to run, so there may be no reason not
to always run it.  It doesn't test correctness, so
it would arguably inflate line coverage, but set/get
are obviously covered elsewhere.
2020-01-03 17:19:59 -08:00
Steve Howell 30ad1b6f16 zjsunit: Remove Dict dependency.
We now require the actual tests to explicitly
to zrequire Dict, rather than magically adding this.

In one case, the use of Dict was clearly just for
the test (not the app), so I converted that an ordinary
JS object (see timerender.js).
2020-01-03 17:19:59 -08:00
Steve Howell ee3e488e02 js: Extract FoldDict class.
We have ~5 years of proof that we'll probably never
extend Dict with more options.

Breaking the classes into makes both a little faster
(no options to check), and we remove some options
in FoldDict that are never used (from/from_array).

A possible next step is to fine-tune the Dict to use
Map internally.

Note that the TypeScript types for FoldDict are now
more specific (requiring string keys).  Of course,
this isn't really enforced until we convert other
modules to TS.
2020-01-03 17:19:50 -08:00
Steve Howell b3a69154a6 refactor: Export compare_for_relevance.
This future-proofs us a bit more for test coverage.
2020-01-03 14:58:05 -08:00
Steve Howell 0985842c62 Fix sorting for broadcast mentions.
We had a potentially nasty bug where we
weren't guaranteeing that all/stream/everyone
collated in consistent ways inside of
`compare_people_for_relevance`, which can
send certain types of sort algorithms into
an infinite loop. I doubt this ever happened
in practice, but it's obviously worth fixing.

Now we also have a clear tiebreaker between
any two all/everyone/stream mentions, which
is the idx field.

Finally, this should be a bit more efficient.
2020-01-03 14:58:05 -08:00
Steve Howell 758786ab87 refactor: Extract broadcast_mentions.
This will be helpful for testing.
2020-01-03 14:58:05 -08:00
Steve Howell 773161cbb7 tests: Test "all" mentions more realistically.
We don't have people named "all".  Instead, we
create pseudo person objects with email/full_name
of "all" (along with some other fields).  The tests
now reflect this.
2020-01-03 14:58:05 -08:00
Steve Howell d227988519 tests: Split up sort_recipient tests. 2020-01-03 14:58:05 -08:00