Explicitly stubbing i18n in 48 different files
is mostly busy work at this point, and it doesn't
provide much signal, since often it's invoked
only to satisfy transitive dependencies.
We now treat util like a leaf module and
use "require" to import it everywhere it's used.
An earlier version of this commit moved
util into our "shared" library, but we
decided to wait on that. Once we're ready
to do that, we should only need to do a
simple search/replace on various
require/zrequire statements plus a small
tweak to one of the custom linter checks.
It turns out we don't really need util.js
for our most immediate code-sharing goal,
which is to reuse our markdown code on
mobile. There's a little bit of cleanup
still remaining to break the dependency,
but it's minor.
The util module still calls the global
blueslip module in one place, but that
code is about to be removed in the next
few commits.
I am pretty confident that once we start
sharing things like the typeahead code
more aggressively, we'll start having
dependencies on util. The module is barely
more than 300 lines long, so we'll probably
just move the whole thing into shared
rather than break it apart. Also, we
can continue to nibble away at the
cruftier parts of the module.
We just get the stream_name from the sub struct now.
This mostly affects node tests.
The only place in real code where we called add_sub()
was when we initialized data from the server.
This reverts commit d84646f091 (which
incorrectly assumed in unread_topic_counter that the messages were
present in the message store), while fixing the type confusion problem
by using IntDict for stream_id keys.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Fixes type confusion in unread_topic_counter, which uses stream IDs as
keys.
Since unread_topic_counter calls message_store.get now, update the
mocks so that message_store.get knows about our mocked messages.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
Note that we haven't fully swept this for Dict,
since some dicts are keyed by strings. For
example PM counts can have a huddle like
"101,102,103" as a key.
When we are pulling data from message.display_recipient
for private messages, the user_id field is always
called 'id', not 'user_id', so we can simplify
some defensive code.
We now require the actual tests to explicitly
to zrequire Dict, rather than magically adding this.
In one case, the use of Dict was clearly just for
the test (not the app), so I converted that an ordinary
JS object (see timerender.js).
We have ~5 years of proof that we'll probably never
extend Dict with more options.
Breaking the classes into makes both a little faster
(no options to check), and we remove some options
in FoldDict that are never used (from/from_array).
A possible next step is to fine-tune the Dict to use
Map internally.
Note that the TypeScript types for FoldDict are now
more specific (requiring string keys). Of course,
this isn't really enforced until we convert other
modules to TS.
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>
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.
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>
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 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.
Apparently, we didn't have one of these, and thus had a moderate
number of generally very old violations in the codebase. Fix this and
clear the ones that exist..
This fixes the most core data structures inside of
muting.js. We still use stream names for incoming
data to set_muted_topics and outgoing data from
get_muted_topics.
This will make us more resilient to stream name changes.
Before, if you were logged on when a stream rename
occured, topics that were muted under that stream would
appear to be unmuted. (You could fix it with a reload,
but it can be jarring to have a bunch of unread messages
appear in your feed suddenly.)
Fixes#11033
We will need this for cases where the topic names in
unread.js are a superset of the names we got from messages.
It's important to pass in a dict of existing dicts to avoid
expensive max() calls to get the max ids of topics (otherwise
the plan would have been to merge the lists in the caller).
This run_test helper sets up a convention that allows
us to give really short tracebacks for errors, and
eventually we can have more control over running
individual tests. (The latter goal has some
complications, since we often intentionally leak
setup in tests.)
Even though starred messages are never unread, it's useful
for us to have helper functions for them.
This change makes it so that clicking on "Starred Messages"
takes you to the last read message immediately, without a
server delay.
In the JS code, we now use `message.unread` universally as
the indicator of whether a message is unread, rather than
the `message.flags` array that gets passed down to us
from the server.
In particular, we use the unread flag for filtering when
you search.
A lot of this commit is just removing logic to add/remove
"read" from `message.flags` and updating tests.
We also explicitly set `message.unread` to `false` inside of
`unread.mark_as_read()` and no longer have `unread.set_flag()`.
(Some of the callers to `unread.set_flag` were also calling
`unread.mark_as_read`, which was updating the `message`
object, so now we just have `unread.mark_as_read` update
the `message` object. And then unread_ops.mark_all_as_read()
was already calling unread.declare_bankruptcy().)
This adds two similar functions to simplify
our batch processing of unread messages.
unread.get_unread_messages
unread.get_unread_message_ids
They are used to simplify two functions that loop
over messages. Before this change, the functions
would short circuit the loop to ignore messages
that were already read; now they just use the
helpers before the loop.
This reverts commit c953759486.
The client side logic for dealing with server counts is actually
fine, as far as we know, but there are still some data-related
issues with cleaning up old unread counts.
The server sends down lists of unread message ids in various
buckets, and we now use those on the client to provide more
complete counts of unread messages.
If you read a message, then got a topic edit for it, we were
adding the message to our data structure of unread stream/topic
messages.
Now we guard against this in unread.update_unread_topics. I
no longer expose an update() method in unread_topic_counter,
since we really want to do the unread check at a higher level
to keep other data structures consistent.
This code adds 'read' to message.flags and sets message.unread
to false.
It's not clear that the boolean message.unread is used in any
meaningful way, but we set it to false to avoid confusion. The
bankruptcy code was not doing this before.
Another quirk that existed before was that you could get two
'read' flags in a message when you declared bankruptcy. It's
also plausible that this could happen if you marked a message
as read via two different ways. It probably did not cause
user-facing bugs, but it would be confusing for troubleshooting.
Fixes#5032.
This function allows us to see whether unread.js thinks a message
id is unread (as opposed to looking at the message itself). This
method is useful when we get notifications from the server that a
message has been read. In the future, we may not actually have
a local copy of an unread message, but we'll still know that it is
unread based on page_params. We'll want to update the data in that
case.
Going forward, we'll want to deprecate message.flags for most use
cases and just use the unread.js data structures to track unread
messages.
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.
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.
This commit changes stream_data.in_home_view() to
take a stream_id parameter, which will make it more
robust to stream name changes.
This fixes a bug. Now when an admin renames a stream
you are looking at, it will correctly show itself to
be un-muted. (Even with this fix, though, the stream
appears to be inactive.)
Some callers still do lookups by name, and they will
call name_in_home_view() for now, which we can
hopefully deprecate over time.
Despite the length of this commit, it is a very straightforward
moving of code from narrow.js -> narrow_state.js, and then
everything else is just s/narrow.foo()/narrow_state.foo()/
(with a few tiny cleanups to remove some code duplication
in certain callers).
The only new functions are simple setter/getters that
encapsulate the current_filter variable:
narrow_state.reset_current_filter()
narrow_state.set_current_filter()
narrow_state.get_current_filter()
We removed narrow.predicate() as part of this, since it was dead
code.
Also, we removed the shim for narrow_state.set_compose_defaults(),
and since that was the last shim, we removed shim.js from the app.
Our unread.js code basically silently treats empty recipient
strings or unknown streams as having zero unread messages,
which is probably the correct behavior. We now have tests
that cover this. This commit also gets us to 100% line
coverage on the module (but not yet 100% branch coverage).
When we process messages for unread counts, we now call
people.pm_reply_user_string() to get a string of user ids,
rather than using emails that may have changed since the
message was originally created.
In people.emails_strings_to_user_ids_string, we just warn
for bad emails going forward.
Users can enter bad emails into the search location bar,
for example, and that causes us to compute a browser hash,
which in turn uses this function.
(It's possible that we should adjust the search code not
to compute hashes for narrowing when the narrow doesn't
make sense, but that could be a non-trivial fix.)
This change introduces an unread_topic_counter object
that manages unread counts for streams and topics. Consolidating
all the logic into a single class will set us up to add
logic for dealing with topic counts that includes provisional
counts of unread messages from the server. It also makes
the current code a little easier to reason about.
Most of this change was simply extracting functions, but
I also removed a few unnecessary and inconsistent calls to
`stream_data.canonicalized_name` that preceded our use of
Dict with a fold_case argument.
* In most cases, eslint --fix with the right comma-dangle settings was
able to update the code correctly.
* The exceptions were cases where the parser incorrectly treated the
arguments to functions like `assert_equal` as arguments; we fixed
these manually. Since this is test code, we can be reasonably
confident that just fixing the failures suffices to correct any bugs
introduced by making changes automatically.
We now use comma-delimited lists of user_ids for the following
data structures in unread.js:
- unread_privates[<user_ids_string>]
- get_counts.pm_count[<user_ids_string>]