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.
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.
We want to mostly deprecate this function (see
the comment I added), so I gave it a more specific
name.
Ideally I'd just fix `stream_create`, but it does
use this function in a couple places, and it's helpful
to reuse the same sort here. In one place stream_create
actually unshifts the "me" user back to the top of the
list, which makes sense for its use case.
If two user_ids in a recent huddle have ids
that sort lexically differently than numerically,
such as 7 and 66, then we were creating two
different buckets in pm_conversations.
This regression was introduced in
263ac0eb45 on
November 21, 2019.
Instead of having our callers pass in a possibly
non-canonical version of a user_ids_string, just
have them pass in a list.
The next commit will canonicalize the sort.
The server may send us ids in the order
[11, 2], instead of [2, 11]. We don't want
to rely on server behavior, regardless, for
the sort.
Our tests now show we process that data.
The current code is is still buggy and causes
us to show the same huddle two different times
for situations where the lexical sort doesn't
match the numerical sort.
This happens on czo often, where Tim is user
7, and his id sorts lexically after ids like
58, 622, 4444, etc.
This should make any operation on subscribed
streams faster (we won't need to filter out
unsubscribed streams every time).
I started writing this before I realized we
had a bug where we call `subscribed_streams`
in a nested loop.
After fixing the bugs, this is not as much of
a bottleneck, but it's still a speedup in many
important places:
* build left sidebar
* every keystroke in search bar
* first keystroke in making #stream_links
* every keystroke in compose stream box
The streams settings code is kinda complicated.
It does a non-deterministic sort of the "others"
bucket when you add elements to the left panel.
They get hidden, anyway. Our values() call now
puts subscribed streams first. It never guaranteed
order, but putting subscribed streams first is
probably a good behavior for most situations.
This defers O(N*S) operations, where
N = number of streams
S = number of subscribers per stream
In many cases we never do an O(N) operation on
a stream. Exceptions include:
- checking stream links from the compose box
- editing a stream
- adding members to a newly added stream
An operation that used to be O(N)--computing
the number of subscribers--is now O(1), and we
don't even pay O(N) on a one-time basis to
compute it (not counting the cost to build the
array from JSON, but we have to do that).
Calling `set_filter_out_inactives` is expensive, since we
count up the number of subscribed streams, which iterates
through all your streams, creates a new list of subscribed
streams, then counts them.
In my dev setup, I created 700 streams, and this shaved
about 700ms off of the initial call to `build_stream_list`.
If we aren't showing users emails, then we don't
want to use emails in the search.
And if we are showing users emails, we want to
search on the email that's displayed to them.
For admins this will be delivery_email.
For regular users we arguably shouldn't search
on emails either, since it mostly causes confusion,
but this commit just preserves the current
behavior for those users (unless `show_email` is
false).
We want to be able to unit test this value,
since it's conditional on several factors:
- am I an admin?
- can non-admins view emails?
- do we have delivery_email for the user?
I'm mocking show_email in the tests, since the
show_email code is in `settings_org` and
kind of hard to unit test. It's not impossible,
but it's too much for this commit. (Either
we need to extract it out to a nice file or
deal with mocking jQuery. That module is
mostly data-oriented, so it would be nice
to have something like `settings_config` that
is actually pure data.)
This was duplicate code. I'm moving it to people
for pragmatic reasons--it's hard to unit test stuff
in settings_users.js due to all the jQuery.
It's also nice to have all people-related search
code in one place, just for auditing purposes.
Once we have max_items results, stop trying
to get more items.
This should really help large realms when
you do a search on streams that turns up
more than N streams (where N is about 12).
We won't even bother to find people.
This isn't a huge speedup, but it's an easy
code change.
We remove the two-liner highlight_with_escaping,
which was only called in one place, and when
we inline it into the caller, we can pull the
first line, which builds the regex, out of the
loop.
The streams:all adveritsement notice in search should only appear
after we've already received the response from the server, to avoid a
mix of problems ranging from misplaced loading indicator to scrolling
issues to the notice just being distracting while you're waiting for
the server to return results.
We need to add a pre_scroll_cont parameter to the message_fetch API,
since adding this notice would otherwise potentially throw off the
scroll positioning logic for which message to select.
Fixes#13441.
In 452e226ea2 and
648a60baf6, we changed how `search:`
narrows work to:
(1) Never mark messages as read inside searches (search:)
(2) Take you to the bottom, not the first unread, if a `near:` or
similar wasn't specified.
This is far better behavior for these use cases, because in these
narrows, you can't actually see all the context around the target
messages, so marking them as read is counterproductive. This is
especially important in `has:mention` where you goal is likely
specifically to keep track of which threads mentioning you haven't
been read. But in many other narrows, the current behavior is
effectively (1) setting the read bit on random messages and (2) if the
search term matches many messages in a muted stream with 1000s of
unreads, making it hard or impossible to find recent search matches.
The new behavior is that any narrow that is structurally a search of
history (including everything that that isn't a stream, topic,
pm-with, "all messages" or "private messages") gets that new behavior
of being unable to mark messages as read and narrows taking you to the
latest matching messages.
A few corner cases of interest:
* `is:private` is keeping the old behavior, because users on
chat.zulip.org found it confusing for `is:private` to not mark
messages as read when one could see them all. Possibly a more
complex answer is required here.
* `near:` narrows are getting the new behavior, even if it's a stream:
+ topic: narrow. This is debatable, but is probably better than
what was happening before.
Modified significantly by tabbott for cleanliness of implementation,
this commit message, and unit tests.
Fixes#9893. Follow-up to #12556.
In 1fe4f795af, we added the
wildcard_mentions_notify setting, which controls whether wildcard
mentions should be treated as mentions for the purposes of
notifications. The original implementation focused on the more
important area of email/push notifications, and neglected to address
desktop notifications for wildcard mentions.
This change makes the wildcard_mentions_notify flag behave correctly
for desktop/sound notifications, including unit tests.
Fixes#13073.
Adds required API and front-end changes to modify and read the
wildcard_mentions_notify field in the Subscription model.
It includes front-end code to add the setting to the user's "manage
streams" page. This setting will be greyed out when a stream is muted.
The PR also includes back-end code to add the setting the initial state of
a subscription.
New automated tests were added for the API, events system and front-end.
In manual testing, we checked that modifying the setting in the front end
persisted the change in the Subscription model. We noticed the notifications
were not behaving exactly as expected in manual testing; see
https://github.com/zulip/zulip/issues/13073#issuecomment-560263081 .
Tweaked by tabbott to fix real-time synchronization issues.
Fixes: #13429.
If a message begins with /me, we do not have any cases where the
rendered content would not begin with `<p>/me`. Thus, we can safely
remove the redundant checks both on the backend and frontend.
In e42c3f7418, we made the assumption
that compose_pm_pill.get_recipient() would return no users for stream
messages. It turns out, due to the confusing name of
compose_state.recipient (which we just renamed to
compose_state.private_message_recipient), this assumption was wrong.
As a result, when composing a stream message using the reply hotkeys,
we'd end up sending typing notiifcations to the person who sent the
message we're replying to as though a PM was being composed.
We fix this by avoiding passing an (expected to be unused) value for
private_message_recipient to compose_state.start.
The compose_state.recipient field was only actually the recipient for
the message if it was a private_message_recipient (in the sense of
other code); we store the stream in compose_state.stream instead.
As a result, the name was quite confusing, resulting in the
possibility of problematic correctness bugs where code assumes this
field has a valid value for stream messages. Fix this by changing it
to compose_state.private_message_recipient for clarity.
Fixes commit id 648a60baf6. When
allow_use_first_unread_when_narrowing() is false last message of
narrow is shown in view.
Comments rewritten by tabbott to explain in detail what's happening.
This simple change switches us to take advantage of the
server-maintained data for the pm_conversations system we implemented
originally for mobile use.
This should make it a lot more convenient to find historical private
message conversations, since one can effectively scroll infinitely
into the history.
We'll need to do some profiling of the backend after this is deployed
in production; it's possible we'll need to add some database indexes,
denormalization, or other optimizations to avoid making loading the
Zulip app significantly slower.
Fixes#12502.
message_id, rather than timestamps, is our standard way to sort by
time. And this refactor is important because we're about to start
using data from the server to populate this data structure.
This change makes it possible for users to control the notification
settings for wildcard mentions as a separate control from PMs and
direct @-mentions.
This commit was automatically generated by `tools/lint --only=eslint
--fix`, after an `.eslintrc.json` change.
A half dozen files were removed from the changes by tabbott pending
further work to ensure we avoid breaking valuable PRs with merge
conflicts.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Hovering over user names (and user circles for PM List) now displays
Name, Status Message and Last online time in a js tooltip.
Hovering over group names displays the names of all group members.
Unavailable users are shown as "Last active: Today".
Hovering on a user circle in the Buddy List results in a js tooltip
with Active/Idle/Offline/Unavailable for
green/orange/white/white-with-line.
Resolves#11607.
When strings are tagged for translation using `tr this`, the strings
were passed into the frontend i18n as-is (including new line and tab
characters that are not functional in the text, existing just to
format the HTML files reasonably).
This did not match the algorithm used in `manage.py makemessages` for
extracting strings for translation, which (correctly) removed that
whitespace to provide a good experience for translators. The fix is
for the `tr this` implementation to use that same whitespace-stripping
algorithm.
Tested manually by checking if those strings that were not translated
earlier were translated, and also fixed an automated test that had the
wrong result, which should help prevent regressions.
Fixes#13389.
ES6 and TS modules don’t insert themselves into `window`, so our tests
shouldn’t insert them either. Since the test `window` behaves like
`global` now, we can rely on legacy modules that do insert themselves
to do it themselves.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
These should work consistently with how the individual user setting
works; see the last commit.
With changes from tabbott to fix real-time sync.
Fixes#12553.
This commit was originally automatically generated using `tools/lint
--only=eslint --fix`. It was then modified by tabbott to contain only
changes to a set of files that are unlikely to result in significant
merge conflicts with any open pull request, excluding about 20 files.
His plan is to merge the remaining changes with more precise care,
potentially involving merging parts of conflicting pull requests
before running the `eslint --fix` operation.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Because of the separate declarations, ESLint would convert them to
`let` and then trigger the `prefer-const` error.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Even though this variable was only assigned once, it was accessed
before its initialization, so it couldn’t be converted directly to
`let` or `const`. Use `let` with an explicit `null` to make it
clearer what’s going on and satisfy ESLint. (Why not `undefined`?
There’s an ESLint rule against that too.)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This feels a bit more semantically appropriate: it more clearly says
"here's some information: there is no (relevant) recipient", rather
than "no information available". (Both `null` and `undefined` in JS
can have either meaning, but `undefined` especially commonly means
the latter.)
Concretely, it ensures a bit more explicitness where the value
originates: a bare `return;` becomes `return null;`, reflecting the
fact that it is returning a quite informative value.
Also make the implementation more explicit about what's expected here,
replacing truthiness tests with `!== null`. (A bit more idiomatic
would be `!= null`, which is equivalent when the value is well-typed
and a bit more robust to ill-typing bugs. But lint complains about
that version.)
It'd already been the case for some while that calling `stop` had the
same effect as calling `update` (previously `handle_text_input`) with
a falsy recipient. With the API changes in the previous few commits,
this becomes quite natural to make explicit in the API.
This was named after when it gets called from the UI, rather than
after what it can be expected to do.
Naming it after what it's meant to do -- and giving a summary line to
expand on that -- provides a more helpful semantic idea for reasoning
about the function. Doubly so for using the function in a different
client with its own UI, like the mobile app.
The main motivation for this change is to simplify this interface
and make it easier to reason about.
The case where it affects the behavior is when
is_valid_conversation() returns false, while current_recipient
and get_recipient() agree on some truthy value.
This means the message-content textarea is empty -- in fact the
user just cleared it, because we got here from an input event on
it -- but the compose box is still open to some PM thread that we
have a typing notification still outstanding for.
The old behavior is that in this situation we would ignore the
fact that the content was empty, and go ahead and prolong the
typing notification, by updating our timer and possibly sending a
"still typing" notice.
This contrasts with the behavior (both old and new) in the case
where the content is empty and we *don't* already have an
outstanding typing notification, or we have one to some other
thread. In that case, we cancel any existing notification and
don't start a new one, exactly as if `stop` were called
(e.g. because the user closed the compose box.)
The new behavior is that we always treat clearing the input as
"stopped typing": not only in those cases where we already did,
but also in the case where we still have the same recipients.
(Which seems like probably the common case.)
That seems like the preferable behavior; indeed it's hard to see
the point of the "compose_empty" logic if restricted to the other
cases. It also makes the interface simpler.
Those two properties don't seem like a coincidence, either: the
complicated interface made it difficult to unpack exactly what
logic we actually had, which made it easy for surprising wrinkles
to hang out indefinitely.
All these cases are meant to simulate having a user actually typing a
message to some actual recipients, so the `conversation_is_valid`
parameter would be true.
We make this change so that in an upcoming change that eliminates this
parameter, the adjustments to the test cases can be highly regular and
we don't have to introduce a new wrinkle to correspond to these values
being false.
The real purpose these two callbacks serve is exactly what an ordinary
parameter is perfect for:
* Each has just one call site, at the top of the function.
* They're not done for side effects; the point is what they return.
* The function doesn't pass them any arguments of its own, or
otherwise express any internal knowledge that doesn't just as
properly belong to its caller.
So, push the calls to these callbacks up into the function's caller,
and pass in the data they return instead.
This greatly simplifies the interface of `handle_text_input` and of
`typing_status` in general.
Users generally don't expect wildcard mentions in muted streams and
topics to be treated as a mention, either for the purposes of desktop
notifications or the unread mention counts.
This fixes the unread mention counts part of the issue.
Fixes part of #13073.
This adds the general machinery required, and sets it up for the file
`typing_status.js` as a first use case.
Co-authored-by: Anders Kaseorg <anders@zulipchat.com>
When a user performs a search that might contain historical public
streams messages that the user has access to (but doesn't because
we're searching the user's own personal history), we add a notice
above the first search result to let the user know that not all
messages may have been searched.
Fixes#12036.
This ensures that typing '```java' and pressing enter would result in
getting dropped into a java codeblock instead of javascript codeblock.
We implement this by pushing the exact match of a query to be pushed to
the top of the returned matches in `sort_languages`.
With some comments added by tabbott in the tests explaining the
current reasoning.
Fixes#13109.
This changes the availability icon for bot users to user_circle_green;
previously it was accidentally defaulting to user_circle_empty, making
it appear that bots were never available.
Fixes#13149.
As it turns out, our rerender_the_whole_thing function (used whenever
we were adding messages and discovered that the resulting message list
would be out-of-order) was just broken and scrolled the browser to a
random location.
This caused two user-facing bugs:
* On very fast networks, if two users sent messages at very close to
the same time, we could end up with out-of-order message deliveries,
triggering this code path, which was intended to silently correct
the situation, but failed.
* In some narrows to streams with muted topics in the history but some
recent traffic, the user's browser-cached history might have some
gaps that mean the server fetch we do after narrowing discovers the
history is out-of-order, again triggering the
rerender_the_whole_thing code path.
The fix is to just remove that function, adding a new option to the
well-tested rerender_preserving_scrolltop (which has explicit logic to
preserve the scroll position) instead.
Fixes#12067. Likely also fixes#12498.
This brings us in line, and also allows us to style these more like
unordered lists, which is visually more appealing.
On the backend, we now use the default list blockprocessor + sane list
extension of python-markdown to get proper list markup; on the
frontend, we mostly return to upstream's code as they have followed
CommonMark on this issue.
Using <ol> here necessarily removes the behaviour of not renumbering
on lists written like 3, 4, 7; hopefully users will be OK with the
change.
Fixes#12822.
Fixes#13134 as the last commit in the series for this issue.
Solves the "The (?) should just be a target=_blank link to
/help/message-a-stream-by-email." part of the issue.
As a result, a bunch code managing the email hint popup can be deleted,
together with a node test for that.
There was a bug where the success banner stuck
around even after the export completed. We now
nicely fade and remove the banner upon a successful
population of the export in the table.
Fixes: #13045
Add ability to search entire message history of all public streams at
once. It includes all subscibed, non subscribed public streams messages
and even historical public stream messages sent before user had joined
an organization or stream.
Fixes#8859.
If a user was active within the last 90 days,
show number of days (23 Days ago).
If the user was active more than 90 days ago and in the same year,
then show MMM DD (Mar 15).
In any other case show MMM DD YYYY (Nov 10 2018),
Change timerender.js test to accomodate changes.
Delete trailing newlines from all files, except
tools/ci/success-http-headers.txt and tools/setup/dev-motd, where they
are significant, and static/third, where we want to stay close to
upstream.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
This reverts commit 76e50af78e.
Empirically, this caused weird issues with the cursor jumping around,
so more investigation is required into the right way to fix it.
Although SimpleBar automatically sets itself up on elements with a
`data-simplebar` attribute, sometimes we try to set event listeners
before that happens. Create the SimpleBar early in that case.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
When you press enter on a typeahead and start typing, your cursor is
placed at the end of the textbox, whereas we want it to be placed at
the end of the typeahead immediately. This causes some characters to
appear at the end of the message before you again get to typing from
where you left off.
To fix, we use the change event triggered on typeahead completion to
reposition the cursor instead of using a setTimeout().
Fixes#12621.
We implement 3 changes:
1. Partial Stream Typeahead
In addition to regular stream completion, we do partial completion
of stream typeahead on pressing '>'. We use our custom addition to
typeahead.js: this.trigger_selection to start topic_list typeahead.
Implements: `#stream na|` (press >) => `#**stream name>|`.
2. Topic Jump Typeahead
'topic_jump' typeahead moves the cursor from just ahead of a
completed stream-mention to just after the end of the mention
text and is triggered by typing '>' after the stream mention.
This typeahead merely uses the regex matching and event hooks of
the typeahead library instead of displaying any text completions.
Implements: `#**stream name** >|` => `#**stream name>|`.
3. Topic List Typeahead
'topic_list' typeahead shows the list of recent topics of a stream
and if your current text doesn't match one of them, also shows you
the current query text, allowing you to create mentions for topics
that do not exist yet.
Implements: `#**stream name>someth|` => `#**stream name>something** |`.
At the end of this commit, we support the following mechanisms to
complete the stream-topic mention:
1. Type "#denmar|".
2. Press Enter to get "#**Denmark** |".
3. Press > to get "#**Denmark>|".
4. Type topic name and press enter.
OR
1. Type "#denmar|".
2. Type > to get "#**Denmark>|".
3. Type topic name and press enter.
Both result in the final inserted syntax: "#**Denmark>topic name**".
Documentation is still pending.
Fixes#4836.
In this refactor, we extract two functions in unread.js. Which one to
use depends on whether res has already been fetched or not.
This also adds node tests to maintain coverage of unread.js.
Tweaked by tabbott for cleaner variable names and tests.
This change is long overdue. After implementing this much more robust
system and deploying it on chat.zulip.org, we hesitated to make
load_server_counts the default behavior in master, because of data
anomalies present for many existing users (basically messages far back
in their history that they had never read, on streams they believed
themselves caught up on), which would have been confusing for many
users.
However, because the mobile apps have been using this data set for a
long time, we've likely cleared out the anomalies from active users'
data set. And for older users, they're going to come back to
approximately infinite unread messages anyway, so the data anomalies
are unlikely to be important.
Fixes#7096.
This icon should only show when the user is not an admin and either the
realm or server settings have disabled name changes. Previously the icon
always showed for admin users.
The count_span element is parented by a .selectable_sidebar_block element
which is parented by the li element that the class is supposed to be added
to. Thus, use the parents() jQuery method for locating the li parent so
that the class gets added to the correct element.
This commit adds a new setting to the user's notification settings that
will change the behaviour of the unread count in the title bar and
desktop application.
When enabled, the title bar will show the count of unread private messages
and mentions. When disabled, the title bar will act as before, showing
the total number of unread messages.
Fixes#1736.
The approach taken here is basically use user IDs in operator that
support it when sending the request for fetching the messages
(see comments in code for more details).
Combined with work in the desktop app, this makes it possible for the
desktop app to clearly indicate to other users whether the current
user is active on the system and thus would see a desktop
notification, not just whether they are active in the current Zulip
window.
Essentially rewritten by tabbott to add unit tests and consider the
desktop app data authoritative.
Add new custom profile field type, External account.
External account field links user's social media
profile with account. e.g. GitHub, Twitter, etc.
Fixes part of #12302
Not all our errors actually happen in the contexts we were
wrapping (e.g. `setTimeout` and `_.throttle`). Also this fixes the
neat Firefox inspector feature that shows you where your event
handlers for a given DOM element actually live.
Using this "semi-modern" browser event means that Safari 9 and older
and IE10 and older may not have our browser error reporting active;
that seems fine giving the vanishing market share of those browsers.
https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
The comment that jQuery “doesn’t have” this was nonsense: jQuery
supports every event the browser does.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
After migration to an ES6 module, `suppress_unread_counts` would no
longer be mutable from outside the module.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
After migration to an ES6 module, `server_furthest_read` would no
longer be mutable from outside the module.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Fix the .get_suggestions and .get_suggestions_legacy
to correctly handle search terms in group PM and treat
it as search term by not concatenating it at end of pm-with
email list operand.
We reuse the link regexes we use elsewhere inn markdown
for parsing links in topic names and add a button to open
them in new tabs similar to our behavior with linkifiers
in topic names.
Fixes#12391.
Right now we have buttons for "New conversation" and "New private message"
in different views, but both buttons do the same thing.
The current state is confusing for new users, since there is already a lot
of terminology one needs to learn in order to understand the Zulip
conversation model. It's very plausible a user would think a "conversation"
is something different from a "private message" or a "topic".
With the help of `check_property_changed` function now we collect the data
whose values are changed from the current one. Currently this optimizes
only for those elements whose values are collected by
`populate_data_for_request` function i.e. it doesn't optimize data
collected by `get_complete_data_for_subsection`.
This is a preliminary commit which refactors `populate_data_for_request`
function, now this function traverse on all "property elements" of a given
subsection, but get the data only of those properties which have
`setting-widget-type` data attribute. Therefore, it doesn't change the
functionality of this function and overall changes don't make any
difference. In upcoming commits, we're going to use `input_elem` as an
argument to `check_property_changed` function, so that only those elements
whose values are changed are sent to the backend.
This commit disables "Mobile notifications" if `push_notifications` are not
enabled. It also adds a tooltip explaining why this is disabled.
Fixes#12208
Add `name` attribute to stream settings `input` elements
and change `id` attribute corresponding to name.
`name` attribute stores value of settings name which is
stored in frontend data sets.
Some search queries always return empty because of how we handle search,
this adds text that ensures users trying bad searches realize that they
are doing so.
This fixes an issue where one could end up with a `(` in the markdown
syntax for a link after copy-pasting this, which doesn't work in
markdown.
Fixes#12579.
Rename notification property `enable_stream_sounds` to
`enable_stream_audible_notifications` to match with other
notification property patterns.
Fixes part of #12304
Prior to this commit, we'd put up the green "Enable desktop
notifications" bar on page load AND the first time a desktop
notification worthy message was received, it would attempt to notify,
automatically triggering a browser permission popup (the same one as
clicking the green bar results in).
Now, desktop notifications are not attempted at all until the green
bar is clicked. Additionally Firefox and Webkit browser-specific
checks are made more uniform and done at the same point.
Tested written by YashRE42.
Fixes#11504.
This tests was added to make sure we catch subtle bug related to
comparing new_recipient and current_recipient. When we changed the
recipient to use arrays instead of string to use new user IDs based
api we encoured this bug and out testing suite couldn't detect this.
API changes:
* The behaviour of Date.toLocaleTimeString() reverts to pre 8.0.0,
this only affects automated tests. Lots of other API changes but
we didn't use any of those.
* The internal sorting algorithm changed which causes one of our own
compare function to miss coverage.
This adds a setting to control Zulip's default behavior of sorting to
bottom and graying out inactive streams. The previous logic is still
the default "automatic", but this gives users more control. See the
models.py comment for details.
Fixes#11524.
We have had a longtime bug where the state of pinned streams would not
update properly from the greyed out/inactive state to the active state
when a first message arrived to them.
After some discussion, we determined that likely the right fix for
this is to simply configure pinned streams to never be marked as
inactive; that's more in line with the intended user experience.
Fixes#8201.
Lightbox previews for youtube playlists use the "current" video in the playlist
for the preview. The open link for such previews is incorrectly set to the first
video alone, and not the playlist. This commit fixes the bug by linking to the
original URL for lightbox preview is being shown, instead of computing the URL.
This commit separates the `waiting_period_threshold` setting from
the `create_stream_policy` setting, adding a new setting that the user
can use to select a waiting period threshold.
Both the invite to stream policy and create stream policy now have
three options: admins only, members and admins, or members after
waiting period/admins.
In email hidden case (that is when `email_address_visibilty` is set to
everyone), for "non admins", this commit hides emails from:
- compose box user typeahead.
- PM user typeahead
In email hidden case, for admins, email is shown in user typeaheads.
In email hidden case (that is when `email_address_visibilty` is set to
everyone), for "non admins", this commit hides emails from:
- user popover
- custom profile popover
In email hidden case, for admins, email is shown in both user popovers and
custom profile popovers.
Along with this, we refactored settings_org.populate_auth_methods to use
HTML function after rendering all auth methods rows rather than appending
each row individually, which actually is a good practice.
Also in this commit, to compare `current_val` and `changed_val` in
`check_property_changed` function of the property
`realm_authentication_methods`, which are objects, and we found here
https://stackoverflow.com/a/1144249 that there is no easy way to do so. So
I followed this approach,
```js
JSON.stringify(obj1) === JSON.stringify(obj2)
```
but before converting them to string we want the same order of keys, so we
used `sort_object_by_key` to sort `current_val` by keys and
`get_auth_method_table_data` always return `changed_val` having keys
sorted.
Since these refactor were closely related we kept them as a single commit
here.
Fixes: #11954.
We now use a Proxy to wrap zjquery elements, so
that we can detect callers trying to invoke methods
(or access attributes) that do not exist. We try
to give useful error messages in those cases.
The main impact here is that we force lots of tests
to explicitly stub `length`.
Also, we can't do equality checks on zjquery
objects any more due to the proxy object, but the
easy workaround is to compare selectors. (This
is generally an unnecessary technique, anyway.)
The proxy wrapper is fairly straightforward, and
we just have a few special cases for things like
"inspect" that happen when you try to print out
objects.
With perfectScrollbar, we needed to call a function from JavaScript to
enable a scrollbar on a new element, but simplebar has a much simpler
default API one can do by using data-simplebar attributes in the HTML.
So we can delete all the scrollbar creation/deletion code.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Instead of deleting and rebuilding #private-container every time its
contents need to be updated, just replace its contents. This
eliminates some scrollbar flashing.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
perfect-scrollbar replaces both the appearance and the behavior of the
scrollbar, and its emulated behavior will never feel native on most
platforms. SimpleBar customizes the appearance while preserving the
native behavior.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Send at most 1k message ids in a single read flag request to avoid locking
large number of rows in server database in a single request and avoid long
processing time.
Fixes#11956.
This commit migrates the Subscription's notification fields from a
BooleanField to a NullBooleanField where a value of None means to
inherit the value from user's profile.
Also includes a migrations to set the corresponding settings to None
if they match the user profile's values. This migration helps us in
getting rid of the weird "Apply to all" widget that we offered on
subscription settings page.
The mobile apps can't handle None appearing as the stream-level
notification settings, so for backwards-compatibility we arrange to
only send True/False to the mobile apps by applying those defaults
server-side. We introduce a notification_settings_null value within a
client_capabilities structure that newer versions of the mobile apps
can use to request the new model.
This mobile compatibility code is pretty effectively tested by the
existing test_events tests for the subscriptions subsystem.
If MAX_FILE_UPLOAD_SIZE is set to 0, then UI elements like the upload
icon in the compose and message edit UI and "Attachments" menu in
"/#settings" are not displayed.
A different error message is also displayed if a user tries to drag and
drop or paste a file into the compose message box.
Fixes#12152.
This adds three bools to message_container object which calculate bools
where the "(EDITED)" label should appear:
* `edited_in_left_col` -- when label appears in left column.
* `edited_alongside_sender` -- when label appears alongside sender info.
* `edited_status_msg` -- when label appears for a "/me" message.
We use the new bools and remove the complicated if else statements
from the templates for the "(EDITED)" label.
This also allows us to add a unit test to verify the logic.
This commit renames the `create_stream_permission` field in the
templates to `create_stream_policy`, matching the field used in the
database model. This matches what `invite_to_stream_policy` does and
will be clearer when the `waiting_period_threshold` is split into its
own field.
This commit replaces the `create_stream_by_admins_only` setting with a
new `create_stream_policy` setting, which mirroring the structure of
the existing `invite_to_stream_policy`.
This is important preparation for migrating the waiting period feature
to be its own independent setting.
Fixes#12236.
Fixes#12251.
Previously when disabling name changes in server settings, instead
of realm settings, the name edit button did not get disabled.
Changing name resulted in a message stating `no changes made`.
Fixes#12132.
Realm setting to disable avatar changes is already present.
The `AVATAR_CHANGES_DISABLED` setting now follows the same
2-setting model as `NAME_CHANGES_DISABLED`.
This is useful when syncing avatars from an integrated LDAP/active
directory.
The upload avatar and delete avatar buttons are hidden if avatar
changes are disabled and the user is a non-admin.
If the user has a gravatar set, then the user will not be able to
upload an image as their avatar if avatar changes are disabled.
Part of #12132.
This commit creates a new organization setting that determines whether
a user can invite other users to streams. Previously this was linked
to the waiting period threshold, but this was both not documented and
overly limiting.
With significant tweaks by tabbott to change the database model to not
involve two threshhold fields, edit the tests, etc.
This requires follow-up work to make the create stream policy setting
work how this code implies it should.
Fixes#12042.
In handlebars and settings_org.js, the subsection in which
`realm_message_retention_days` property lies doesn't agree, and this wasn't
observed for a long time as it's disabled, still to make things right, in
this commit we have moved the logic which handles the collection of data
from `other_permission` to `other_settings` as it makes more sense there.
This is a small patch to fix the error message an admin would receive if
they tried to change bot info and owner from the "bots" setting of the
organization settings panel.
The alphabetic sorting of lists in the User/Organization settings was
changed in fa0a5ec to be case insensitive.
This commit makes changes to the list_render.js test to verify that the
sorting of these lists is indeed case insensitive.
We no longer store handlers as an array of functions,
and instead we assume that code will only ever set up
one handler per sel/event or sel/event/child. This is
almost always a sane policy for the app itself.
We also try to improve error handling when devs write
incorrect tests.
The only tests that required changes here are the
activity tests, which were a little careless about how
data got reset between tests.
Apparently, our use of JavaScript string `.replace()` here was buggy,
because replace() has several special escape sequences starting with
`$` if they appear in the replacement content string. We can work
around this through something of a hack, which is to pass a function
as the second argument to replace, which seems cleaner than replacing
all $s with $$s.
Thanks to Shreya for the report.
Now that we have a scroll container for the PM list,
it doesn't make much sense to limit the number to
five.
We may resurrect this feature if "more conversations"
actually fetches more conversations, but it doesn't
currently.
We also may soon make it easy to limit PMs to just
unread messages, which will make the max-5 feature
perhaps less necessary, and we don't want to make
the UI overly complicated.
This is the follow-up of PR #10267.
Here, we add typeahead for slash commands `/me` and `/poll` in compose box.
The slash typeahead will open only when `/` is the first character and all
slash commands will be displayed when one types `/`, as this helps a lot in
discoverability. This also adds a description of what the slash command
does in the typeahead.
When new PMs came in, we would do a little
animation to show you the incoming message.
Unfortunately, it was broken and would animate
too many things. (The code looks at a single
var to see if PM counts changed, but there are
actually mulitple PM counts. We could fix that,
but we decided that this feature just isn't
worth the complexity.)
We still animate incoming mentions.
Fixes#11868.
This makes the "more topics" option which appears below the list of
known topics in the left sidebar appear only when it's possible there
are actually more topics to be displayed. Two specific cases it
resolves completely include:
* Newly created realms; this widget was a common source of confusion
for new organization administrators.
* Newly created streams.
There are still some corner cases this doesn't handle, e.g. if you
just joined a private stream with protected history, but there isn't
as easy a fix for those.
Essentially rewritten by tabbott to fix code duplication and comment
extensively.
Fixes#10265.
As a follow up of commit (bf1c9420df), this
commit removes the `build_realm_day_mode_logo_widget` and
`build_realm_night_mode_logo_widget` function , and changes
`build_realm_logo_widget` to take single argument `is_night` and depending
on this argument, corresponding `day mode` or `night_mode` widget is
handled.
This changes the "new private message" button to be instead "new
conversation" when looking at PMs, to avoid confusion that the button
was the right thing to do to reply to the current private message
conversation.
Fixes#11679.
Even though there are only ever zero or one active
topic widgets in our current sidebar, it's almost the
same amount of code to just manage them with a Dict.
Also, we can more easily do possible future features
like setting streams to be always-open.
This moves the configuration of widget type from settings_org to instead
live in respective HTML templates, via `data-widget-setting-type` and we
also remove `get_subsection_property_types` and refactor function
`populate_data_for_request` accordingly.
Fixes: #11708.
This fixes the bug where the `Saved` state button faded out almost
instantly (that is actually 300 ms) and `Discard` button fades out
along with `Saved` state button; the key problem here was that the
setTimeout intended to fade was actually delaying the transition from
"saving" to "saved".
Now, first of all, we use `setTimeOut` function to fadeout elements giving
fadeout_delay time as `800 ms` and we hide discard button during `saving`
state. Also, when `Discard` button is selected, `Save changes` and `Dicard`
fade out simultaneously.
Fixes: #11737.
If you click on the avatar, we now show the menu
right next to the avatar. The current behavior
is particularly funny for long names. (I confirmed
this with Rishi.)
Adds possibility for users to use | as an OR-operator (besides ,)
when searching for other users.
This is a thing reasonable folks might try, and | in the thing to
search for isn't a realisitic possibility, so there's no real downside
to adding this.
Fixes#4109.
In this commit, I've added a feature to unstar all the starred
messages. This is useful, e.g., for folks who are using starred
messages to keep track of things they should come back when next at
their desktop.
The event flow is the standard one for a feature with a confirmation modal:
(1) User clicks on unstar all messages.
(2) We display a confirmation modal; if the user confirms, we send a
request to the backend to clear all starred messages.
(3) The events system sends that UI update back to us, removing the
stars from the UI.
Fixes#11401.
This commit deduplicates the code for `build_realm_logo_widget` and
`build_realm_night_logo_widget`. It deduplicates the common code for
`build_realm_day_mode_logo_widget` & `build_realm_night_mode_logo_widget`
into tthe function `build_realm_logo_widget`.
Add a background highlight to vote count button if currently
logged in user votes on that option.
Tweaked by tabbott to use better variable names and Rishi for better
styling.
This is a pure data function, so it shouldn't be in popovers.js file
(Steve Howell added test coverage here, and tabbott removed an
accidental functional change.)
The correct behavior here is that we want to ensure there is
whitespace in between the syntax being added and the content on either
side. Our smart_insert logic handled this for the cases that were
common with inserting emoji (etc.), but didn't handle the more complex
cases with "quote and reply".
Fixes#11702.
This new helper allows us to do the same operation
on every message in our message_store. We will
use this in a future commit to clear the `is_tall`
flags on all messages, after a resize.
We should be somewhat cautious about using this,
but simple operations should be really fast, even
if you have lots of messages in the store.
Previously, if you were in the process of editing the last message in
a narrow and a new message came in, we'd rerender that second-to-last
message, causing your editing widget to lose focus (and thus the next
few keys you typed to be interpreted as keyboard shortcuts, which
had a good chance of resulting in your navigating somewhere random).
This rerendering was essentially unnecessary; the only change to state
going into the rendering process was the next_is_same_sender CSS class
being toggled on the messagebox in the message. So, at most, we
should have been just toggling that CSS class (and this commit makes
us do precisely that).
It seems like we could further improve this code by just removing the
next_is_same_sender CSS class entirely and removing this block, but
I'm leaving that for follow-up work.
Fixes#11656.
This fixes an issue where closing stream search was not working if
user had not entered a search term and tried to close the search box
by clicking on the close icon; the problem was that we'd end up
re-opening the widget immediately after through event propagation.
Fixes: #11636.
Also adds tests to ensure that we do not accidentally overwrite
the 'beginning' variable that contains the message content upto
that point. These should prevent similar errors in the future.
The bug was added in 8119258c4d.
The bug here was that when we rerendered messages following local echo
through the echo.process_from_server code path, the eventual call to
_rerender_header() made the implicit assumption that all messages in a
message group had the same date. As a result, it created a totally
new/fake message group and called the rendering logic on that group
without calling the functions for setting up recipient row dates,
which would always result in no recipient bar date being added. This
bug was latent/invisible before, because when introduced, the locally
echoed messages were always being added to a recipient group from
today, where the recipient bar's date area was by default empty anyway.
This latent bug was revealed when we modified the structure of the app
to do date dividers between individual messages within a message
group, rather than strictly between message groups.
For consistency, we should keep all the code that works with
@mentions in markdown.js. In this case, message_list_view was
rewriting the contents of the mentions in cases where users'
names had been changed since we rendered their mention.
This change should help people discover to distinguish
silent mentions in text as a part of Zulip syntax while
differentiating them from regular mentions.
To test formatting we want a hard coded date, so we
can verify the date arithmetic with stable dates.
To make the test less brittle, we disable the
feature to remove old drafts.
This was an emergency fix. We should probably just
remove the last N drafts instead of having the 30-day
limit. Or we should have a better way to stub the cutoff
date.
This is mostly adding markup, calling some convenient
functions in buddy_data.js, and adjusting CSS.
To make the circles update dynamically, I mostly
orchestrate this though activity.js for now. It's
possible we'll want to adjust that eventually to
happen through something like a `presence_events`
dispatcher, but that's essentially what
a good part of `activity.js` does now.
We now have a function get_user_circle_class
that returns one of these values:
"user_circle_green"
"user_circle_orange"
"user_circle_empty"
And we put that in the templates.
And then CSS renders the circle of the appropriate
color.
The unit tests now explicitly capture whether
we are rendering the correct kind of circle.
This fixes a longstanding UI issue when you have way too many recent
private message conversations, as you can now scroll down the list to
find what you're looking for.
Fixes#5384.
This removes the left border extending the stream label from the
recipient bar in from the drafts in drafts modal. Those borders are
important in the message feed for containing several messages, but
here we're only ever going to show individual drafts, and this change
avoids potential color clashes with the blue box surrounding the
recipient blocks.
Show "sent to different narrow" notification and other such notification by
notifications.notify_local_mixes for non locally echoed message sent by
current client.
With significant new comments added by tabbott.
Fixes: #11488.
We swallow the error if our python_to_js_filter code is
unable to parse some python regex properly. This ensures
that the web app stays responsive.
We would fail to show an accurate local echo for these
regexes, however, the backend would act as the final
authority for handling the realm pattern conversion.
Since on replacing the first 'P<>' group, we remove this text from
the string, we have to make the RegExp start looking from index 0
again to properly convert later 'P<>' groups to JS regex syntax.
We want the search widget, when visible, to be
outside the scroll container for the stream list.
One obvious use case is if you start scrolling, and
then realize it might be less effort to search.
Also, for user search, it already worked this way.
We have to add a couple resizing hooks here, but
it's not necessary to change the actual resize
calculation, since we move the section inside
of #streams_header, which is already accounted
for.
The only markup change here is to add
a `stream_search_section` class. I don't
know why we use `notdisplayed` here instead of
jQuery, or what `input-append` is for, but I
considered them outside the scope of this change.
We can also remove some crufty CSS that was
compensating for it being inside the container.
This adds date dividers within a single message group when the only
reason we had previously been splitting apart two message groups is a
change of date. The overall effect is a cleaner message list user
experience.
The downside of this change would be that the recipient bars no longer
will always show a new date for date changes; to fix that, we rewrite
how the floating recipient bars both set the date field on the
floating recipient bar itself, as well as ensure that non-floating
recipient bars don't show duplicate dates.
In a future design update where we modify how message recipient bars
look, we may very well be able to simplify this logic by removing some
of the dynamic nature of the recipient bar calculations. But this is
a good implementation of what remains.
Tweaked significantly by tabbott from Steve Howell's original, both to
extract these changes from a larger PR as well as to modify the
first_visible_message logic to handle some tricky corner cases.
Fixes#10171.
Use the results of commit #73d26c8 to remove the method
`render_stream_description` in static/js/stream_data.js and instead
use the rendered_description attribute now being sent by the backend.
This will be a valuable optimization and a step towards removing the
need for the marked.js markdown parser and speeding up the client end.
In small screen sizes, when the user presses shortcut `w` to search
for another user, the hide_all function calls in the search code path
would hide the right sidebar, immediately after opening it, making the
hotkey basically unusable.
We fix this by extracting a separate hide method that hides all true
popovers, but not the user list sidebar.
Fixes#11463.
This code will correctly add video call link to the message
textarea based on whether 'Add video call' was selected from
message composition form or message edit form.
The implementation was semi-rewritten by tabbott to remove an
unnecessary global variable, with fixes for the unit tests from
showell.
Fixes#11188.
This is primarily a feature for onboarding, where an organization
administrator might send a bunch of random test messages as part of
joining, but then want a pristine organization when their users later
join.
But it can theoretically be used for other use cases (e.g. for
moderation or removing threads that are problematic in some way).
Tweaked by tabbott to handle corner cases with
is_history_public_to_subscribers.
Fixes#10912.
This function unlike `invite_streams()` returns an array of objects having
various info (name, stream_id, invite_only, default_stream) related to
streams rather than an array of names of streams.
We now compute the class that drives the tiny
green/orange/empty dot in the user popover using
the same logic as the buddy list.
This was broken in the early implementation of
set/clear-away, but it was never released.
Fixes#11413
This makes it possible to mention a user with a name like Gaël that
contains diacritics by typing e.g. "Gael", significantly reducing the
need to use a special keyboard to mention other users.
Fixes#11183.
The following elements in the top left corner
are major components of our app:
All messages
Private messages
Starred messages
Mentions
We can now find them directly:
$('.top_left_all_messages')
$('.top_left_private_messages')
$('.top_left_starred_messages')
$('.top_left_mentions')
Before this, we had to build up complicated selectors
like below:
exports.get_global_filter_li = function (filter_name) {
var selector = "#global_filters li[data-name='"
+ filter_name + "']";
return $(selector);
};
I don't think any newbie would know to grep for "global_filter",
and I've seen a PR where somebody added specific markup here
to "Private messages" because they couldn't grok the old scheme.
Another thing to note is that we still have a "home-link"
class for "All messages", which overlapped with portico
code that had the same name. (There were some inaccurate
comments in the code relating to the tab bar, but we don't
actually have a way to click to the home view in the tab
bar any more.) I'll eliminate that cruft in another commit.
For this commit the four elements still have the
"global-filter" class, since there's some benefit to being
able to style them all as a group, although we should give
it a nicer name in a subsequent commit.
Most of this PR is basic search/replace, but I did add a
two-line helper: `top_left_corner.update_starred_count`
We had initially designed the poll widget like a blog
post with comments beneath it but it makes more sense
to think of it as just a simple poll with options.
Instead of custom stubs, we now use zjquery. We also
limit a couple checks to the first call to
`show_empty_narrow_messages`, since it's the same
logic every time.
When you hover over a user that has set a user
status, we now show something like "out to lunch."
You can test this in the console by doing:
user_status.server_update({status_text: 'out to lunch'})
And then hover over your name in the buddy list.
The stubs here were kind of unnecessary, as the
real people module is lightweight and data setup
is pretty easy.
In passing I also removed the unnecessary `sed`
abbreviation.
The name `insert_user_into_list` is sort of misleading,
since we are often just redrawing the user's existing
item in the buddy list.
I chose `redraw_user` over `update_user` to emphasize
that we're just going to redraw it with whatever data
has been updated by the callers.
This adds a setting under "Notification" section of
"Organization settings" tab, which enables Organization administrator to
control whether the missed message emails include the message content or
not.
Fixes: #11123.
The commit f863a9b567 had modified
jquery.filedrop's paste method to exit early if any of the items in the
clipboardData is of the string kind. The early exit was added to prevent pasting
an image thumbnail for text copied from software like MS Word, instead of
pasting the actual copied text content. When copying an image in a (modern?)
Browser, though, the clipboard seems to contain a html `img` tag item, along
with the actual image file. This resulted in pastes being broken.
This commit modifies the condition checked for the early exit. We now actually
look at the html content in the clipboard to see if it is an `img` tag, in which
case we upload the image, instead of exiting early.
Closes#7130.
This commit takes away the ability for non-admin members to create
streams where only admins can post messages by hiding the option from
them.
Fixes#11290.
You can now pass in an info field with a value
like "out to lunch" to the /users/me/status,
and the server will include that in its outbound
events.
The semantics here are that both "away" and
"status_text" have to have defined values in order
to cause changes. You can omit the keys or
pass in None when values don't change.
The way you clear info is to pass the empty
string.
We also change page_params to have a dictionary
called "user_status" instead of a set of user
ids. This requires a few small changes on the
frontend. (We will add "status_text" support in
subsequent commits; the changes here just keep
the "away" feature working correctly.)
We had a bug where if you started typing a message
and then used quote/reply (after the fact), we
would overwrite the user's original message.
The bug was kind of subtle--the internal call
to "respond" to the message would select the message
text, and then `smart_insert` would replace the
selection, unless it was Firefox.
Note that we now also allow you to cross-post
replies, which is a plausible scenario, although
possibly unintentional at times, too. I'm erring
on the side of giving the user control here, but
I'll add a warning in the next commit. Our compose
fade feature should also prevent unintentional
mixes here, too.
NOTE: If you revert this commit, you want to revert
the immediately prior commit as well. The history
is that Ishan made some improvements to the widget,
but there were some minor bugs. I decided not
to squash the commits together so that the git
history is clear who did what. (In particular, I
want questions about the JS code to come to me if
somebody does `git blame`.)
Anyway...
This is a fairly significant rewrite of the polling
widget, where I clean up the overall structure of
the code (including things from before the prior
fix) and try to polish the prior commit a bit as
well.
There are a few new features:
* We tell "other" users to wait for the poll
to start (if there's no question yet).
* We tip the author to say "/poll foo" (as
needed).
* We add edit controls for the question.
* We don't allow new choices until there's
a question.
On the backend, we extend the BlockQuoteProcessor's clean function that
just removes '>' from the start of each line to convert each mention to
have the silent mention syntax, before UserMentionPattern is invoked.
The frontend, however, has an edge case where if you are mentioned in
some message and you quote it while having mentioned yourself above
the quoted message, you wouldn't see the red highlight till we get the
final rendered message from the backend.
This is such a subtle glitch that it's likely not worth worrying about.
Fixes#8025.
These mentions look like regular mentions except they do not
trigger any notification for the person mentioned. These are
primarily to be used when you make a bot take an action and
the bot mentions you, or when you quote a message that mentions
you.
Fixes#11221.
AFAIK I should this never fail, hence the blueslip.error line. But it
is failing in practice when rendering user groups after looking them
up by ID, and the error handling should definitely be softer.
In between releases, the following commit introduced
a bug where we agressively scroll to the top every
place we call `ui.update_scrollbar`:
092b73d0b7
The main symptoms were that the left and right sidebars
would go to the top for things like selecting a topic,
getting activity updates from the server, and resizing
the window. It was very jarring.
The recent commit looked innocuous--the root of the problem
was the original API expressed an intent to scroll to the
top, but didn't actually do it, so it was a bug in hiding.
There are **some** occasions where it's actually appropriate
to scroll to the top, mostly around search filtering, and
in those places we now call the new `ui.reset_scrollbar`
function.
This is a bit of an emergency fix, so particularly with
the settings stuff, we may get more reports of glitches here.
The important thing here is that you almost never want to
reset the scrollTop for sidebars.
This seems like a small change (apart from all the
test changes), but it fundamentally changes how
the app finds "topic" on message objects. Now
all code that used to set "subject" now sets "topic"
on message-like objects. We convert incoming messages
to have topic, and we write to "topic" all the way up
to hitting the server (which now accepts "topic" on
incoming endpoints).
We fall back to subject as needed, but the code will
emit a warning that should be heeded--the "subject"
field is prone to becoming stale for things like
topic changes.
We now have two functions:
add_new_messages
add_old_messages
This is a lot easier on the eyes, and it will also
prevent us from exceeding line length in future commits.
We also remove an unneeded stub in the narrow_activate
tests.
This is the preferred way to check that a user
id belongs to the current user.
We have a recent bug where the current user's
circle doesn't turn green right away. It's not
clear this is the fix, though. (It's hard to
repro locally.)
This is mostly for testing purposes. The code
structure here is pretty stable--we will probably
always use level() here to either sort or
group users, and being able to test it directly
is nice, rather than bringing in all the other
machinery.
This makes it possible it include our standard markdown formatting in
one's custom profile fields, allowing for links, emphasis, emoji, etc.
Fixes#10131.
While we're at it, we remove the JSON parsing that was part of the
user field code path, since this function isn't responsible for
rendering user fields.
Previously, messages with more than one line did not parse '/me' at
the beginning of the message. Since there's a reasonable way to
render multi-line messages, this commit adds support for doing so.
This change does potentially break with the expected behavior of other
slash commands, but it seems worth providing useful functionality over
a blind focus on consistency.
Fixes#11025.
We instead get the specific fields from message
that we use. This is particularly helpful
for subject -> topic migration; we no longer
have to account for "subject" fields in
client-side templates.
This continues the effort to isolate "subject" references
to util calls.
Also, we fix a comment.
Finally, we use canonicalized operators in a switch
statement.
The `assert_message_groups_list_equal` and
`assert_message_list_equal` helpers were
always returning `true`, as they were doing
a bogus traversal of the data structures and
always comparing empty arrays, even when there
was real data.
To prevent this pitfall in the future, we assert
that the extracted data is truth-y, and for the
empty cases we just directly assert deep equality
to `[]`.
As part of giving the stream/topic fields in the
compose box longer ids, I broke the autocomplete
code that handles re-focusing the cursor after
a user hits enter. The worst symptom of this was
that we tried to send a message before compose
finished (although it wouldn't fully deliver the
message).
The new code should be a bit easier to grep for
if we rename these fields again, as we explicitly
use selector syntax.
This adds a new realm_logo field, which is a horizontal-format logo to
be displayed in the top-left corner of the webapp, and any other
places where we might want a wide-format branding of the organization.
Tweaked significantly by tabbott to rebase, fix styling, etc.
Fixing the styling of this feature's loading indicator caused me to
notice the loading indicator for the realm_icon feature was also ugly,
so I fixed that too.
Fixes#7995.
We are trying to carve room for a more specific
"user_status" concept, which refers to statuses
that users specifically set, like "I'm away".
So we call this function "update_presence_info",
which reflects that it's more about actual
"presence"--i.e. the user really is present
in the browser, even though the actual human
may not want to be disturbed.
The current user gets excluded from all non-empty
searches, even ones that match the user, since
it can look funny when the user's at the top of a
search, and you'd never need to search for yourself
(again, since the current user is at the top of
the buddy list).