This commit ensures the hover state appears on the first list item in
the channel picker dropdown by default. It enables navigation through
the list using Up/Down arrows while keeping browser focus in the text
input. The Tab key now shifts focus to the topic input instead of the
next list item.
Fixes: #33448.
This commit add configuration options to improve dropdown behavior:
- `keep_focus_to_search`: Keeps focus in the search input during
navigation.
- `tab_moves_focus_to_target`: Moves focus to the target item on
Tab key press.
This commit renames `active` to `current_user_setting` and
`is_item_selected` to `is_current_user_setting` to clarify
it’s the user’s current choice, not hover, and to prevent
future naming conflicts.
Earlier, keyboard shortcuts were not supported for non-latin
keyboard layouts.
This commit adds support for it.
Keyboard can be:
* configured to type latin text, with the QWERTY, AZERTY, etc layout.
* configured to type non-latin text.
For non-latin users, if a shortcut requires a key and it is not
present on the keyboard, they press the same physical key that a
QWERTY user would press.
Pressing QWERTY equivalent key is not a Zulip specific requirement,
non-latin users have confirmed in CZO that they use the same behaviour
on other applications.
Algorithm:
We need to determine the key combination pressed in a consistent way,
irrespective of the keyboard layout.
For keyboard layouts (e.g. QWERTY) where `event.key` results in
printable ASCII characters or named key attribute values like "Tab",
"Enter", etc., we use `event.key` directly to determine the key
combination.
For layouts where the character defined for a hotkey can't be typed
directly (e.g. 'a' in Cyrillic), users press the same physical key
combination that a QWERTY user would use (e.g. 'ф' on Cyrillic maps
to 'a' on QWERTY). In such cases, we derive the key combination
(QWERTY equivalent) using `event.code` and the `CODE_TO_QWERTY_CHAR`
map.
Here `event` is "keydown" event.
Once, the key combination is determined the action to perform is
executed.
Fixes: #19605.
Earlier, with Caps Lock enabled, pressing letters like 'a', 'i', etc
resulted in the keyboard shortcuts for 'Shift+A', 'Shift+I', etc
getting executed. Ideally, they should work only when 'Shift + Key'
is pressed.
We used to check capitalized letters, which can result either due
to `key` pressed with Caps Lock enabled or `Shift + key` pressed.
This commit fixes the bug by using the event modifiers states to
construct a fully descriptive string like 'Cmd+Ctrl+Alt+Shift+A',
and then look up that string in a single mapping for further execution.
We treat a-z letters case-insensitively. We distinguish between
'a' and 'A' as 'A' vs 'Shift+A'.
This descriptive string approach also resolves a bug where
`Ctrl + Meta + C/K/S/.` was working. We define the valid hotkey as
`Meta + C/K/S/.` for macOS and `Ctrl + C/K/S/.` for others.
This commit removes the deprecated `keypress` event.
Now, we use the `keydown` event to handle all the cases.
Earlier, we used `keypress` because it allowed us to distinguish
between lowercase and uppercase characters using `event.which`.
For example:
* For 'r':
* keypress.which = 114
* keydown.which = 82
* For 'R':
* keypress.which = 82
* keydown.which = 82
As shown, `keydown.which` cannot distinguish between 'r' and 'R',
which is why `keypress` was helpful.
Now, modern browsers support `event.key` on `keydown`, which directly
gives 'r' or 'R' as needed. This makes `keypress` unnecessary, and
we can safely rely on `keydown` with `event.key` to get the exact
character.
An earlier commit in this PR #34570, in which we replaced
the `event.which` with `event.key` plays a major role as a prep
commit to help removing `keypress` event in this commit.
Earlier, 'H' and 'N' were being tested as unmapped keys and the test
was falsely passing because these keys are handled by `process_keydown`
but the test was processing it with `process_keypress`.
This commit removes those keys from the test.
We already test them with keydown in other tests.
The `keydown` and `keypress` event handlers defined in `hotkey.js`
were using `event.which`, which is deprecated.
This commit makes changes to use `event.key` instead.
As a side effect, it fixes a small bug where both `Alt+P` and
`Alt+Shift+P` could be used to toggle preview mode. Only `Alt+P`
is the defined shortcut for that.
In f768d3330b, the node test
written was a noop because "e" hotkey is handled by `keypress`
instead of `keydown`. So, the expected codepath was never getting
executed at all.
This commit fixes the test.
This pulls in changes from the latest django-jinja[^1]
`makemessages.py` monkey-patching. Specifically, it adds support for
`trimmed`, `notrimmed`, and the `ext.i18n.trimmed` policy. We enable
that, which removes unsightly and unnecessary whitespace inside of
`{% trans %}` blocks.
[^1]: aac828ca63/django_jinja/management/commands/makemessages.py
Simplebar was not being implemented correctly in groups UI
left panel because $container and $simplebar_container args
passed to ListWidget.create were same elements and thus the
simplebar related elements were being removed when rendering
the list.
This commit fixes it by adding a wrapper element to be used
as simplebar container.
We set the height of left and right panel elements in
groups UI when browser window is resized as per the
heights of header, search container, etc.
We used common classes to set the height in both streams
and groups UI so the height for left panel and right panel
of groups UI were being set as per the height of headers,
search container, etc. of streams UI which made the UI
and scrolling experience buggy.
This commit fixes it by changing the Jquery selectors to
be more specific and calling the functions separately for
streams and groups UI.
If a realm's data has been scrubbed, update the deactivated realm
to note the URL can be reused, but not that the realm can be
reactivated.
Updates the template for context variables that are no longer used.
Uppy doesn't allow uploading another file and replacing the exisiting
one in the same session due to `maxNumberOfFiles: 1` set by us.
We don't want to remove this restriction, so only way to allow
replacing files easily is to just resert the current uppy session
after the last upload finishes.
Our backend deletes any existing upload by default. So, this works
as expected on all fronts.