mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
hotkey: Add Shift
+ V
shortcut to toggle read receipts modal.
The read receipts option, resides under the triple-dot message actions menu. This made the process of viewing the read receipts take up multiple steps, even via a keyboard-driven workflow. Via this commit, now while focused on any message in a message feed, and pressing `Shift` + `V`, efficiently brings up the read receipts for that message. Fixes part of #24716. Co-Authored-by: SameepAher <sameepaher@gmail.com>
This commit is contained in:
@@ -148,6 +148,9 @@ in the Zulip app to add more to your repertoire as needed.
|
||||
|
||||
* **Show message sender's user card**: <kbd>U</kbd>
|
||||
|
||||
* **View read receipts**: <kbd>Shift</kbd> + <kbd>V</kbd> — Same shortcut
|
||||
also closes the read receipts menu (if open).
|
||||
|
||||
* **View image**: <kbd>V</kbd>
|
||||
|
||||
* **Edit message or view message source**: <kbd>E</kbd>
|
||||
|
@@ -42,6 +42,7 @@ import * as playground_links_popover from "./playground_links_popover";
|
||||
import * as popover_menus from "./popover_menus";
|
||||
import * as popovers from "./popovers";
|
||||
import * as reactions from "./reactions";
|
||||
import * as read_receipts from "./read_receipts";
|
||||
import * as recent_view_ui from "./recent_view_ui";
|
||||
import * as recent_view_util from "./recent_view_util";
|
||||
import * as scheduled_messages_overlay_ui from "./scheduled_messages_overlay_ui";
|
||||
@@ -92,6 +93,7 @@ const keydown_shift_mappings = {
|
||||
40: {name: "down_arrow", message_view_only: false}, // down arrow
|
||||
72: {name: "view_edit_history", message_view_only: true}, // 'H'
|
||||
78: {name: "narrow_to_next_unread_followed_topic", message_view_only: false}, // 'N'
|
||||
86: {name: "toggle_read_receipts", message_view_only: true}, // 'V'
|
||||
};
|
||||
|
||||
const keydown_unshift_mappings = {
|
||||
@@ -715,8 +717,18 @@ export function process_hotkey(e, hotkey) {
|
||||
return emoji_picker.navigate(event_name);
|
||||
}
|
||||
|
||||
// modals.any_active() and modals.active_modal() both query the dom to
|
||||
// find and retrieve any active modal. Thus, we limit the number of calls
|
||||
// to the DOM by storing these values as constansts to be reused.
|
||||
const is_any_modal_active = modals.any_active();
|
||||
const active_modal = is_any_modal_active ? modals.active_modal() : null;
|
||||
|
||||
// `list_util` will process the event in send later modal.
|
||||
if (modals.any_active() && modals.active_modal() !== "#send_later_modal") {
|
||||
if (is_any_modal_active && active_modal !== "#send_later_modal") {
|
||||
if (event_name === "toggle_read_receipts" && active_modal === "#read_receipts_modal") {
|
||||
read_receipts.hide_user_list();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -890,7 +902,7 @@ export function process_hotkey(e, hotkey) {
|
||||
}
|
||||
|
||||
// Prevent navigation in the background when the overlays are active.
|
||||
if (overlays.any_active() || modals.any_active()) {
|
||||
if (overlays.any_active() || is_any_modal_active) {
|
||||
if (event_name === "view_selected_stream" && overlays.streams_open()) {
|
||||
stream_settings_ui.view_stream();
|
||||
return true;
|
||||
@@ -1146,6 +1158,10 @@ export function process_hotkey(e, hotkey) {
|
||||
stream_popover.build_move_topic_to_stream_popover(msg.stream_id, msg.topic, false, msg);
|
||||
return true;
|
||||
}
|
||||
case "toggle_read_receipts": {
|
||||
read_receipts.show_user_list(msg.id);
|
||||
return true;
|
||||
}
|
||||
case "zoom_to_message_near": {
|
||||
// The following code is essentially equivalent to
|
||||
// `window.location = hashutil.by_conversation_and_time_url(msg)`
|
||||
|
@@ -93,3 +93,7 @@ export function show_user_list(message_id: number): void {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function hide_user_list(): void {
|
||||
modals.close_if_open("read_receipts_modal");
|
||||
}
|
||||
|
@@ -224,6 +224,10 @@
|
||||
<td class="definition">{{t "Show message sender's user card" }}</td>
|
||||
<td><span class="hotkey"><kbd>U</kbd></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="definition">{{t 'View read receipts' }}</td>
|
||||
<td><span class="hotkey"><kbd>Shift</kbd> + <kbd>V</kbd></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="definition">{{t 'Show images in thread' }}</td>
|
||||
<td><span class="hotkey"><kbd>V</kbd></span></td>
|
||||
|
@@ -104,7 +104,8 @@
|
||||
{{#if should_display_read_receipts_option}}
|
||||
<li>
|
||||
<a class="view_read_receipts" data-message-id="{{message_id}}" tabindex="0">
|
||||
<i class="zulip-icon zulip-icon-readreceipts" aria-label="{{t 'View read receipts' }}"></i> {{t "View read receipts" }}
|
||||
<i class="zulip-icon zulip-icon-readreceipts" aria-label="{{t 'View read receipts' }}"></i>
|
||||
{{t "View read receipts" }} <span class="hotkey-hint">(V)</span>
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
@@ -81,6 +81,7 @@ const popovers = mock_esm("../src/user_card_popover", {
|
||||
},
|
||||
});
|
||||
const reactions = mock_esm("../src/reactions");
|
||||
const read_receipts = mock_esm("../src/read_receipts");
|
||||
const search = mock_esm("../src/search");
|
||||
const settings_data = mock_esm("../src/settings_data");
|
||||
const stream_list = mock_esm("../src/stream_list");
|
||||
@@ -185,6 +186,7 @@ run_test("mappings", () => {
|
||||
assert.equal(map_down(46).name, "delete");
|
||||
assert.equal(map_down(13, true).name, "enter");
|
||||
assert.equal(map_down(78, true).name, "narrow_to_next_unread_followed_topic");
|
||||
assert.equal(map_down(86, true).name, "toggle_read_receipts"); // Shift + V
|
||||
|
||||
assert.equal(map_press(47).name, "search"); // slash
|
||||
assert.equal(map_press(106).name, "vim_down"); // j
|
||||
@@ -363,7 +365,7 @@ run_test("modal open", ({override}) => {
|
||||
|
||||
run_test("misc", ({override}) => {
|
||||
// Next, test keys that only work on a selected message.
|
||||
const message_view_only_keys = "@+>RjJkKsuvi:GM";
|
||||
const message_view_only_keys = "@+>RjJkKsuvVi:GM";
|
||||
|
||||
// Check that they do nothing without a selected message
|
||||
with_overrides(({override}) => {
|
||||
@@ -374,7 +376,7 @@ run_test("misc", ({override}) => {
|
||||
// Check that they do nothing while in the settings overlay
|
||||
with_overrides(({override}) => {
|
||||
override(overlays, "settings_open", () => true);
|
||||
assert_unmapped("@*+->rRjJkKsSuvi:GM");
|
||||
assert_unmapped("@*+->rRjJkKsSuvVi:GM");
|
||||
});
|
||||
|
||||
// TODO: Similar check for being in the subs page
|
||||
@@ -413,6 +415,12 @@ run_test("misc", ({override}) => {
|
||||
|
||||
override(message_edit, "can_move_message", () => false);
|
||||
assert_unmapped("m");
|
||||
|
||||
assert_mapping("V", read_receipts, "show_user_list", true, true);
|
||||
|
||||
override(modals, "any_active", () => true);
|
||||
override(modals, "active_modal", () => "#read_receipts_modal");
|
||||
assert_mapping("V", read_receipts, "hide_user_list", true, true);
|
||||
});
|
||||
|
||||
run_test("lightbox overlay open", ({override}) => {
|
||||
|
Reference in New Issue
Block a user