For filter values which don't exist or are invalid in some
way, we return false to show user that there are no messages
in the filter user is trying to render. Our previous behaviour
was to show all the messages and ignore the filter which
isn't good.
The popup that appears when you mute a topic is a bit hard to read,
since nothing makes the topic and stream names jump out from the rest
of the paragraph. Fix this by using bold around the stream/topic and
also cutting a bunch of unnecessary verbiage.
Tweaked by tabbott to further simplify the language.
This reverts commit a00f5dd90e (#17801).
That commit introduced a regression in the portico pages as described
in commit 85b3157b47. Since that fix
introduced a regression of its own, we need to revert both commits for
now.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This reverts commit 85b3157b47.
This broke the × button on Blueslip alert boxes, because @extend does
not work across different PostCSS compilation units.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
The start time of the last password change was the wrong time to use,
because we could start a password change, start another request,
finish the password change, and then observe that the other request
failed due to the password change.
We could use the end time, but a counter is more robust to
sub-millisecond race conditions.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
* We shouldn't use "Search" when we mean "Filter". Filter is correct
here, since we are just showing a subset of what's otherwise shown,
and won't find anything that's older (or whatever).
* The stream/topic wording was unnecessary; the things we're filtering
are topics (E.g. "Filter users" might look at name/email, and is the
right label, not "Filter name/email").
There can be several cases when we don't require a reset button
with the dropdown_list_widget.
Hence, Added an abstraction for dropdown_list_widget that
renders the button only if it's corresponding text is passed.
This commits adds on to 9884226f, which was added to
handle a rare race condition that occurs when the
session hash is not updated by the backend during the
password change process.
It handles a variant race situation where the request was initiated
before/during the password change event and completed after it was
completed. Hence, forcing the page to redirect to the login page.
In a00f5dd90e, we needed to move the
`alert-box` styles from alerts.css to be visible in portico pages.
However, when doing so, we incorrectly moved all of alerts.css, which
also has styles for `alert` and` alert-error` designed to make it
convenient to include hidden elements for potential errors in the
webapp settings UIs directly in the HTML template (and then use
show/hide to manage them).
We fix this by moving just the alert-box scope to the common
components.css module, which is designed as the place for styles
shared between the webapp and portico pages.
This fixes an issue where the error messages for wrong password and
the like were invisible :(.
This commit make compose_ui.autosize_textarea handle most of the autosize
logic of the textarea. It audits for any logic that is trying to do
autosize manually and replace it with compose_ui.autosize_textarea.
This allows to have better check for when the textarea is autosized.
Mainly done this so that we can have a check on #compose-textarea when
to autosize and when not to, thus helping to have all the logic in only
one function.
We now unconditionally enable backgroung events when 'hidden.bs.modal'
event is triggered on closing of modal. We do not need to handle them
separateley for closing modal by close_modal, data-dismiss or escape.
We handle this by single handler for modals in settings and subscription
overlay.
Fixes#16688.
This commit changes the code to not remove the modal element from DOM
after closing the modal for the deactivation stream modal and stream
privacy modal.
This is a prep commit for enabling background mouse events
unconditionally using 'hidden.bs.modal', because removing element
using '.remove' remove all events attached to it and this will also
remove the 'hidden.bs.modal' event which we do not want.
This remove behavior is inconsistent as we remove some of the modals
but do not remove some, so for now we are not removing the modal
after closing but it is anyway removed before opening a modal to handle
case of having two elements of same id and avoids any bugs.
This behavior of when to remove the element from DOM and when to not
remove needs to be discussed and may be modified in future.
We show a modal as a warning when unsubscribing a private stream
because it is a irreversible action and one cannot re-subscribe
tovit until added by other member of stream.
Fixes#9254.
This commit adds "close-modal-btn" class to cancel button in
the modal and cross icon.
We do this change because we would add a modal for unsubscribing
from private stream in further commit using confirm_dialog module.
We would need to avoid the unexpected closing of stream settings
on closing the modal which can be done by calling 'e.stopPropagation'
to prevent propagating of events in other elements.
Thus, adding this class will mean that the handler used for stream
privacy modal for this same task will be used for unsubscribe modal
also.
This commit adds 'close-modal-btn' class to cancel button and cross icon
in the deactivation stream modal.
This change is a prep commit for enabling background events on
'hidden.bs.modal' event. As we would enable background events in furhter
commit using the 'hidden.bs.modal' event, we would need to remove the
'hide.bs.modal' event of deactivation_stream_modal which removes the
element from DOM.
When we remove this event we would need a e.stopPropagation call to avoid
unexpected closing of stream settings which was not a problem previously
because the element was being removed from DOM before actual closing of
modal.
So instead of adding a different handler, we can use the handler used
for stream privacy modal here by adding this new class.
This commit renames the class of both cancel button and the cross
icon to close-modal-btn.
This change is a prep commit for enabling background events on
'hidden.bs.modal' event. As we would enable background events in
furhter commit using the 'hidden.bs.modal' event, we would need to
remove the 'hide.bs.modal' event of deactivation_stream_modal which
removes the modal element from DOM.
When we remove this we would need a e.stopPropagation call to avoid
unexpected closing of subscription settings, which was not a problem
before as the element was removed from DOM before the actual closing
of modal.
So instead of adding a separate `e.stopPropagation' call, we can use
the same handler that is being used for stream privacy modal and this
is the reason the class name of cancel button of privacy modal is
being changed.
We do not remove the stream row instantly from the subscribed list in
subscription overlay when unsubscribing from public streams in most
of the cases but we do so when unsubscribing using hotkey.
This commit makes it consistent by not removing the stream row on
unsubscribing using hotkey.
We also not remove the 'active' class as streams settings is still
open in the right seciton and this behavior is also consistent with
the other ways of unsubscribing.
Note that this behavior is only for public streams, we remove the
stream row in case the stream is private, as user cannot
resubscribe himself and this behavior is consistent across all ways
of unsubscribing.
- Rectifies broken label tag having a misleading 'for' attribute.
- Removed 'name' attribute from unlabelled span tag.
- Removed label expression from DropdownListWidget to built an,
abstraction for control group only.
Fixes#17311.
Restructured dropdown_list_widget template to unwrap label tag
from the control group, hence defaulting the edit_bot
dropdown items to their original text size.
We now consistently set the PM counts for the right
sidebar toggle in unread_ui, similar to what we
do for the overall counts in the left sidebar toggle.
(Use a thin window to see the code in action.)
This breaks a dependency cycle.
In passing I improve the test coverage for the
actual job that pm_list still does (updating its
own total count in the "Private Messages" section).
For messages which we don't have stored locally, we don't update
our data structures. This was actually our behaviour before
59e5f2d8fc, which introduced this
bug.
Not doing this caused a major bug where we ran into errors
moving messages for topics for which we didn't have all
the messages available.
This data structure has never been one that we actually render into
the DOM; instead, its role is to support clicking into view that
contain muted streams and topics quickly.
This downgrade makes that situation much more explicit, and is also
useful refactoring to help simpify the upcoming changes in #16746.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit fixes the 'Your account' settings page to show
correct role of organization owner. Previously it was
incorrectly displayed as administrator.
Commit message tweaked by sahil839.
I lift this function out of message_store to
break some dependencies, and it's also more
consistent with the rest of the codebase:
alert_words.process_message
pm_conversations.process_message
recent_topics.process_messages
recent_senders.process_message_for_senders
We can do further cleanup to make these names
consistent (and possibly have them all work in
bulk), but that's out of the scope of the current PR.
We move the message_store.add_message_metadata function
(and all its dependencies) into a new module called
message_helper and rename the function to process_new_message.
(It does a bit more than adding message metadata, such
as updating our message store.)
We also have a "protected" interface now in message_store,
so that message_helper can access the message store:
update_message_cache
get_cached_message
Because update_message_cache is identical to
the former create_mock_message, we just renamed it
in the tests.
Most callers should use these functions:
message_helper.process_new_message (setting)
message_store.get (getting)
It's slightly annoying that the setter interface
is in a different module than the getter interface,
but that's how you break a bunch of dependencies.
We also extract the tiny message_user_ids class:
user_ids()
add_user_ids()
All the code moves here are pretty trivial, and
the code that was moved maintains 100% line
coverage.
The module name `message_helper` is not ideal, but it's a single
function and it'll save time to just do the topology change now and
leave thinking through the right name to later.
This function should be named similarly to the well-named
end_inline_topic_edit; previously the main hint that this was the
inline code path was just that the recipient_row was the parameter.
Before this we did not have remove event in server_events_dispatch.js
for the user group delete event even though server had. This was
leading to blueslip errors. Extracted the logic which was used in
success() of channel.del for user_groups into the remove case in
server_events_dispatch. Also removed the redundant reload call as
we already do that in server events.
This is a mostly verbatim extraction.
I re-phrased one line of code to work around a lint
false alarm. (Look for `preamble` in the diff.)
There are about 8 lines missing coverage here, so
the new module might be a good candidate to get
100% line coverage on.
Before this change, you would need to remove 74
edges from our dependency graph to make it
acyclic. Now it's 72.
This change does not impact the overall complexity
of our dependency graph (at least in terms of the
number of edges that we would need to remove to get
a tree), but it does clarify the picture a bit.
Rename few functions referencing the "CHOICE" field to
instead use the new "SELECT" name. This is done so that they
can be reused in "SELECT_MULTIPLE" field.
When a user entered an invalid character (whitespace or characters not
present in a name), the cleaned-up array, and hence the query,
would be empty which resulted in an error.
Fixes#17542
We were loading filters from localstorage after rendering the
filters block which caused the incorrect icons being displayed
for filters.
Since usually recent_topics renders a couple times when it
is loaded directly and the filters were being loaded as part of
show_selected_filters after we rendered recent_topics filters,
it meant the correct filters were being displayed in the
second render.
But, when user loads any other narrow directly when Zulip is loaded,
and opens recent_topics, recent_topics is only rendered once,
hence the bug gets noticed.
Fixes#17496
Extend our markdown system to support mentioning of users
by id also. Following these changes, it would be possible
to mention users with @**|user_id** and silently mention
using @_**|user_id**.
Main intention for extending the mention syntax is to make
it convenient for bots to mention a users using their ids. It
is to be noted that previous syntax are also supported.
Documentation tweaked by tabbott for better readability.
The changes were tested manually in development server, and also
by adding some new backend and frontend tests.
Fixes: #17487.
We add support to shorten links and test their shortening in
well-organized, clean manner that makes it trivial to extend the
GitHub approach for GitLab and perhaps other services.
We only shorten basic types of GitHub links (issue, PR, commit) that
fit a set of simple common patterns; the default behaviour of Autolink
is kept for everything else.
Logic added in frontend and backend Markdown Processor is identical.
This makes easy to extend the logic for other services like GitLab.
Fixes#11895.
The only reason to use typeof foo === "undefined" is when foo is a
global identifier that might not have been declared at all, so it
might raise a ReferenceError if evaluated. For a variable declared
with const or let or import, a function argument, or a complex
expression, simply foo === undefined is equivalent.
Some of these conditions have become impossible and can be removed
entirely, and some can be replaced more idiomatically with default
parameters (note that JavaScript does not share the Python misfeature
of evaluating the default parameter at function declaration time).
Signed-off-by: Anders Kaseorg <anders@zulip.com>
These were introduced in ff9a929d7a
with no explanation of why they were necessary.
Generally you only render a few things, and it's
important that they're up to date.
We weren't doing a good job of invalidating the cache.
Eliminating the cache will fix bugs (like presence circles
being out of date) and break some dependencies.
I removed some very fragile test code that was relying
on invalid values taken out of the cache. (We now have
less line coverage, but if we want to test our rendering,
there are much cleaner ways to do it.)
As part of testing this, I renamed Hamlet to "aaron", so
that there are two aarons, and then I logged on as Iago
to see the "secondary" code in action that shows their
emails to distinguish them.
This add the schema checker, openapi schema, and also a test for
realm/deactivated event.
With several block comments by tabbott explaining the logic behind our
behavior here.
Part of #17568.
This helper was added in eac6463031 and
used by the "message.handlebars" file. This is no current call for
this helper in the codebase, hence it is removed to improve coverage.
This commit also marks template.js to have 100% test coverage.
This adds support for unstarring all (starred)
messages from a particular topic, from the topic
popover.
The earlier implementation of this in #16898
was reverted in bc55aa6a01 (#17429)
because it had two problems-
1. The crash reported in bc55aa6a01
was due to message_store returning undefined. This happens
when the message itself hasn't been fetched from the server
yet, but we know that the message is starred from the ids
in `page_params` in `starred_messages.js`.
This commit handles this case explicitly.
Note that, we simply ignore those messages which
we haven't fetched, and because of this, it may
happen that we don't unstar some messages from that
topic. The correct implementation for this would
be to ask the backend for starred IDs in a topic.
2. The earlier implementation actually unstarred **all**
messages. This was because it grabbed the topic and stream_id
from the topic popover `data` attributes, after the topic
popover had been closed. This passed `undefined`, which
the function then interpreted as an action to unstar all
messages.
With this commit, we use the confirm_dialog widget,
which eliminates the need to store this data in the DOM.
* Currently, the confirm_dialog is used only in
the settings pane, which already has the `new-style`
class in the main `settings_overlay.hbs` file. So,
the confirm modal is rendered correctly there. But to
make it available for use outside of the settings pane,
we add the `new-style` class to the confirm container
itself, without which, the buttons look ugly.
* The other change here is the click handler for
removing the modal element. Previously, when the
modal was closed (with any of the "yes"/"no"/"cross"
buttons), there was a small time interval of around
a second during which the modal had disappeared,
but the background content was still in the faded-out
state. This change fixes this glitch. This glitch was
probably not noticable earlier, because the settings
pane itself causes the background to be slightly faded
out.
This code was added in 2d414fa897, after
the `window.exports` variable was removed from
`stream_popovers.js`, while converting it to an ES6 module
in c71af35461. This resulted
in opening the starred messages or all messages
popovers throw `Error: exports in undefined.`.
Follow up to #14768. This feature was already non-functional due to
.alert-display { display: none; }, and if we want to reimplement it,
we should do it using a modern library.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Remove the unused notifications-area wrapper. Remove the feature
detection code as all browsers recognize the <audio> element. Create
the <audio> statically with the page template. Use multiple <source>s
to let the browser detect the appropriate format instead of trying to
do its job for it. Remove the absurd loop="yes" attribute, which had
fortunately been specified on the wrong element.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This is mostly a refactoring to break the unnecessary
dependency of bot_data on settings_bots.
This is a bit more than a refactoring, as I remove all
the debounced calls to render bots during the
initialization of bot_data. (The debouncing probably
meant we only rendered once, but it was still needless
work.)
We don't need to explicitly render bots during
bot_data.initialize(), which you can verify by loading
"#settings/your-bots" as the home page. It was just an
artifact of how add() was implemented.
Note that for the **admin** screen, we did not and
still do not do live updates for add/remove; we only do
it for updates. Fixing that is out of the scope of this
change. The code that was moved here affects
**personal** bot settings.
Note that the debounce code is quite fragile. See my
code comment that explains it. I don't have time to go
down the rabbit hole of a deep fix here. The puppeteer
tests would fail without the debounce, even though I
was able to eliminate the debounce in an earlier
version of this fix and see good results during manual
testing. (My testing may have just been on the "lucky"
side of the race.) I created #17743 to address this
problem.
The keyboard-shortcuts icon currently has a fix position
causing design related bugs such as overlapping with userlist
in the sidebar.
The fix wraps the invite-more-users link and keyboard icon inside
a div with display property as flex instead of just using the anchor
tags inside the side-bar items.
This mainly extracts a new module called
browser_history. It has much fewer dependencies
than hashchange.js, so any modules that just
need the smaller API from browser_history now
have fewer transitive dependencies.
Here are some details:
* Move is_overlay_hash to hash_util.
* Rename hashchange.update_browser_history to
brower_history.update
* Move go_to_location verbatim.
* Remove unused argument for exit_overlay.
* Introduce helper functions:
* old_hash()
* set_hash_before_overlay()
* save_old_hash()
We now have 100% line coverage on the extracted
code.
I moved four functions, verbatim, to a new module.
They were in message_util before, which led to
filter.js having several accidental indirect
dependencies.
I considered just putting these four functions in
filter.js, but I think it's a nice abstraction boundary
that filter.js delegates actual message parsing, and
the original author apparently had a similar thought
process.
I also wanted to make it so that a casual reader of
filter.js doesn't think we are manipulating DOM. It's
true that we still indirectly require jquery here, but
it's only for parsing, and it seems plausible we would
eventually use a more low-level parser.
I can see us maybe using these functions in something
like MessageListData in the future, so speculatively
splitting them out might future-proof us from some
cyclical dependencies.
I also think it's plausible that we will just modify
our two markdown processors to attach that kind of
metadata to the messages.
Last but not least, I think there might be opportunity
here to simplify the filter tests and remove some of
the zjquery hacks. We would instead just mock the
message_has_* helpers for the filter tests, and then
do more detailed direct testing on the functions
themselves.