Previously, we had this complicated layering where the right sidebar
logic would display "Last active: foo" but the user popovers would
just display "foo", which doens't make any sense, since the two
settings have equal context about the string.
We deduplicate that and also arrange that the "Last active:" prefix is
used when it's not clear what we're talking about; i.e. all the values
except for "Active now".
There is no clear reason to not use a button element here. According
to the spec pharasing content, which includes the <span> element,
are allowed in the button element.
Manually tested both buttons to make sure it works and made sure all
the selectors are updated by grepping all the selector classes/id in
the handlebars templates that are parents of the button or are
present on the button.
(One of the jQuery handler code got reformatted due to it fitting
the line limit due to one character deletion for the selector)
Modified resend_invite modal heading to remove the email
field to avoid it's duplication, since the email feild is
also displayed within the actual modal body.
Tested by the adding a console log to the handlers and typing Tab
and Enter in the group PM and stream compose box. This two event
handlers are attached to form#send_message_form which is the compose
box form.
The tests set keyCode to 42 previously, which does not represent a
valid key, so I assume they were trying to test a random key, and
replace it with "a".
There is no functionality change caused by this change. We turn the
event key to lowercase so hotkeys work even when Caps Lock is on as
it did before.
Tested by using the keybinds with and without Caps Lock in compose
box:
- "Ctrl + B" and "Ctrl + Shift + B",
- "Ctrl + I", and
- "Ctrl + Shift + L".
(Also tested that "Ctrl + Shift + I" and "Ctrl + L" do not work.)
Tested by doing the following in the compose box input for PMs:
- "Enter" works as expcected with and without input
- "Backspace" when there is no input deletes the last pill
- Left arrow in the input focuses last pill
- Comma works as expected for correct and incorrect input
- Left arrow, Right arrow and Backspace work correctly for pills.
We use e.key for our side of code and still pass e.keyCode and
e.which to the custom jQuery event we trigger. The event is handled
by our patched copy of outdated bootstrap and it still requires the
e.keyCode and e.which properties.
One of the places this widget is used is in the settings panel, at
Manage Organization > Organization Settings > Notifications > New
stream notifications. One of the handler is attached to the
dropdown menu items that shows up when you click the "#announce"
button. The other one is attached to the search button. The second
one triggers the custom jQuery event and passes the event data to
bootstrap unless the Up & Down arrow or Esacape is used. The first
event handler handles the Enter click on one of the items and saves
it. Verified that the widget works as expected.
Tested by making sure Enter is treated as click at one of the places
this function is used, recent topics view. Using the keyboard to
focus the mute or read button and click Enter treats it like a
click.
Tested by making sure pressing Enter in the input field of the
changed organization settings (the organization name for example)
clicks the save changes button if present.
This change fixes a bug where pressing Enter does not save the
changes as expected, due to an incorrect selector, when the
save/discard changes button shows up in settings. Tested by changing
the Organization name and pressing Enter at Manage Organization >
Organization profile > Organization name.
The Giphy SDK sends tracking pings when it loads; we don’t want those
to be sent for visitors who aren’t using Giphy.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
We were passing new_stream_id as undefined in case of topic
edit as event.new_stream_id is undefined in that case.
We pass the correct stream_id to fix it.
The Event.which and Event.keyCode are deprecated as pointed out by
TypeScript intellisense based on the jQuery types. We use Event.key
instead which behaves similarly to Event.which & Event.keyCode for
our use case.
The only difference in functionality by this change is that the vim
keys won't work when Caps Lock is on. This is because, in this case,
the key property will be "J" instead of 'j'. We can fix this by
adding a mapping for this, however, I think we don't want to handle
this case so I left this change out. Tested by trying out the
everywhere keydown_util is used.
Finally, we also turn off the new-cap rule for tests since I think
it fine to only enforce it on real code and exempting test code is
fine.
This commit disables the button and shows a loading spinner on
the button when signup request is being processed to avoid race
conditions caused by user clicking on the button multiple times.
The fix is done observing that for the case when form is invalid
the whole page is rerendered and thus we do not need to remove
the spinner and enable the button again and for other errors
we redirect to some other page.
And for the validation taking place in client-side, the button
is disabled and spinner is shown, only is form is valid, by
using "$('#registration').valid()".
We live update the "Add subscribers" UI on subscribing/unsubscribing
the stream and the field sub.can_add_subscribers is used to check
whether user is allowed to add subscribers or not.
The sub object used here is not the complete sub object and thus
sub.can_add_subscribers is undefined. We need to use the updated
sub obejcts with all the setting fields that we can get from
'stream_settings_data.get_sub_for_settings' before rendering UI.
This calculation of additional fields was done previously by
'stream_data.update_calculated_fields', but in d50462568b
call to 'updated_calculated_fields' was removed with the aim to
call 'get_sub_for_settings' before updating UI which was missed
in this part of UI update.
Fixes#18616.
Source in pill_typeahead, was intialized in a
very tricky way. In this cleanup, we refactor it
to clearly reflect how source is initialized for
different cases. These changes do not change its
behavior for its current use and solve potential
issues, so that it could be safely used at places
that do not require user pills at all.
In options that we pass to pill_typeahead.set_up we
specify if we want typeahead to support stream or
user_group pills, and use users as source by default.
Using users for source by default, can have unnecessary
suggestions in typeaheads where only user_groups or streams
are needed.
So to solve that, we specify if we want users pill in the input.
This is then utilized in further commits, to clean up hacky code
that deals with intializing source for typeahead.
We make the typeahead a little more nicer but only showing one alias
per language. For example if the user searches for prefix "j", then
the typeahead list should contain "javascript" only, and not "js" and
"javascript".
When muted user's message is revealed, popover should have
an option for hiding the message again. But in case if the
popover is already open while message is being revealed then
option for undo reveal in the popover could be out of sync.
To avoid this, we hide the message actions popover before
revealing muted user's message.
Tooltips in message action buttons for failed message were
not shown properly because they were initialized two times
first because of general tippy-zulip-tooltip class and then
because of message_control_button class. So to avoid showing
an extra empty tooltip for failed message icons we return
false from onShow() method of message_control_button class
initialization of tooltip.
This check was not needded as it is possible to have even zero
edit message buttons in cases when a message is fails. So it
raises unncesary errors on hovering over icons of those failed
messages.
Since this is currently only useful to interpret presence data, we
send this only if presence is requested.
I'm not sure that server_timestamp is the right name for this field,
but ultimately it should match the main presence API format.
When quoting a reply or mentioning a person having full name matching
wildcard mention, in such case, `get_mention_syntax` doesn't return
mention syntax of format: **full_name|user_id**.
As a result, a normal user can't mention such users and users who
can mention them may unwillingly trigger wildcard mention.
This commit fixes such issue.
Prior to this, we restricted to show any user group suggestions
if silent mention syntax is used. But with the addition of
user group silent mentions, there are cases where one may want to
refer to some user groups without actually notifying them.
So, we add typeahead logic for such cases.
Test cases for silent syntax (@_*) and non-silent syntax (@*)
are added.
The regex could have match a bunch of characters including `>`
and hence end up matching across multiple adjacent spans in
a weird way. This commit fixes such an issue.
We add a '?' icon besides the "GIPHY integration" label of
giphy settings dropdown.
The icon links to readthedocs page for setting up giphy API
key when api key is not set, and it points to help center
article of GIFs when the api key is added.
The extracted logic is in linkifier.js.
We have decided to name it linkifier.js instead of realm_linkifier.js
because in future when we will add stream-level linkifiers, we'll
likely want them to be managed by this same file.
We fix the code to show giphy icon live update only if the
updated setting is not disabled and API key has been added.
Though the dropdown is disabled,the setting can still be
changed using API, so this change is necessary.
Previously, we were not checking whether API key is there or
not and icon was shown on live update even if API key was
not there and then it went off on reload.
The command:
codespell --skip='./locale,*.svg,./docs/translating,postgresql.conf.template.erb,.*fixtures,./yarn.lock,./docs/THIRDPARTY,./tools/setup/emoji/emoji_names.py,./tools/setup/emoji/emoji_map.json,./zerver/management/data/unified_reactions.json' --ignore-words=codespell_ignore_words.txt .
The content of codespell_ignore_words:
```
te
ans
pullrequest
ist
cros
wit
nwe
circularly
ned
ba
ressemble
ser
sur
hel
fpr
alls
nd
ot
```
The inconsistent style between these three buttons looked bad.
We have to take some care with the "Starred messages" and "Edit" ones,
to make sure they live-update properly.
Previously, the focus event tends to skip the first
element within the dropdown list when the user presses
the down arrow.
Added a stopPropogation event for keydown handler within
dropdown_list_widget which propoerly binds the focus
event to the dropdown list items.
Previously, the "Move topic" option was only displayed to organization
administrators, despite the new setting making who can move topics
between streams configurable.
Making this migration requires us to remove the text on the previous
"Admin actions" divider, and just make it an hrule, to avoid confusing
normal users, while still providing a hint that moving topics is a
non-personal operation.
We also change the ordering for consistency.
This commit adds the dropdown in 'Stream settings' section of organization
permissions page to control who can move messages between streams and
also hides the stream-edit UI in message-edit form accordingly.
Fixes#14499.
This also handles a few other places missed earlier like
narrow headings, beacuse they use the same function.
We already rerender the PM list for events, so there's no
need to do anything special when someone is muted/unmuted.
`people.get_full_names` is now only used in the settings pages
while creating ListWidgets etc, so we add a new test for
it to ensure coverage.
Directly rendering the default view on pressing `escape` key will lead
to default_view being rendered on the current window hash. So, we set
empty hash to load default view and let hashchange handle it.
This fixes a bug introduced in
59a45d3521.
Long ago, we changed Zulip to inspect server-provided topic history in
our compose and search typeahead modules, but did not trigger a query
to the server to fetch data.
This could result in confusing experiences where someone thought that
a topic doesn't exist that just isn't present in recent history.
Once we merge this, we may want to adjust the messaging in typeahead
to advertise that the first option will create a new topic, since this
change may make it feel more like creating topics is a heavyweight
operation.
Fixes#9857.
We’re getting unexplained exceptions from URL.createObjectURL in
Firefox 88 (#18374); contain them to this function.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Previously, the hook to save drafts when closing the compose box was a
focusout on #compose-textarea. This mostly worked, and was essentially
invisible to users (because the animation to notify you about saved
drafts was in the close_compose_ui widget that is hidden), but you'd
end up seeing the tooltip appear (in the wrong place) if you closed
the compose box immediately after sending a message with Tab+Enter.
The correct fix is for the drafts hook to be just before we start
clearing compose box state, inside hide_box.
This was difficult to catch in a development environment, since one
doesn't use that flow with "Enter sends" enabled.
We were apparently not using the ListWidget API for replacing the
content of a widget without removing the whole thing from the DOM and
replacing it.
Unless ListWidget has unexpected bugs, this should have the exact same
result as the previous logic, with much a nicer user experience.
We use styling same as that of the number shown for overflow
(e.g "+3") which has a gray background.
To keep these avatars up-to-date, we need to rerender the
recent topics view after receiving a `muted_users` event.
Also update the user documentation to mention this detail.
We deliberately avoid mentioning "recent topics" because
this applies to mobile too.
This seems more consistent with what users would expect; Recent topics
may be a better default view in general, but if a user has picked
another default view, we should use that where the default view is
desired.
The default label for empty narrows depends on whether it's a
stream/topic narrow or a PMs narrow.
We leave some default text in compose.hbs for reply label
because it take some time for the js to display the
correct label.
The browser seems to autofill the `Name` field of the add-playground
form. Most likely this behavior is a result of value of the `name`
input field being `name`, causing the browser do to something weird
here. This name is now changed to `playground_name`.
The old logic, inline in the compose area, has produced a very weird
effect where the buttons would move to fit the notification, ever
since design changes to use the full bottom row space.
We address this by just using a Tippy tooltip instead.
Share code between `safe_full_names` and `get_display_full_names`
functions, and rename `safe_full_names` to `get_full_names_for_poll`,
because that was the only place where this was used earlier.
This also has the nice side effect of showing "Muted user" instead
of the muted username in poll results.
Instead of changing the hash to the default_view hash, we render
the default_view directly in case of recent topics and all messages.
This also fixes the bug that user is unable to go back in
browser window history.
We don't want to rely on browser hash to check if RT is visible
because soon we want to display default_view without any hash
and RT may or may not be visible in that hash.
Active stream's hash look like this - `#streams/1/announce`
Since the stream_id is present where typically hash section
is for all other hashes, get_current_hash_section should return
the same result.
Added a commit to bind vim keys with the SettingsPanelMenu,
allowing users to control the settings and organization tabs
using 'h','j','k' and 'l' keys.
vim_left('h') -> Switch between tab by shifting focus to the left.
vim_right('l') -> Switch between tab by shifting focus to the right.
vim_up('k') -> Move up.
vim_down('j') -> Move down.
Also link to it from the API documentation page,
other help pages, and the confirmation dialog for
muting a user.
With substantial edits by tabbott and alya.
To calculate the max-height of buddy_list_wrapper, we use
invite-link-height. This works alright if inviting is enabled
for all. However for users who aren't permitted to invite,
the element does not render, hence the logic uses `0` as
default value for subtraction in `get_new_heights` function
under resize.js. This leads to the keyboard-shortcut icon
rendered below the browser window. Hence use the parent div
`right-sidebar-shortcuts` height for the logic.
* Remove unnecessary json_validator for string parameters.
* Update frontend to pass right parameter.
Bump api feature level and highlight the fix for `emojiset`
parameter of `settings/display` endpoint in zulip.yaml file.
Fixes part of #18035.
* Remove unnecessary json validator for string validator.
* Update frontend to pass right validator.
* Update zulip.yaml to pass right parameter for curl request
in openapi.
* Update python_examples to pass right paramater.
Fixes part of #18035.
Commit ad76df25ac (#18405) uses Map
incorrectly. A JavaScript Map needs to be indexed with .get() and
.set(), not with [].
Also, clean up the API: ‘lookup_table’ is a meaningless variable name,
and there was no information in the array that wasn’t also in the Map.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
The previous `top_offset` calculation didn't include the height
of the panels which led the calculations to be performed as if
a portion which was hidden behind the searchbox, was visible to
the user.
The new formula is corect as the frb_top calculation in
panel.resize_app also uses panels_height.
A modal is added to edit the realm linkifier which
supports ui_report error.
Puppeteer tests to verify linkifier update and an
invalid test to verify that linkifier error messages
are reported on the modal are added as well.
Implemented dropdown_list_widget in Move topic popover which enables,
the functionality to search for streams while moving a particular topic.
The aim is to reduce the user effort by having an input
typeahead instead of haivng a dropdown list of streams.
Closes#14860.
Previously, the focus event was triggering on a hidden
dropdown input field, which caused it to not gain focus when
clicked on dropdown button.
This is so because focus events cannot be triggered to
hidden elements or elements that aren't visible in DOM.
Added a fix by explicilty triggering the focus event to
dropdown input field only if the input field is visible in the DOM.
This is good to do in general for these type of event handlers
and this also fixes a bug where pressing on reply button in
the recent topics will open compose with a new line since
browser assumed enter was pressed on compose_textarea since
process_enter_key returned false.
Since we support hooking up code playgrounds for custom languages
outside of the list of languages supported by Pygments, we display
an option to select a "Custom language" in the typeahead.
The `pygments_name` field typeahead shows a list of human-readable
`pretty_name`to pick from. However, the Pygment aliases which are
used for code highlighting within a code block are different from
these. This mismatch might be confusing for folks unfamiliar with
technical details of the "code playgrounds" feature.
To bridge the gap, we now include the Pygment aliases within
parenthesis along with its human-readable name, in the typeaheads.
E.g: Python 2.x (py2, python2).
Added a fix to bind vim_up(k) and vim_down(j) keys
with the draft section, allowing users to scroll
between the drafts using 'k' (scroll up) and
'j'(scroll down) keys.
Fixes#18397
Previously, we used to hide 1:1 PMs with muted users everywhere
in the UI. This commit makes it so that such messages will now be
visible in `pm-with/<muted_user>` narrows, meaning these will not
be excluded from message lists, but will still be hidden under
the "This message was hidden." dialog implemented earlier.
* We hide 1:1 PMs from and to muted users throughout
the UI, because doing so will not lead to loss of
conversational context. The "to" part is also important,
because the last few messages sent to a user before
muting them would probably be asking them to stop
spamming.
* After this change, we will need to do filtering for either
user or topic muting in pretty much all narrows, so we need
to keep the `_all_items` list in MessageListData always
up-to-date.
* A further commit will relax this and make it possible to
view these messages only when in a `pm-with/muted_user`
narrow.
This basically reverts 4bd7ec7c36 and
3a9dfc02e6.
The plan earlier was to have compeletely different codepaths
for user and topic muting, so that we could call seperate
functions in the message list class on receiving the respective
events.
However, this cannot be done, because if we, for example, on
receiving a `muted_users` event, filter `_all_items` based on
just user mutes, and store the result in `_items`, then, that
result may still contain topic-muted messages, which is
undesirable. Hence whenever we filter messages, we must do so
based on both user as well as topic muting.
(The code for the former will be added in further commits.)
So, we will have a single function which will handle updating
the message lists for muting.
We were losing scroll position after re-render because there
were not enough rows present in the table to focus back to
the same position. With this commit it is possible now since we
always render with enough rows to do so.
We save the scroll position of the user by keeping the topic
row at the center of the visible scroll container in focus. The
avoids focus being reset to first topic row when recent topics
renders. Thus, this improves the UX of recent topics.
Add a function which is called before every render to
get the number of items it can render. This can be used by
instance to load custom number of items as per its state.
We allow ListWidget instances to pass functions in opts that can
be called after scrolling to determine when to render.
Also, allow a callback function to be called pre render.
We move compose from being a part of message feed to
being a part of middle column which is a common parent of recent
topics and message feed. This allows us to use a common compose
box for both the views. Fortunately, compose actions were
independent of this change so there weren't any evident
side effects.
Fixes#17543
* Remove unnecessary json_validator for string parameters.
* Remove unnecessary JSON encoding in frontend calls. Structurally,
JavaScript does correct encoding without explicit JSON encoding.
Fixes part of #18035.
The `.refresh-failed-message button` was registering clicks even
while the button was spinning (has already been clicked once).
Thus a network request was sent for every subsequent click which
raises an exception that the local id is not found in the message
store as it had already been reifyed by the first request.
Fixes#18375.
In this 009b7bca24 commit `before_punctuation`
regex was updated to use lookbehind feature of regex.
This caused a regex error in some browsers (reported in
Safari) because lookbehind feature is not yet supported
on all the browsers (https://caniuse.com/js-regexp-lookbehind).
This commit fixes that error by reverting to stable regex which
works on all the browsers.
Thumbor and tc-aws have been dragging their feet on Python 3 support
for years, and even the alphas and unofficial forks we’ve been running
don’t seem to be maintained anymore. Depending on these projects is
no longer viable for us.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Leave the Intel build as the prominent default, since it will run on
both platforms. (I would have liked to detect the appropriate
platform, but Apple seems to have put significant effort into making
that impossible for anti-fingerprinting reasons, which is probably an
overall good.)
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Due to spaghetti CSS that should be fixed but isn’t fixed here, the
<span> wrapper is still needed so the hover effect is applied.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This button will allow users to avoid a distracting red banner across
their screen, while they wait for their sysadmin to do the upgrade
work.
Fixes: #18359
Since we don't process private messages yet, we don't
need to re-render when we receive a new private message
as it doesn't change any data related to recent_topics.
This will allow us to avoid duplication of array filtering
logic of the form-
`Array.filter((user_id) => !muting.is_user_muted(user_id))` and
`Array.filter((person) => !muting.is_user_muted(person.user_id))`
We want to exclude 1:1 PMs from muted users everywhere
except in `pm-with/<muted_user>`.
This method will help us determine whether we are in such
a narrow.
* We show a "Click here to reveal." hyperlink in the hidden
message dialog for user to click on and read a hidden message.
* The "reveal" action is temporary, in the sense that a revealed
message will again be hidden once the broswer tab reloads or
if the user renarrows.
* When a message is revealed, we make sure to show the sender
of that message, even if it isn't the first message of it's group.
This is because the first message of that message group (which
would have otherwise shown the sender) can still be hidden.
* Reactions and background color after revealing a message are
the same as if the message hadn'e been hidden at all in the
first place.
* We hide the sender and reactions on messages sent by muted
users, and replace the content with a "This message was hidden"
dialog.
* Ideally, we should collapse a series of consequetive
messages sent by muted users into one such dialog, but
that could break the cursor behaviour and `near/<message_id`
links, so we as of now show one dialog per muted message.
* Because we hide the sender, there is a chance of the first
hidden message in a group looking like it was sent by the
author of the message above it. To tackle this, we intentionally
make the hidden message dialog float-left, so that it is clear
that this is a special type of message.
* For context, we still show the timestamp of the message.
* Starring, editing, deleting etc a message still work just like
before.
A further commit will add the ability to reveal a
hidden message.
We were not considering the owner role in `sort_role` function
which was leading to improper sorting when sorting the users
list according to role. This commit fixes this bug by considering
role in `sort_role` function.
We also add a check to see if `message_feed_container` is visible,
since it is possible that recent topics could be visible which
was not a possibility when this logic was written.
The typeahead suggests a human-readable `pretty_name` for the
`language` field in the add-playgrounds form.
The suggestions are sorted based on the popularity of these
languages.
E.g: A `py` prefix would match with `Python` first before
matching with others like `Python 2.x` based on priority.
The UI makes use of an onclick on the trash icon to call
DELETE /realm/playground/{playground_id}. The id is
extracted from the data attribute `data-playground-id`
set on that element.
The design of the form is similar to the linkifiers page
and is styled similarly.
The introduction text for "Code playgrounds" is improved
with more details and examples.
Also, we can remove the hardcoded playground and the fix
we had previously done to prevent breaking the hardcoded
playground.
This commit displays the loading animation and hides other
avatar options as delete_user_avatar is called and as we get
response from the server, we show the options back and hide
the loading animation.
These two blocks of code has incorrectly placed or implemented
conditionals for the rare corner case of Zepyhr mirroring
organizations.
Longer-term, we'll want to refactor this further to directly reference
can_render_subscribers, making the logic more general.
The previous commit remove an obsolete form laying within
subscription_table_body.hbs. However, doing so broke the functionality
of triggering the stream-creation modal using the 'Enter' hotkey.
This commit re-introduces the functionality of loading the stream
creation modal only if the user has the permission to create streams.
At the same time, we make sure it's still possible to subscribe to
streams within zephyr mirroring organizations.
The 'reply' button shows the stream>topic or recipient(s) of the
selected message, for better UX. It also expands to fill the
remaining horizontal space in the button bar -- this should help make
it easier for new users to figure out how to reply.
Finally, it uses "Message" instead of "Reply", to better match the
compose box.
Fixes#17940.