ES and TypeScript modules are strict by default and don’t need this
directive. ESLint will remind us to add it to new CommonJS files and
remove it from ES and TypeScript modules.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Prettier would do this anyway, but it’s separated out for a more
reviewable diff. Generated by ESLint.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
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>
With webpack, variables declared in each file are already file-local
(Global variables need to be explicitly exported), so these IIFEs are
no longer needed.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
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.
Returning true from this function means we go on to send, or extend
the lifetime of, a typing notification; returning false means we don't.
It's hard to see why having a partially-entered name in the recipient
box should mean we're *more* inclined to send a typing notification to
the set of recipients that are already entered; if anything, it seems
like it should make us *less* inclined to do so. So we're better off
without this conditional.
The conditional was introduced in commit 72295e94b, as part of a
conversion from user emails to user IDs; there, it seems to replace a
condition that went in the opposite direction, returning *false* if
there were any invalid emails in the recipient box. So perhaps it's
just inverted.
Moreover, the (re-)inverted version would also be wrong: if the user
is typing a PM addressed to some users, and they hit send, the message
will go to those users whether or not they have any unconverted text
in the recipients box. So the typing notifications should too.
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.
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>
These indeed used to be strings, but were converted to arrays in
b8250fc61, and these names didn't get updated to match.
A classic example of why type-checking is a great job to get
machines to do. :-)
When typing_status adds 10000 to this value, it would previously
obtain wacky strings like
"Fri Oct 04 2019 16:45:59 GMT-0700 (Pacific Daylight Time)10000"
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
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.
We now ask compose_pm_pill to give us a list of user
ids that we are PM'ing to, and we only convert user
ids to emails right before we put requests on the wire.
We also let the "pill system" tell us whether we
have unconverted data.
It also sets up for an upcoming server change where we
can just send user ids to the server.
This change should be transparent to the majority of users.
For Zephyr users we are slightly less aggressive about
sending typing indicators, since we now require valid
user ids.
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.
We now wait to start typing notifications until everything else
is initialized. This prevents traceback where things like compose
pills have not been initialized.
Also adds a custom rule to eslint. Since the recommended way of extending
eslint is to create plugins as standalone npm packages, the separate rule
is published as 'eslint-plugins-empty-returns'.
Fixes#8669.
This commit helps reduce clutter on the navigation sidebar.
Creates new directories and moves relevant files into them.
Modifies index.rst, symlinks, and image paths accordingly.
This commit also enables expandable/collapsible navigation items,
renames files in docs/development and docs/production,
modifies /tools/test-documentation so that it overrides a theme setting,
Also updates links to other docs, file paths in the codebase that point
to developer documents, and files that should be excluded from lint tests.
Note that this commit does not update direct links to
zulip.readthedocs.io in the codebase; those will be resolved in an
upcoming follow-up commit (it'll be easier to verify all the links
once this is merged and ReadTheDocs is updated).
Fixes#5265.
We now only call compose_state.composing() in a boolean context,
where we simply care whether or not the compose box is open. The
function now also returns true/false.
Callers who need to know the actual message type (e.g. "stream" or
"private") now call compose_state.get_message_type().
This change moves most of the logic related to starting and
stopping outbound typing indicators to a new module called
typing_status.js that is heavily unit tested.
While this was in some sense a rewrite, the logic was mostly
inspired by the existing code.
This change does fix one known bug, which is that when we
were changing recipients before (while typing was active), we
were not stopping and starting typing indicators. This was
a fairly minor bug, since usually users leave the compose
box to change recipients, and we would do stop/start under
that scenario. Now we also handle the case where the user
does not leave the compose box to change recipients.
The old code may have had some subtle bugs related to sorting of
ids or stringification or failed Dict lookups. The new data
layer should be more robust. We had some tracebacks recently
from the old code, and they should go away now.
Send typing notification events when user types in the compose box.
Listen for these events and display a notification.
Sending notifications: Notifications are throttled, so that start
notifications are sent every 10 seconds of active typing, and stop
notifications are sent 5 seconds after active typing stops or when the
compose box is closed.
Displaying notifications:
When a typing notification is received, if the current narrow is private
messages or is: pm-with and the user is not the sender,
"Othello is typing..." is displayed underneath the last message. This notification is
removed after 15 seconds. If another notification is received during this period, the
expiration is extended. When a stop notification is received the notification is removed.
Internally, a list of users currently typing is maintained for each
conversation (in a dict). When an event is received the list (for the appropriate
conversation) is updated and the notifications template is re-rendered
based on the narrow information. This template is also re-rendered when
the narrow changes.
Significantly modified by tabbott for clarity.
Fixes#150.