diff --git a/frontend_tests/node_tests/hotkey.js b/frontend_tests/node_tests/hotkey.js index b7b9b96170..10aa279378 100644 --- a/frontend_tests/node_tests/hotkey.js +++ b/frontend_tests/node_tests/hotkey.js @@ -20,10 +20,6 @@ set_global('drafts', { set_global('overlays', { }); -set_global('reactions', { - reaction_navigate: function () { return; }, -}); - set_global('$', function () { return { // Hack: Used for reactions hotkeys; may want to restructure. diff --git a/static/js/emoji_picker.js b/static/js/emoji_picker.js index 64fb7edcc4..3e2c962488 100644 --- a/static/js/emoji_picker.js +++ b/static/js/emoji_picker.js @@ -130,7 +130,7 @@ exports.toggle_emoji_popover = function (element, id) { wheelSpeed: 25, }); current_message_emoji_popover_elem = elt; - reactions.render_reaction_show_list(); + exports.render_emoji_show_list(); } }; @@ -147,6 +147,154 @@ exports.hide_emoji_popover = function () { } }; +function get_selected_emoji() { + return $(".emoji-popover-emoji").filter(":focus")[0]; +} + +var emoji_show_list = []; // local emoji_show_list + +exports.render_emoji_show_list = function () { + var reaction_list = $(".emoji-popover-emoji"); + emoji_show_list = reaction_list.filter(function () { + return $(this).css('display') === "inline-block"; + }).toArray(); +}; + +function filter_emojis() { + var elt = $(".emoji-popover-filter").expectOne(); + var search_term = elt.val().trim().toLowerCase(); + var emoji_list = $(".emoji-popover-emoji"); + if (search_term !== '') { + emoji_list.each(function () { + if (this.title.indexOf(search_term) === -1) { + this.classList.add("hide"); + } else { + this.classList.remove("hide"); + } + }); + } else { + emoji_list.removeClass("hide"); + } + exports.render_emoji_show_list(); +} + +function get_emoji_at_index(index) { + if (index >= 0 && index < emoji_show_list.length) { + return emoji_show_list[index]; + } +} + +function find_index_for_emoji(emoji) { + return emoji_show_list.findIndex(function (reaction) { + return emoji === reaction; + }); +} + +function maybe_select_emoji(e) { + if (e.keyCode === 13) { // enter key + e.preventDefault(); + var first_emoji = get_emoji_at_index(0); + if (first_emoji) { + if (emoji_picker.is_composition(first_emoji)) { + first_emoji.click(); + } else { + reactions.toggle_emoji_reaction(current_msg_list.selected_id(), first_emoji.title); + } + } + } +} + +$(document).on('click', '.emoji-popover-emoji.reaction', function () { + // When an emoji is clicked in the popover, + // if the user has reacted to this message with this emoji + // the reaction is removed + // otherwise, the reaction is added + var emoji_name = this.title; + var message_id = $(this).parent().attr('data-message-id'); + + var message = message_store.get(message_id); + if (!message) { + blueslip.error('reactions: Bad message id: ' + message_id); + return; + } + + if (reactions.current_user_has_reacted_to_emoji(message, emoji_name)) { + $(this).removeClass('reacted'); + } + reactions.toggle_emoji_reaction(message_id, emoji_name); +}); + +exports.toggle_selected_emoji = function () { + // Toggle the currently selected emoji. + var message_id = current_msg_list.selected_id(); + + var message = message_store.get(message_id); + + if (!message) { + blueslip.error('reactions: Bad message id: ' + message_id); + return; + } + + var selected_emoji = get_selected_emoji(); + + if (selected_emoji === undefined) { + return; + } + + var emoji_name = selected_emoji.title; + + reactions.toggle_emoji_reaction(message_id, emoji_name); +}; + +exports.navigate = function (e, event_name) { + var first_emoji = get_emoji_at_index(0); + var selected_emoji = get_selected_emoji(); + var selected_index = find_index_for_emoji(selected_emoji); + + // special cases + if (event_name === 'down_arrow') { + if ($('.emoji-popover-filter').is(':focus') && first_emoji) { // move down into emoji map + $(first_emoji).focus(); + } + } else if (event_name === 'up_arrow') { + if (selected_emoji && selected_index < 6) { + // In this case, we're move up into the reaction filter + // rows. Here, we override the default browser behavior, + // which in Firefox is good (preserving the cursor + // position) and in Chrome is bad (cursor goes to + // beginning) with something reasonable and consistent + // (cursor goes to the end of the filter string). + $('.emoji-popover-filter').focus().caret(Infinity); + return true; + } + } + + if (selected_emoji === undefined) { + return false; + } + var next_index; + switch (event_name) { + case 'down_arrow': + next_index = selected_index + 6; + break; + case 'up_arrow': + next_index = selected_index - 6; + break; + case 'left_arrow': + next_index = selected_index - 1; + break; + case 'right_arrow': + next_index = selected_index + 1; + break; + } + var next_emoji = get_emoji_at_index(next_index); + if (next_emoji) { + $(next_emoji).focus(); + return true; + } + return false; +}; + exports.register_click_handlers = function () { $(document).on('click', '.emoji-popover-emoji.composition', function (e) { var emoji_text = ':' + this.title + ':'; @@ -180,6 +328,10 @@ exports.register_click_handlers = function () { // .icon-vector-chevron-down element as the base for the popover. emoji_picker.toggle_emoji_popover($(".selected_message .icon-vector-chevron-down")[0], msgid); }); + + $(document).on('input', '.emoji-popover-filter', filter_emojis); + $(document).on('keydown', '.emoji-popover-filter', maybe_select_emoji); + }; exports.is_composition = function (emoji) { diff --git a/static/js/hotkey.js b/static/js/hotkey.js index af5406491b..c161630a28 100644 --- a/static/js/hotkey.js +++ b/static/js/hotkey.js @@ -253,7 +253,7 @@ exports.process_enter_key = function (e) { if (emoji_picker.is_composition(e.target)) { e.target.click(); } else { - reactions.toggle_selected_emoji(); + emoji_picker.toggle_selected_emoji(); } return true; } @@ -443,7 +443,7 @@ exports.process_hotkey = function (e, hotkey) { } if (emoji_picker.reactions_popped()) { - return reactions.reaction_navigate(e, event_name); + return emoji_picker.navigate(e, event_name); } if (overlays.info_overlay_open()) { diff --git a/static/js/reactions.js b/static/js/reactions.js index 2c5f28d8de..4c254b138b 100644 --- a/static/js/reactions.js +++ b/static/js/reactions.js @@ -71,159 +71,6 @@ exports.toggle_emoji_reaction = function (message_id, emoji_name) { emoji_picker.hide_emoji_popover(); }; -function get_selected_emoji() { - return $(".emoji-popover-emoji").filter(":focus")[0]; -} - -var reaction_show_list = []; // local reaction_show_list - -exports.render_reaction_show_list = function () { - var reaction_list = $(".emoji-popover-emoji"); - reaction_show_list = reaction_list.filter(function () { - return $(this).css('display') === "inline-block"; - }).toArray(); -}; - -function filter_emojis() { - var elt = $(".emoji-popover-filter").expectOne(); - var search_term = elt.val().trim().toLowerCase(); - var reaction_list = $(".emoji-popover-emoji"); - if (search_term !== '') { - reaction_list.each(function () { - if (this.title.indexOf(search_term) === -1) { - this.classList.add("hide"); - } else { - this.classList.remove("hide"); - } - }); - } else { - reaction_list.removeClass("hide"); - } - exports.render_reaction_show_list(); -} - -function get_emoji_at_index(index) { - if (index >= 0 && index < reaction_show_list.length) { - return reaction_show_list[index]; - } -} - -function find_index_for_emoji(emoji) { - return reaction_show_list.findIndex(function (reaction) { - return emoji === reaction; - }); -} - -function maybe_select_emoji(e) { - if (e.keyCode === 13) { // enter key - e.preventDefault(); - var first_emoji = get_emoji_at_index(0); - if (first_emoji) { - if (emoji_picker.is_composition(first_emoji)) { - first_emoji.click(); - } else { - exports.toggle_emoji_reaction(current_msg_list.selected_id(), first_emoji.title); - } - } - } -} - -$(document).on('click', '.emoji-popover-emoji.reaction', function () { - // When an emoji is clicked in the popover, - // if the user has reacted to this message with this emoji - // the reaction is removed - // otherwise, the reaction is added - var emoji_name = this.title; - var message_id = $(this).parent().attr('data-message-id'); - - var message = get_message(message_id); - if (!message) { - return; - } - - if (exports.current_user_has_reacted_to_emoji(message, emoji_name)) { - $(this).removeClass('reacted'); - } - exports.toggle_emoji_reaction(message_id, emoji_name); -}); - -// TODO: Move emoji-picker stuff to emoji_picker.js. -// (two click handlers, toggle_selected_emoji, reaction_navigate) - -$(document).on('input', '.emoji-popover-filter', filter_emojis); -$(document).on('keydown', '.emoji-popover-filter', maybe_select_emoji); - -exports.toggle_selected_emoji = function () { - // Toggle the currently selected emoji. - var message_id = current_msg_list.selected_id(); - - var message = message_store.get(message_id); - - if (!message) { - blueslip.error('reactions: Bad message id: ' + message_id); - return; - } - - var selected_emoji = get_selected_emoji(); - - if (selected_emoji === undefined) { - return; - } - - var emoji_name = selected_emoji.title; - - exports.toggle_emoji_reaction(message_id, emoji_name); -}; - -exports.reaction_navigate = function (e, event_name) { - var first_emoji = get_emoji_at_index(0); - var selected_emoji = get_selected_emoji(); - var selected_index = find_index_for_emoji(selected_emoji); - - // special cases - if (event_name === 'down_arrow') { - if ($('.emoji-popover-filter').is(':focus') && first_emoji) { // move down into emoji map - $(first_emoji).focus(); - } - } else if (event_name === 'up_arrow') { - if (selected_emoji && selected_index < 6) { - // In this case, we're move up into the reaction filter - // rows. Here, we override the default browser behavior, - // which in Firefox is good (preserving the cursor - // position) and in Chrome is bad (cursor goes to - // beginning) with something reasonable and consistent - // (cursor goes to the end of the filter string). - $('.emoji-popover-filter').focus().caret(Infinity); - return true; - } - } - - if (selected_emoji === undefined) { - return false; - } - var next_index; - switch (event_name) { - case 'down_arrow': - next_index = selected_index + 6; - break; - case 'up_arrow': - next_index = selected_index - 6; - break; - case 'left_arrow': - next_index = selected_index - 1; - break; - case 'right_arrow': - next_index = selected_index + 1; - break; - } - var next_emoji = get_emoji_at_index(next_index); - if (next_emoji) { - $(next_emoji).focus(); - return true; - } - return false; -}; - function full_name(user_id) { if (user_id === page_params.user_id) { return 'You (click to remove)';