diff --git a/frontend_tests/node_tests/hotkey.js b/frontend_tests/node_tests/hotkey.js index 61097c3ad8..066adcc00b 100644 --- a/frontend_tests/node_tests/hotkey.js +++ b/frontend_tests/node_tests/hotkey.js @@ -139,7 +139,7 @@ function stubbing(func_name_to_stub, test_function) { // Unmapped keys should immediately return false, without // calling any functions outside of hotkey.js. - assert_unmapped('abdefhlmnoptuxyz'); + assert_unmapped('abdefhlmoptuxyz'); assert_unmapped('BEFHILNOQTWXYZ'); // We have to skip some checks due to the way the code is @@ -178,6 +178,7 @@ function stubbing(func_name_to_stub, test_function) { hotkey.is_subs = return_true; assert_mapping('U', 'subs.keyboard_sub'); assert_mapping('V', 'subs.view_stream'); + assert_mapping('n', 'subs.new_stream_clicked'); hotkey.is_subs = return_false; assert_mapping('?', 'ui.show_info_overlay'); diff --git a/static/js/hotkey.js b/static/js/hotkey.js index 2886763848..06c0b91e99 100644 --- a/static/js/hotkey.js +++ b/static/js/hotkey.js @@ -114,6 +114,7 @@ var keypress_mappings = { 105: {name: 'message_actions', message_view_only: true}, // 'i' 106: {name: 'vim_down', message_view_only: true}, // 'j' 107: {name: 'vim_up', message_view_only: true}, // 'k' + 110: {name: 'new_stream', message_view_only: false}, // 'n' 113: {name: 'query_users', message_view_only: false}, // 'q' 114: {name: 'reply_message', message_view_only: true}, // 'r' 115: {name: 'narrow_by_recipient', message_view_only: true}, // 's' @@ -593,6 +594,11 @@ exports.process_hotkey = function (e, hotkey) { subs.view_stream(); } return true; + case 'new_stream': + if (exports.is_subs()) { + subs.new_stream_clicked(); + } + return true; } if (current_msg_list.empty()) { diff --git a/static/js/subs.js b/static/js/subs.js index 5c15be1147..a1d34ec0ac 100644 --- a/static/js/subs.js +++ b/static/js/subs.js @@ -685,7 +685,7 @@ exports.change_state = (function () { if (hash.arguments.length > 0) { // if in #streams/new form. if (hash.arguments[0] === "new") { - $("#create_stream_button").click(); + exports.new_stream_clicked(); components.toggle.lookup("stream-filter-toggle").goto("All streams"); } else if (hash.arguments[0] === "all") { components.toggle.lookup("stream-filter-toggle").goto("All streams"); @@ -1000,6 +1000,46 @@ exports.sub_or_unsub = function (sub) { } }; +exports.new_stream_clicked = function () { + var stream = $.trim($("#search_stream_name").val()); + + if (!should_list_all_streams()) { + // Realms that don't allow listing streams should simply be subscribed to. + meta.stream_created = stream; + ajaxSubscribe($("#search_stream_name").val()); + return; + } + + // this changes the tab switcher (settings/preview) which isn't necessary + // to a add new stream title. + $(".display-type #add_new_stream_title").show(); + $(".display-type #stream_settings_title").hide(); + + $(".stream-row.active").removeClass("active"); + + $("#stream_settings_title, .subscriptions-container .settings, .nothing-selected").hide(); + $("#stream-creation, #add_new_stream_title").show(); + + $('#create_stream_name').val(stream); + show_new_stream_modal(); + + // at less than 700px we have a @media query that when you tap the + // #create_stream_button, the stream prompt slides in. However, when you + // focus the button on that page, the entire app view jumps over to + // the other tab, and the animation breaks. + // it is unclear whether this is a browser bug or "feature", however what + // is clear is that this shoudn't be touched unless you're also changing + // the mobile @media query at 700px. + if (window.innerWidth > 700) { + $('#create_stream_name').focus(); + } + + // change the hash to #streams/new to allow for linking and + // easy discovery. + + window.location.hash = "#streams/new"; +}; + $(function () { @@ -1015,10 +1055,6 @@ $(function () { $(".nothing-selected, #stream_settings_title").show(); $("#add_new_stream_title, .settings, #stream-creation").hide(); }, - stream_creation: function () { - $("#stream_settings_title, .subscriptions-container .settings, .nothing-selected").hide(); - $("#stream-creation, #add_new_stream_title").show(); - }, settings: function () { $(".settings, #stream_settings_title").show(); $("#add_new_stream_title, #stream-creation, .nothing-selected").hide(); @@ -1027,43 +1063,7 @@ $(function () { $("#subscriptions_table").on("click", "#create_stream_button", function (e) { e.preventDefault(); - - var stream = $.trim($("#search_stream_name").val()); - - if (!should_list_all_streams()) { - // Realms that don't allow listing streams should simply be subscribed to. - meta.stream_created = stream; - ajaxSubscribe($("#search_stream_name").val()); - return; - } - - // this changes the tab switcher (settings/preview) which isn't necessary - // to a add new stream title. - $(".display-type #add_new_stream_title").show(); - $(".display-type #stream_settings_title").hide(); - - $(".stream-row.active").removeClass("active"); - - show_subs_pane.stream_creation(); - - $('#create_stream_name').val(stream); - show_new_stream_modal(); - - // at less than 700px we have a @media query that when you tap the - // #create_stream_button, the stream prompt slides in. However, when you - // focus the button on that page, the entire app view jumps over to - // the other tab, and the animation breaks. - // it is unclear whether this is a browser bug or "feature", however what - // is clear is that this shoudn't be touched unless you're also changing - // the mobile @media query at 700px. - if (window.innerWidth > 700) { - $('#create_stream_name').focus(); - } - - // change the hash to #streams/new to allow for linking and - // easy discovery. - - window.location.hash = "#streams/new"; + exports.new_stream_clicked(); }); $('body').on('change', '#user-checkboxes input, #make-invite-only input', update_announce_stream_state);