diff --git a/frontend_tests/node_tests/hotkey.js b/frontend_tests/node_tests/hotkey.js index c827095217..1d0b81247a 100644 --- a/frontend_tests/node_tests/hotkey.js +++ b/frontend_tests/node_tests/hotkey.js @@ -80,7 +80,7 @@ mock_esm("../../static/js/recent_topics_util", { is_in_focus: () => false, }); -mock_esm("../../static/js/stream_popover", { +const stream_popover = mock_esm("../../static/js/stream_popover", { stream_popped: () => false, topic_popped: () => false, all_messages_popped: () => false, @@ -262,7 +262,7 @@ function test_normal_typing() { run_test("allow normal typing when processing text", ({override, override_rewire}) => { // Unmapped keys should immediately return false, without // calling any functions outside of hotkey.js. - assert_unmapped("bfmoyz"); + assert_unmapped("bfoyz"); assert_unmapped("BEFHILNOQTWXYZ"); // All letters should return false if we are composing text. @@ -336,7 +336,7 @@ run_test("modal open", ({override}) => { test_normal_typing(); }); -run_test("misc", () => { +run_test("misc", ({override}) => { // Next, test keys that only work on a selected message. const message_view_only_keys = "@+>RjJkKsSuvi:GM"; @@ -370,6 +370,12 @@ run_test("misc", () => { assert_mapping(":", reactions, "open_reactions_popover", true); assert_mapping(">", compose_actions, "quote_and_reply"); assert_mapping("e", message_edit, "start"); + + override(message_edit, "can_move_message", () => true); + assert_mapping("m", stream_popover, "build_move_topic_to_stream_popover"); + + override(message_edit, "can_move_message", () => false); + assert_unmapped("m"); }); run_test("lightbox overlay open", ({override}) => { diff --git a/static/js/hotkey.js b/static/js/hotkey.js index 368ddd6c62..725e60cdb2 100644 --- a/static/js/hotkey.js +++ b/static/js/hotkey.js @@ -148,6 +148,7 @@ const keypress_mappings = { 106: {name: "vim_down", message_view_only: true}, // 'j' 107: {name: "vim_up", message_view_only: true}, // 'k' 108: {name: "vim_right", message_view_only: true}, // 'l' + 109: {name: "move_message", message_view_only: true}, // 'm' 110: {name: "n_key", message_view_only: false}, // 'n' 112: {name: "p_key", message_view_only: false}, // 'p' 113: {name: "query_streams", message_view_only: true}, // 'q' @@ -965,6 +966,14 @@ export function process_hotkey(e, hotkey) { message_edit.start($row); return true; } + case "move_message": { + if (!message_edit.can_move_message(msg)) { + return false; + } + + stream_popover.build_move_topic_to_stream_popover(msg.stream_id, msg.topic, msg); + return true; + } } return false; diff --git a/static/js/message_edit.js b/static/js/message_edit.js index 2ac9b2bbfc..f003892492 100644 --- a/static/js/message_edit.js +++ b/static/js/message_edit.js @@ -181,6 +181,21 @@ export function get_deletability(message) { return false; } +export function can_move_message(message) { + if (!page_params.realm_allow_message_editing) { + return false; + } + + if (!message.is_stream) { + return false; + } + + return ( + get_editability(message) !== editability_types.NO || + settings_data.user_can_move_messages_between_streams() + ); +} + export function stream_and_topic_exist_in_edit_history(message, stream_id, topic) { /* Checks to see if a stream_id and a topic match any historical stream_id and topic state in the message's edit history. diff --git a/static/templates/actions_popover_content.hbs b/static/templates/actions_popover_content.hbs index 618ebb872d..e7c79a60fc 100644 --- a/static/templates/actions_popover_content.hbs +++ b/static/templates/actions_popover_content.hbs @@ -23,6 +23,7 @@
  • {{move_message_menu_item}} + (m)
  • {{/if}} diff --git a/static/templates/edit_content_button.hbs b/static/templates/edit_content_button.hbs index 694376e111..3a9af4556b 100644 --- a/static/templates/edit_content_button.hbs +++ b/static/templates/edit_content_button.hbs @@ -1,7 +1,7 @@ {{#if is_content_editable}} {{else if can_move_message}} - + {{else}} {{/if}} diff --git a/static/templates/keyboard_shortcuts.hbs b/static/templates/keyboard_shortcuts.hbs index bcd228f203..670c2136fe 100644 --- a/static/templates/keyboard_shortcuts.hbs +++ b/static/templates/keyboard_shortcuts.hbs @@ -220,6 +220,10 @@ {{t 'Edit selected message or view message source' }} E + + {{t 'Move messages or topic' }} + M + {{t 'Star selected message' }} Ctrl + S diff --git a/templates/zerver/help/keyboard-shortcuts.md b/templates/zerver/help/keyboard-shortcuts.md index 8cb4e5280d..0272dc57b4 100644 --- a/templates/zerver/help/keyboard-shortcuts.md +++ b/templates/zerver/help/keyboard-shortcuts.md @@ -145,6 +145,8 @@ below, and add more to your repertoire as needed. * **Edit message or view message source**: E +* **Move message and (optionally) other messages in the same topic**: M + * **Star message**: Ctrl + S * **React with