Previously, we were searching the whole message_row object for emoji,
mentions, etc., which has a bunch of UI elements that can't contain
the syntax we want to modify. This should be a slight improvement in
the performance of message post-processing, which runs a lot of times
and thus is fairly important.
This check caused us to only run the code inside that block if the
message mentioned the current user (since that's when the `mention`
class is added to the main message row).
While this was a useful performance optimization, it probably was a
small one, not worth it for the correctness cost.
If a user has an old mention and has since been renamed, there's
really nothing for us to do to render it; we should just return as
though we have no data.
The stream_list test that was fixed here was sort of
broken. It accomplished the main goal of verifying
what gets rendered, but now the data setup part is
more like the actual app code (and simpler, too).
When a user's name is edited, currently we still show the old name is
mentions (though clicking on the item does the right thing).
However, at present, it creates a new problem in search results, where
the highlighting is removed by this substitution.
Previously, Topic editing was offered in the UI even to message
senders and organizations admins only if the message was no more than
one day old. This was correct for the "community topic editing" case,
but not for message senders and organization admins.
While we're at it, this also centralizes some previously haphazard
logic to always call message_edit.is_topic_editable().
Tweaked significantly by tabbott to fix the logic.
Closes#10568.
For message groups, I just changed the internal name
to "topic_links".
For uses of "subject_links" that are tied to how the
server names fields, I introduced these wrappers:
* util.set_topic_links(obj, topic_links)
* util.get_topic_links(obj)
These can be used for either messages or events.
We split out two new functions and call them
everywhere that we used to call add_display_time():
- `update_group_time_display`
- `update_timestr`
We also make some of the local vars more consistent,
as well as doing more explicit clearing of vars than
`delete`.
Splitting these functions will allow us to muck with date
dividers without affecting the `update_str` functionality.
This allows several modules to no longer need
to import `narrow` (or, in our current pre-import
world, to not have to use that global).
The broken dependencies are reflected in the node
tests, which should now run slightly faster.
The values of this dictionary used to be raw DOM elements,
but get_row() wraps them again, so there's not a huge
reason to store them as raw DOM elements internally. It
is slightly easier to reason about the code if everything
stays at the jQuery level.
To preserve the old behavior here, we have to do something
that is kind of ugly, but at least it's explicit now. In
the old code, our cache was DOM elements, and if an id
wasn't in the cache, we would sneakily return $(undefined)
with this code in get_row():
return $(this._rows[id]);
And it turns out that $(undefined) is basically just a
zero-element jQuery object. A lot of our code depends
on this behavior and just works around the zero-element
objects as needed with checks like this:
if (this.selected_row()).length === 0) {
// don't try to get offset
}
For now we just preserve this behavior. We could eventually
be more strict here, or at least have aggressive warnings
on cache misses, but we'd need to retrofit code to be
able to call something like `has_rendered_selection()`
and/or deal with `undefined` as the return value for the case
where the selection hasn't been rendered.
Here is some example code that would cause tracebacks if
we just returned `undefined` for cache misses:
rerender_preserving_scrolltop: function () {
// old_offset is the number of pixels between the top of the
// viewable window and the selected message
var old_offset;
var selected_row = this.selected_row();
var selected_in_view = selected_row.length > 0;
if (selected_in_view) {
old_offset = selected_row.offset().top;
}
return this.rerender_with_target_scrolltop(selected_row,
old_offset);
},
This function is more cohesive and always takes in
a jQuery object containing exactly one DOM element,
and it does all stuff at the jQuery level of
abstraction (no raw DOM).
It's a pretty simple extraction--removing the level
of indentation makes the diff a bit noisy.
We shorten the name of the function and avoid having
all the callers call `.get()`. Now we mostly stay
in jQuery "space", which avoids some confusion about
when we're dealing with raw DOM elements and which
will facilitate unit testing.
This implements right-to-left message automatic detection support in
the compose box as well as the message feed. Full unit tests and
support in the message-editing UI are for future work (as are
potentially more fancy things like supporting things like
right-to-left multi-word names for users/streams/etc.).
Fixes#3123.
This commit prepares the frontend code to be consumed by webpack.
It is a hack: In theory, modules should be declaring and importing the
modules they depend on and the globals they expose directly.
However, that requires significant per-module work, which we don't
really want to block moving our toolchain to webpack on.
So we expose the modules by setting window.varName = varName; as
needed in the js files.
This commit lays the foundation to handle submessages for
plugin widgets. Right now it just logs events, but subsequent
commits will add widget functionality.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).
The one area that we do not attempt to work on here is the
"switch/case" indentation.
The refactor in 12509515ae had a subtle
bug, which is that we switched from accessing the message list "this"
(aka the message list being rerendered) to current_msg_list. This
meant that when the narrowed_msg_list was in view and code needed to
modify home_msg_list, we accessed the wrong `selected_row` to preserve
the scroll position of (namely, the one in current_msg_list, not the
one in home_msg_list).
Fix this, by moving the function to be a property of the
message_list_view object, which makes more sense structurally, anyway.
We may, in the future, want to do a similar migration for more of
message_viewport.js.
Fixes#8854.
Based on extensive manual testing with print-debugg (the exact
situation here was highly reproducible), in the absence of this line
here or slightly above here, Chrome 64 will consistently trigger an
extra scroll-forward-by-12000-pixels size downward scrolling event
immediately after it finishes rendering the 5th batch of ~100 messages
one gets from hitting the End key in `near:1` narrows.
I don't understand clearly why this change would protect against such
a Chrome bug, but my best guess is that Chrome was doing some sort of
incorrect optimization, and querying the scrollTop was forcing it to
come to a clear conclusion about the scrolling position before
appending more content.
But runs with the scrollTop() line not present in that function show a
scrollTop of around 25K in `append()` just before the call to
`render()`, and 37K at the end; while runs with this scrollTop line
always show 25K both before and after, so it does seem to work.
We don't have any consumers for this event after removing
some obsolete code related to subscribe buttons.
Handling this event reliably consumed about 75% of the time
spent in _post_process_dom_messages, and maybe a percentage
point or two of overall rendering, so this will be a minor
speedup.
Applies the logic to allow community members to edit topics
of others' messages if this setting is True. Otherwise,
only administrators can update the topic of others' messages.
This logic includes a 24-hour time limit for community topic editing.
In `recipient-row` template, if conditions to add/hide/show edit
icon for message topic is incorrect.
In some cases, we only want to just hide the edit icon, but icon
should be in DOM, cause in future if organization settings are
changed we want to show edit icon in message row.
If user can edit topic of message, surely add edit icon element to
DOM regardless of user is allowed to edit or not. If user is
allowed to edit then show edit icon otherwise hide edit icon element.
We no longer have a special UI setting and model
field ("emoji_alt_code") for saying users want text-only
emojis. We now instead make "text" be a fifth choice
for "emojiset".
Fixes#7406
This change has a few cleanups:
* We early-return on last_msg_container === undefined
to make the function flatter.
* We avoid comparing two boolean values for equality,
which can be a landmine if one of the values is
`undefined`, which is falsy but not actually `false`.
* We extract some local variables for readability.
* We make the conditions for subscribe/unsubscribe
more explicit.
Do not attempt to autoscroll down to view new messages if popovers are
open. This prevents the issue where someone can be viewing a profile or
reacting to a message and not be able to due to a new message coming in.
Fixes: #7319.
When we added support for mentioning users when editing messages, we
neglected to add this bit of code needed to make sure the UI code in
message_list_view.js would actually rerender that part of the
message's state.
Arguably, this is a sign that the message_container structure should
be just recomputed every time we rerender messages, but that's a less
tactical fix.
We've been getting reports for a few months of folks coming back to
their Zulip window after a night's sleep and finding it scrolled to
the bottom, past dozens or hundreds of messages that they haven't
read. Oddly, the pointer is actually still located where it should be
(verifiable by hitting the Up key), but it's too late: everything
below gets marked as read because bottom_whitespace is in view.
There's only a few places in the zulip codebase where we scroll the
page down, and this is the main one of them. My best theory for what
could be happening is that the browser is, in its overnight
power-saving mode, not granting the Zulip window the resources to
actually repaint the early scrolls. This, in turn, would cause
scrolling down to happen that is not limited by the need to keep the
pointer in view.
I don't think that this fully closes the issue; ideally, we'd have a
reproducer and much more precise detection logic for this situation,
but it should mostly resolve the problem with likely no user-facing
visible harm.
We had a bug where once you scrolled back far enough
in the message view, your "window" for rendered messages
would be at the max, and `prepend` was not adjusting
the window correctly. Now we follow the example of
`append` and call `maybe_rerender`.
This partially addresses #6628, where users were
reporting that the home key stopped going up in their
feed. There was another bug at play for that issue
as well, which is fixed in the next commit.