When we populate the buddy list or update it for activity, we now
have buddy_data set a faded flag that is rendered in the template.
This avoids some re-rendering overhead and is on the eventual path
to having our widget be more data-oriented (and all rendering happens
"behind" the widget).
We still do direct DOM updates when the compose state changes or
when we get peer subscription events.
This introduces a generic class called list_cursor to handle the
main details of navigating the buddy list and wires it into
activity.js. It replaces some fairly complicated code that
was coupled to stream_list and used lots of jQuery.
The new code interacts with the buddy_list API instead of jQuery
directly. It also persists the key across redraws, so we don't
lose our place when a focus ping happens or we type more characters.
Note that we no longer cycle to the top when we hit the bottom, or
vice versa. Cycling can be kind of an anti-feature when you want to
just lay on the arrow keys until they hit the end.
The changes to stream_list.js here do not affect the left sidebar;
they only remove code that was used for the right sidebar.
This was a bit more than moving code. I extracted the
following things:
$widget (and three helper methods)
$input
text()
empty()
expand_column
close_widget
activity.clear_highlight
There was a minor bug before this commit, where we were inconsistent
about trimming spaces. The introduction of text() and empty() should
prevent bugs where users type the space bar into search.
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.
This change makes a common code path for these two operations:
* clicking on a user
* hitting enter when a user is highlighted
The newer codepath, for the enter key, had some differences that
were just confusing. For example, there's no need to open the
compose box, since that's already handled by the narrowing code.
For possibly dubious reasons, I let each handler still call
popovers.hide_all() on its own, since it makes the code a bit
more consistent with existing code patterns.
This brings the right sidebar UI to match the similar widget in the
left sidebar. Since there's no other plausible effect for a click in
this whitespace, this small tweak should make using Zulip a bit more
convenient.
Fixes#8161.
The function name `get_realm_human_user_ids` was a lie--it
includes active bots as well.
The only user of this function is `activity.js`, which wasn't
impacted by the misleading name, because we eventually filter
out bots in the `info_for` function.
It's possible that we actually want to include bots in the right
sidebar, since they can be difficult to discover in other parts
of the UI. Or, if we want to keep the right sidebar as all
human users, we may eventually want to make the logic to exclude
bots happen higher in the stack (but for real, this time).
We sometimes get blueslip errors from browsers that are clearly still
attempting to reload long after they should have. These browsers can
produce a lot of unnecessary presence update exceptions.
To solve that, we start checking reload_in_progress in the presence
code path.
While we're at it, we also add some blueslip logging for the reload
code path, in case it becomes useful when debugging future issues.
This function was extracted from build_user_sidebar(). We
also slightly streamlined it to not unnecessarily call
filter() when the filter text was blank. This extraction
also eliminated the need for us to have the two-line
filter_and_sort() function.
Also, we get to 100% coverage in this commit.
We now intialize user-list-filter within activity.initialize(),
which gives us more control to set the module variable
`meta.$user_list_filter` before we build the user sidebar,
while setting up its handlers after we build the sidebar.
This will look through all users and not just ones active in the last
three weeks but only when you are searching with the right sidebar
input box.
Fixes: #5775.
The sidebar selectors may not exist at a particular point on load but
we’d like to realistically cache the results once they are, so we try
to load them live until we know that a valid selector has been found.
This call to update the users scrollbar is inside a huddles update
method which should only affect the group PMs, so we can remove the
update function.
The `exports.build_user_sidebar` method already calls the resize
function, so there’s no need to call it again or wrap it in the
`actually_update_users_for_search` method.
This adds the perfectScrollbar to the right side and theoretically
updates it any time a piece of code interacts with the sidebar and
updates the counts of users displayed in it.
This function no longer sets properties to false, so the supported
way of doing this is to instead use prop(foo, false). Some tests
had to be fixed to accommodate this.
This commit de-couples the PM code from Group code. It also
simplified some code related to finding parent elements by
both introducing local variables and removing unnecessary
selectors.
This is the first part of handling an annoying race that would cause
us to try drawing the right sidebar using (in part) users that we
haven't learned about yet (because we were offline/suspended when they
were created, and we haven't quite realized our event queue is gone yet).
The web app doesn't need any presence data for its first ping to
the server, because it already has up-to-date presence info in
page_params. So now we can tell the server not to send us a big
payload that we were already ignoring.
Most of this code was simply moved from activity.js with some
minor renaming of functions like set_presence_info -> set_info.
Some functions were slightly nontrivial extractions:
is_not_offline:
came from activity.huddle_fraction_present
get_status/get_mobile:
simple getters
set_user_status:
partial extraction from activity.set_user_status
last_active_date:
pulled out of admin.js code
We also fixed activity.filter_and_sort to take user_ids.
This was regressed in 89e17e1aee.
At least one of the symptoms was that we weren't updating the
activity list properly. This could also cause tracebacks in
compose fade logic.
We now correctly pass the list item for a user to the function
compose_fade.update_one_row().
This regression started happening in the recent commit of
eece725073. Before that commit,
compose-fade was broken in a different way.
Testing this fix requires creating a stream and opening the compose
box in one window. Then, in the other window, have a user not
subscribed to the stream log on for the first time. Be careful
to make sure you flip back to the other browser tab quickly, and
you should see the new user grayed out. (You can get a false
positive if you wait too long, because the periodic update was
correctly fading before this fix.)
Introducing the level function makes it a bit more clear that active
users get sorted to the top.
It also shaves a couple milliseconds for large buddy lists, although
that is mostly negligible compared to name sorting and rendering.
It's easier to reason about the activity.js code if we just
make it clear that presence_info is a global singleton. Going
forward, functions that use that data will explicitly refer to
exports.presence_info.
This change makes some tests slightly more awkward to set up, but
with the actual code you now don't have to question whether there
are multiple copies of presence_info to maintain.
The diff for compare_function is a bit confusing to read, but it's
basically just de-dented since we don't need to parameterize the
compare function any more.
The function focus_lost() was setting has_focus to false
in all cases; now it does it more clearly. I also added a
comment explaining why we don't ping on losing focus.
We no longer build the buddy list twice during page load; we
build it just once from page_params information. (We also send
the initial ping and schedule subsequent pings slightly later in
the process.)
We also don't do redraws upon regaining focus, since we don't
show ourselves in the buddy list, and even if we did, we wouldn't
need a full server update.
To have this flexibility, we introduce the want_redraw flag to
focus_ping.