We have added people.pm_with_url(message), which computes a
PM url from a private message using user ids rather than emails.
We call this in add_message_metadata(), since the slugs will
be valid even if emails change, so we don't need to compute
them on the fly during message rendering.
Currently, searching for group private messages requires typing each
person's email individually. This change improves the typeahead
suggestions for group `pm-with` searches by suggesting additional people
whenever a comma is entered.
Fixes: #3575
Previously, we were incorrectly not updating the data-message-id used
in the .message_reactions section to use the final ID when
echo.reify_id was called.
This meant in particular that if someone else reacted to a message you
sent, and you clicked it to share the reaction, you'd get an exception.
The function people.update_email() is not yet connected
to anything, but it sets the stage for upcoming changes.
When emails get updated, fundamentally we just update
the appropriate person object and add a new key to
people_dict. We sort of get a shim for free--old email
lookups will continue to work--but we add blueslip warnings
for stale lookups.
Now that we have the minified_source_filenames feature, we don't need
to serve zxcvbn from node_modules/ directly to avoid re-minifying it.
Moving this this allows us to stop shipping the (duplicate)
node_modules directory in release tarballs, which will save many
megabytes of unnecessary increase in our release tarball size.
In a96fdd18b1, I introduced a few
regressions related to the blue highlighting that happens
in the top left corner for Home, Private messages, Starred
messages, and @-mentions. Basically, we weren't clearing
the highlighting when we thought we were, so Home would stay
blue too long and the other filters wouldn't turn blue.
We went a surprising long time before noticing the regression.
This fix adds a function called deselect_top_left_corner_items()
to clear the blue backgrounds, so that will happen more explicitly.
And then I restored a line of code to pm_list.js that puts the
blue in place when you are in an is:private narrow (vs. a
specific PM narrow).
When filtering streams, we were incorrectly treating the regexp input
provided by the user as a regular expression, meaning that terms like
`c++` would trigger errors because they are invalid regular expression
syntax. We fix this by replacing RegExp with a simple IndexOf check.
Node test added by tabbott.
Fixes#3559.
The [More...] link for un-collapsing messages has been made easier to
click, by giving it a top margin which prevent clicks on the top
portion of it from being masked by the top part of the message body.
Fixes#3313.
This fixes a number of issues in the prototype /stats graphs, including:
* Adding a Total Users number to the Users graph.
* Changing the Messages sent over time graph so that the bot
trace is hidden by default.
* Fades out the last bars in the weekly view to represent unfinished
ata.
* Sets the default view to weekly only if the realm is > 12 weeks old.
* Gets rid of the tooltips and replaces them with hover text
for the Number of Users graph.
* Fixes a bug in the legend colors for the Messages Over Time
graph.
* It also adds the year to the hover text.
* Sets the pie chart colors and adds spaces between sectors.
* Changes the font to Humbug.
This fixes an issue where Array.prototype.split is called on an
undefined instance due to the EventTarget.oldURL property not being
recorded in IE. We fix this by recording it ourselves.
This adds a frontend for the analytics system we've had for a few
months, showing several graphs of the data in Zulip.
There's a ton more that we can do with this tooling, but this initial
version is enough to provide users with a pretty good experience.
Fixes#2052.
Various server events can be passed into admin.js before
the initial widgets have been set up. This code short
circuits live update code when these events happen.
Note that live updates don't consistently work for the
admin pages before this fix (and after it), since don't
store data changes when the widgets aren't built.
The of stream-search box in left-sidebar was being opened incorrectly
when clicking the + icon to add a new subscription (because that's
what would happen if you clicked the area around the +). Changes were
made in click_handlers.js by adding e.stopPropagation and
e.preventDefault in appropriate click handler.
Fixes#3517.
Currently the loading spinner on the settings page is too small
and is in the left corner of the parent box. This changes the width
to the same as the main page: 100% fill inside a 38px square container.
We now trigger an event in user_events.js, and we dynamically
build the list of names in pm_list.js by calling out to
people.get_recipients().
We have a few variations of functions that build lists of names
for huddles, which should be cleaned up eventually. They are
called at different times in the code path, so the different
functions, while doing mostly the same thing, start with different
data sources.
This breaks the function
message_store.get_private_message_recipient into two functions:
get_pm_emails and get_pm_full_names.
The get_pm_emails function behaves the same way as the original
function, but get_pm_full_names now dynamically gets full names
from people.js using the user_id in the message.display_recipient
row.
This makes the recipient bar show the correct new name if you reload
your page. It doesn't help with live updates.
Note that this only works for people who are currently logged in.
Folks that log in after you may pick up the old full name from
the message. (I'll address this in a separate commit.)
Replaces the hardcoded list of emoji_names and unicode_emoji_names in
static/js/emoji.js with a list generated from emoji_map.json, both to get
the list out of version control and so we can start modifying it for our
autocomplete. This does not change the contents of emoji_names. It sorts and
removes duplicates from unicode_emoji_names (causes no change in behavior,
since unicode_emoji_names is only used as if it were a set).
Previously, if you pressed the escape key with various modals open
(keyboard shortcuts, markdown help, etc.), the modals would close but
also the compose box would close and the user would be unnarrowed.
This changes makes it so all that happens is the modal closes.
Fixes#3472.
This fixes CSS issues such as removing padding with negative margins
and then re-adding padding back later. It also ensures the width of the
picker is exactly six columns wide and does not shift around when zoom
is enabled in the browser.
We now allow spaces and other special characters to be part
of the token (following "#", "@", or ":") that the typeahead
code will further evaluate as a typeahead candidate.
This is important for folks with short/common first names
on larger realms.
We have links when to create a stream to "Click all" or
"Unclick all" for checkboxes.
In FF it's easy to accidentally start dragging these links,
which has no real value (since their href is uninteresting)
and is confusing.
Perhaps these should just be buttons.
This adds a capped height of 70px to the description box (same as the
images) and then uses a gradient to fade out any text that may be near
the bottom.
This changes all references of the data-stream-name to more
predictable data-stream-id references in the subscriptions overlay.
This prevents unescaped characters from breaking selectors and stream
renames from breaking selectors.
This function throttles the function and only allows the on scroll
event to fire the popovers.hide_all() function once on scroll start
(determined as > 250ms after the last scroll event fire on .app.
This should resolve some performance issues surrounding constantly
firing queries and potentially changing the document tree.
Apparently, the updated version of this has a serious scrolling
performance problem in the left sidebar that basically makes scrolling
in that area unusable.
This reverts commit b683b2d3c3.
This change makes it so that when you are creating a stream
and use "Copy from Stream", the UI will immediately
check/uncheck the user checkboxes that correspond to the
stream's subscribers.
In concrete terms this allows Cordelia to create a new
stream call "Paris" that has all the "Verona" subscribers
except for Hamlet.
It also makes it so that when you go to create the stream,
the response is a little quicker, because we don't have to
iterate the streams.
Finally, it removes an odd quirk from the original design,
where if you clicked on Denmark but then collapsed the
streams, we wouldn't actually add the Denmark subscribers
to your new stream.
The current UI will still be slightly intuitive for people, as
I think checkmarks don't really make sense here. What we
really want are Add/Remove links (or buttons) next to each
of the existing streams.
I moved the UI element for "Copy from Stream" to be above
the list of users, including the filter box and check/uncheck
links, which no longer get applied to the list of streams.
The reason I no longer apply the filter to streams is...
* It's kind of confusing to have filters apply to both
streams and users. There should be separate filters for
them, and I will try to resuscitate that feature later.
* The code to filter the streams was doing a sketchy
regex operation against user-inputted data. (`match()`)
* We want to use the same stream filtering code as the
right sidebar uses.
* It improves performance for the common case that you
are filtering users.
The reason I no longer apply the check-all/uncheck-all actions
to streams is that it would be crazy to select all your streams
to copy users from, and it would be expensive/slow for large
realms, and it would likely be done by accident if somebody was
trying to manage individual users.
Finally, the check-all/uncheck-all actions have been scoped
to the users filtered by the text box, so I moved the links
under the text box to make that hopefully more clear to users.
If we blank out the user filter for users (by hitting backspace,
for example), then we now have short-circuit logic to display all
the user checkboxes. (The user-facing behavior doesn't change here,
but now we don't have to process all the strings.)
The function people.filter_by_search_terms() used
to return a JS object with emails as keys to represent
a set of users. Now we return a Zulip Dict() object
with user_ids as keys.
The old implementation was O(N squared) for N = number of
users due to its using an O(N) selector inside of a loop.
Now we simply iterate through all the checkboxes and turn them
on or off based on a bunch of O(1) operations.