The prior implementation was needlessly complex. Both del() and
add() are cheap and idempotent.
With this change we no longer bother to delete a topic from a
dictionary when its last message is mark as read, since it doesn't
really help performance. We add a line to the tests to maintain
100% line coverage.
It's not always clear whether user_ids are strings or integers, so
we explicitly convert them to integers for sorting when creating
keys for PMs.
To keep the tests passing, this commit removes some unneeded
defensive code in message_store.js that only applies to contrived
test input.
This commit extract send_messages.js to clean up code related
to the following things:
* sending data to /json/report_send_time
* restarting the event loop if events don't arrive on time
The code related to /json/report changes the following ways:
* We track the state almost completely in the new
send_messages.js module, with other modules just
making one-line calls.
* We no longer send "displayed" times to the servers, since
we were kind of lying about them anyway.
* We now explicitly track the state of each single sent
message in its own object.
* We now look up data related to the messages by local_id,
instead of message_id. The problem with message_id was
that is was mutable. Now we use local_id, and we extend
the local_id concept to messages that don't get rendered
client side. We no longer need to react to the
'message_id_changed' event to change our hash key.
* The code used to live in many places:
* various big chunks were scattered among compose.js,
and those were all moved or reduced to one-line
calls into the new module
* echo.js continues to make basically one-line calls,
but it no longer calls compose.report_as_received(),
nor does it set the "start" time.
* message_util.js used to report received events, but
only when they finally got drawn in the home view;
this code is gone now
The code related to restarting the event loop if events don't arrive
changes as follows:
* The timer now gets set up from within
send_messages.message_state.report_server_ack,
where we can easily inspect the current state of the
possibly-still-in-flight message.
* The code to confirm that an event was received happens now
in server_events.js, rather than later, so that we don't
falsely blame the event loop for a downstream bug. (Plus
it's easier to just do it one place.)
This change removes a fair amount of code from our node tests. Some
of the removal is good stuff related to us completing killing off
unnecessary code. Other removals are more expediency-driven, and
we should make another sweep at ramping up our coverage on compose.js,
with possibly a little more mocking of the new `send_messages` code
layer, since it's now abstracted better.
There is also some minor cleanup to echo.resend_message() in this
commit.
See #5968 for a detailed breakdown of the changes.
Prior to this we were also performing highlighting inside HTML tags
which was wrong and causing weird behavior. Like, for example, if
someone added `emoji` as an alert word then any message containing
both emoji and alert word was rendered with a jumbo emoji.
Fixes: #4357.
A realm filter should match only after the start of a line, whitespace
or opening delimiters. But markdown was not configured to respect those
rules which was causing some weird rendering behavior. This commit fixes
the regex used for matching realm filters. On the backend we are using
regex with negative lookbehind to perform matches but since javascript
regex don't support lookbehind we are using a workaround on the frontend
using `contains_backend_only_syntax()` function which detects if a realm
filter can be rendered correctly by backend only and if so it stops the
message from getting echoed locally.
Fixes: #5154.
While we do have some known cases where syntax diverges intentionally,
this change should make it a lot easier to maintain
markdown.contains_backend_only_syntax over time.
It appears that a regression introduced in
3f60074c33 caused undefined to be passed
as the subject to the recent_senders library much more often; this
fixing that, and makes the library handle such cases reasonably
without an exception regardless.
This was causing a huge number of "Tried to call a Dict method with an
undefined key." exceptions.
This mostly moves code, and it also removes some unnecessary
coupling to stream_data.js. The topic_data code purely
works in the stream_id space, so there's no need to set up
actual stream data for it.
We now call topic_data.add_message() and
topic_data.remove_message() when we get info about
incoming messages. The old way of passing in a boolean
made the calling code hard to read and added unncessary
conditional logic to the codepath.
We also have vague plans to change how we handle
removing topics, since increment/decrement logic is now
kind of fragile, so making the "remove" path more explicit
prepares us to something smarter in the future, like just
figure out when the last topic has been removed by calling
a filter function or something outside of topic_data.js.
Another thing to note here is that the code changed here
in echo.js is dead code, since we've disabled
message editing for locally edited messages. I considered
removing this code in a preparatory commit, but there's
other PR activity related to local echo that I don't want
to conflict with.
One nice aspect of removing process_message() is that
the new topic_data.js module does not refer to the legacy
field "subject" any more, nor do its node tests.
This commit introduces a per-stream topic_history class
inside of topic_data.js to better encapsulate how we store topic
history.
To the callers, nothing changes here. (Some of our non-black-box
node tests change their way of setting up data, though, since the
internal data structures are different.)
The new class has the following improvements:
* We use message_id instead of timestamp as our sorting key.
(We could have done this in a prep commit, but it wouldn't
have made the diff much cleaner here.)
* We use a dictionary instead of a sorted list to store the
data, so that writes are O(1) instead of O(NlogN). Reads
now do sorts, so they're O(NlogN) instead of O(N), but reads
are fairly infrequent. (The main goal here isn't actually
performance, but instead it just simplifies the
implementation.)
* We isolate `topic_history` from the format of the messages.
This prepares us for upcoming changes where updates to the
data structure may come from topic history queries as well
as messages.
* We split out the message-add path from the message-remove
path. This prepares us to eventually get rid of the "count"
mechanism that is kind of fragile and which has to be
bypassed for historical topics.
This new module tracks the recent topic names for any given
stream.
The code was pulled over almost verbatim from stream_data.js,
with minor renames to the function names.
We introduced a minor one-line function called stream_has_topics.
We now have all of our callers into recent_topics code just
receive a list of topic names from get_recent_topic_names().
This is more encapsulated than handing off tiny little
structures to the three callers, two of whom immediately
mapped the objects to names, and one of whom needlessly
used the now defunct name canon_subject field.
The consolidation here removes some "subject" references, and
now all lookup are by stream id, not stream name.
The diff here is a bit daunting, but it's mostly simplification
of tests and calling code. Two of the callers now need to look
up stream ids, but they are otherwise streamlined.
The main change here is to stream_data.js, and we replace the
`canon_subject` and `subject` fields with `name`.
We use multiple casings of "lunch" as a topic in our tests, so
that we verify that unread counts respect that topics are
not case sensitive.
We also eliminate an obsolete stub.
Modified timerender.js absolute_time() to include the year
in the returned string when the supplied timestamp is in
an older year. This included adding an optional second
argument to specify the current date to facilitate unit
tests.
Fixes#5737.
This commit specifically addresses the issue when in preview mode,
while "enter sends" is enabled. Previously the messages were just
sent, now they must pass validation.
Fixes#5574.
This allows us to reliably parse the error in code, rather than
attempt to parse the error text. Because the error text gets
translated into the user's language, this error-handling path
wasn't functioning at all for users using Zulip in any of the
seven non-English languages for which we had a translation for
this string.
Together with 709c3b50f which fixed a similar issue in a
different error-handling path, this fixes#5598.
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.
In case the user was not allowed to upload an emoji, we were displaying
two different but sematically same tips. This commit merges them and
also updates `update_custom_emoji_ui()` function in settings_emoji.js
to live update tooltip.