diff --git a/include/functions.php b/include/functions.php index f0bd31831..ac9cce90f 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1963,12 +1963,66 @@ $params["num_feeds"] = (int) $num_feeds; $params["collapsed_feedlist"] = (int) get_pref($link, "_COLLAPSED_FEEDLIST"); + $params["hotkeys"] = get_hotkeys($link); $params["csrf_token"] = $_SESSION["csrf_token"]; return $params; } + function get_hotkeys($link) { + $hotkeys = array( + "navigation" => array( + "next_feed" => "k", + "prev_feed" => "j", + "next_article" => "n", + "prev_article" => "p", + "search_dialog" => "/"), + "article" => array( + "toggle_mark" => "s", + "toggle_publ" => "S", + "toggle_unread" => "u", + "edit_tags" => "T", + "dismiss_selected" => "D", + "dismiss_read" => "X", + "open_in_new_window" => "o", + "catchup_below" => "c p", + "catchup_above" => "c n", + "email_article" => "e"), + "article_selection" => array( + "select_all" => "a a", + "select_unread" => "a u", + "select_marked" => "a U", + "select_published" => "a p", + "select_invert" => "a i", + "select_none" => "a n"), + "feed" => array( + "feed_refresh" => "f r", + "feed_unhide_read" => "f a", + "feed_subscribe" => "f s", + "feed_edit" => "f e", + "feed_catchup" => "f q", + "feed_reverse" => "f x", + "catchup_all" => "Q", + "cat_toggle_collapse" => "x"), + "goto" => array( + "goto_all" => "g a", + "goto_fresh" => "g f", + "goto_marked" => "g s", + "goto_published" => "g p", + "goto_tagcloud" => "g t", + "goto_prefs" => "g P"), + "other" => array( + "select_article_cursor" => "(9)", // tab + "create_label" => "c l", + "create_filter" => "c f", + "collapse_sidebar" => "c s", + "help_dialog" => "(191)") + ); + + return $hotkeys; + } + function make_runtime_info($link) { $data = array(); diff --git a/js/tt-rss.js b/js/tt-rss.js index 56f7df65d..67fbea28e 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -647,13 +647,134 @@ function hotkey_handler(e) { if (keycode == 16) return; // ignore lone shift if (keycode == 17) return; // ignore lone ctrl - if ((keycode == 70 || keycode == 67 || keycode == 71 || keycode == 65) + if (!shift_key) keychar = keychar.toLowerCase(); + + if (!hotkey_prefix && ["a", "f", "g", "c"].indexOf(keychar) != -1) { + + var date = new Date(); + var ts = Math.round(date.getTime() / 1000); + + hotkey_prefix = keychar; + hotkey_prefix_pressed = ts; + + cmdline.innerHTML = keychar; + Element.show(cmdline); + + return true; + } + + Element.hide(cmdline); + + var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")"; + hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey; + hotkey_prefix = false; + + var hotkey_action = false; + var hotkeys = getInitParam("hotkeys"); + + for (cat in hotkeys) { + for (action in hotkeys[cat]) { + if (hotkeys[cat][action] == hotkey) { + hotkey_action = action; + break; + } + } + } + + switch (hotkey_action) { + case "next_feed": + return true; + case "prev_feed": + return true; + case "next_article": + return true; + case "prev_article": + return true; + case "search_dialog": + return true; + case "toggle_mark": + return true; + case "toggle_publ": + return true; + case "toggle_unread": + return true; + case "edit_tags": + return true; + case "dismiss_selected": + return true; + case "dismiss_read": + return true; + case "open_in_new_window": + return true; + case "catchup_below": + return true; + case "catchup_above": + return true; + case "email_article": + return true; + case "select_all": + return true; + case "select_unread": + return true; + case "select_marked": + return true; + case "select_published": + return true; + case "select_invert": + return true; + case "select_none": + return true; + case "feed_refresh": + return true; + case "feed_unhide_read": + return true; + case "feed_subscribe": + quickAddFeed(); + return true; + case "feed_edit": + return true; + case "feed_catchup": + return true; + case "feed_reverse": + return true; + case "catchup_all": + return true; + case "cat_toggle_collapse": + return true; + case "goto_all": + return true; + case "goto_fresh": + return true; + case "goto_marked": + return true; + case "goto_published": + return true; + case "goto_tagcloud": + return true; + case "goto_prefs": + return true; + case "select_article_cursor": + return true; + case "create_label": + return true; + case "create_filter": + return true; + case "collapse_sidebar": + return true; + case "help_dialog": + return true; + default: + console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey); + } + + +/* if ((keycode == 70 || keycode == 67 || keycode == 71 || keycode == 65) && !hotkey_prefix) { var date = new Date(); var ts = Math.round(date.getTime() / 1000); - hotkey_prefix = keycode; + hotkey_prefix = keychar; hotkey_prefix_pressed = ts; cmdline.innerHTML = keychar; @@ -667,10 +788,12 @@ function hotkey_handler(e) { Element.hide("hotkey_help_overlay"); } - /* Global hotkeys */ - Element.hide(cmdline); + + /* Global hotkeys */ + return; + if (!hotkey_prefix) { if (keycode == 27) { // escape