summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/AppBase.js22
-rw-r--r--js/CommonDialogs.js56
-rw-r--r--js/FeedStoreModel.js2
-rwxr-xr-xjs/FeedTree.js22
-rw-r--r--js/Feeds.js42
-rwxr-xr-xjs/Headlines.js93
-rw-r--r--js/PluginHost.js7
-rw-r--r--js/PrefFeedTree.js4
-rw-r--r--js/PrefUsers.js2
-rwxr-xr-xjs/Toolbar.js14
-rwxr-xr-xjs/form/ComboButton.js12
-rwxr-xr-xjs/form/DropDownButton.js12
-rwxr-xr-xjs/form/Select.js8
-rwxr-xr-xjs/prefs.js11
-rw-r--r--js/tt-rss.js22
15 files changed, 252 insertions, 77 deletions
diff --git a/js/AppBase.js b/js/AppBase.js
index 121b7aa85..a5e20b8f9 100644
--- a/js/AppBase.js
+++ b/js/AppBase.js
@@ -60,14 +60,12 @@ define(["dojo/_base/declare"], function (declare) {
const hotkeys_map = App.getInitParam("hotkeys");
const keycode = event.which;
- const keychar = String.fromCharCode(keycode).toLowerCase();
+ const keychar = String.fromCharCode(keycode);
if (keycode == 27) { // escape and drop prefix
this.hotkey_prefix = false;
}
- if (keycode == 16 || keycode == 17) return; // ignore lone shift / ctrl
-
if (!this.hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) {
this.hotkey_prefix = keychar;
@@ -87,13 +85,19 @@ define(["dojo/_base/declare"], function (declare) {
Element.hide("cmdline");
- let hotkey_name = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
+ let hotkey_name = "";
+
+ if (event.type == "keydown") {
+ hotkey_name = "(" + keycode + ")";
- // ensure ^*char notation
- if (event.shiftKey) hotkey_name = "*" + hotkey_name;
- if (event.ctrlKey) hotkey_name = "^" + hotkey_name;
- if (event.altKey) hotkey_name = "+" + hotkey_name;
- if (event.metaKey) hotkey_name = "%" + hotkey_name;
+ // ensure ^*char notation
+ if (event.shiftKey) hotkey_name = "*" + hotkey_name;
+ if (event.ctrlKey) hotkey_name = "^" + hotkey_name;
+ if (event.altKey) hotkey_name = "+" + hotkey_name;
+ if (event.metaKey) hotkey_name = "%" + hotkey_name;
+ } else {
+ hotkey_name = keychar ? keychar : "(" + keycode + ")";
+ }
const hotkey_full = this.hotkey_prefix ? this.hotkey_prefix + " " + hotkey_name : hotkey_name;
this.hotkey_prefix = false;
diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js
index 2b7ee8a7f..e0338a97c 100644
--- a/js/CommonDialogs.js
+++ b/js/CommonDialogs.js
@@ -7,25 +7,6 @@ define(["dojo/_base/declare"], function (declare) {
const dialog = dijit.byId("infoBox");
if (dialog) dialog.hide();
},
- uploadIconHandler: function(rc) {
- switch (rc) {
- case 0:
- Notify.info("Upload complete.");
-
- if (App.isPrefs())
- dijit.byId("feedTree").reload();
- else
- Feeds.reload();
-
- break;
- case 1:
- Notify.error("Upload failed: icon is too big.");
- break;
- case 2:
- Notify.error("Upload failed.");
- break;
- }
- },
removeFeedIcon: function(id) {
if (confirm(__("Remove stored feed icon?"))) {
Notify.progress("Removing feed icon...", true);
@@ -40,6 +21,11 @@ define(["dojo/_base/declare"], function (declare) {
else
Feeds.reload();
+ const icon = $$(".feed-editor-icon")[0];
+
+ if (icon)
+ icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
+
});
}
@@ -52,7 +38,35 @@ define(["dojo/_base/declare"], function (declare) {
alert(__("Please select an image file to upload."));
} else if (confirm(__("Upload new icon for this feed?"))) {
Notify.progress("Uploading, please wait...", true);
- return true;
+
+ const xhr = new XMLHttpRequest();
+
+ xhr.open( 'POST', 'backend.php', true );
+ xhr.onload = function () {
+ switch (parseInt(this.responseText)) {
+ case 0:
+ Notify.info("Upload complete.");
+
+ if (App.isPrefs())
+ dijit.byId("feedTree").reload();
+ else
+ Feeds.reload();
+
+ const icon = $$(".feed-editor-icon")[0];
+
+ if (icon)
+ icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
+
+ break;
+ case 1:
+ Notify.error("Upload failed: icon is too big.");
+ break;
+ case 2:
+ Notify.error("Upload failed.");
+ break;
+ }
+ };
+ xhr.send(new FormData($("feed_icon_upload_form")));
}
return false;
@@ -466,4 +480,4 @@ define(["dojo/_base/declare"], function (declare) {
};
return CommonDialogs;
-}); \ No newline at end of file
+});
diff --git a/js/FeedStoreModel.js b/js/FeedStoreModel.js
index 7f2af22ec..7d8020871 100644
--- a/js/FeedStoreModel.js
+++ b/js/FeedStoreModel.js
@@ -31,7 +31,7 @@ define(["dojo/_base/declare", "dijit/tree/ForestStoreModel"], function (declare)
},
getFeedUnread: function (feed, is_cat) {
const unread = parseInt(this.getFeedValue(feed, is_cat, 'unread'));
- return (isNaN(unread)) ? 0 : unread;
+ return (isNaN(unread)) ? -1 : unread;
},
setFeedUnread: function (feed, is_cat, unread) {
return this.setFeedValue(feed, is_cat, 'unread', parseInt(unread));
diff --git a/js/FeedTree.js b/js/FeedTree.js
index b8e50872a..1dcbae3f9 100755
--- a/js/FeedTree.js
+++ b/js/FeedTree.js
@@ -2,7 +2,10 @@
define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"], function (declare, domConstruct) {
return declare("fox.FeedTree", dijit.Tree, {
- _onKeyPress: function(/* Event */ e) {
+ _onContainerKeydown: function(/* Event */ e) {
+ return; // Stop dijit.Tree from interpreting keystrokes
+ },
+ _onContainerKeypress: function(/* Event */ e) {
return; // Stop dijit.Tree from interpreting keystrokes
},
_createTreeNode: function(args) {
@@ -64,6 +67,13 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
CommonDialogs.editFeed(this.getParent().row_id, false);
}}));
+ menu.addChild(new dijit.MenuItem({
+ label: __("Debug feed"),
+ onClick: function() {
+ window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + this.getParent().row_id +
+ "&csrf_token=" + App.getInitParam("csrf_token"));
+ }}));
+
/* menu.addChild(new dijit.MenuItem({
label: __("Update feed"),
onClick: function() {
@@ -125,7 +135,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
args.item.unread > 0 || args.item.auxcounter > 0 ? Element.show(ctr) : Element.hide(ctr);
- args.item.unread == 0 && args.item.auxcounter > 0 ? ctr.addClassName("aux") : ctr.removeClassName("aux");
+ args.item.unread <= 0 && args.item.auxcounter > 0 ? ctr.addClassName("aux") : ctr.removeClassName("aux");
domConstruct.place(ctr, tnode.rowNode, 'first');
tnode.counterNode = ctr;
@@ -161,7 +171,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
Element.show(ctr) :
Element.hide(ctr);
- item.unread == 0 && item.auxcounter > 0 ? ctr.addClassName("aux") : ctr.removeClassName("aux");
+ item.unread <= 0 && item.auxcounter > 0 ? ctr.addClassName("aux") : ctr.removeClassName("aux");
}
}
@@ -174,7 +184,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feed-icon";
},
getLabelClass: function (item, opened) {
- return (item.unread == 0) ? "dijitTreeLabel" : "dijitTreeLabel Unread";
+ return (item.unread <= 0) ? "dijitTreeLabel" : "dijitTreeLabel Unread";
},
getRowClass: function (item, opened) {
let rc = (!item.error || item.error == '') ? "dijitTreeRow" :
@@ -343,7 +353,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
if (node) {
const check_unread = tree.model.getFeedUnread(bare_id, true);
- if (hide && cat_unread == 0 && check_unread == 0 && (id != "CAT:-1" || !show_special)) {
+ if (hide && cat_unread <= 0 && check_unread <= 0 && (id != "CAT:-1" || !show_special)) {
Effect.Fade(node[0].rowNode, {duration : 0.3,
queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
} else {
@@ -387,7 +397,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"],
const node = tree._itemNodesMap[id];
if (node) {
- if (hide && unread == 0 && !has_error && (bare_id > 0 || bare_id < _label_base_index || !show_special)) {
+ if (hide && unread <= 0 && !has_error && (bare_id > 0 || bare_id < _label_base_index || !show_special)) {
Effect.Fade(node[0].rowNode, {duration : 0.3,
queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
} else {
diff --git a/js/Feeds.js b/js/Feeds.js
index 401d669a7..07ec89452 100644
--- a/js/Feeds.js
+++ b/js/Feeds.js
@@ -3,7 +3,7 @@
define(["dojo/_base/declare"], function (declare) {
Feeds = {
counters_last_request: 0,
- _active_feed_id: 0,
+ _active_feed_id: undefined,
_active_feed_is_cat: false,
infscroll_in_progress: 0,
infscroll_disabled: 0,
@@ -44,6 +44,8 @@ define(["dojo/_base/declare"], function (declare) {
this._counters_prev = [];
},
parseCounters: function (elems) {
+ PluginHost.run(PluginHost.HOOK_COUNTERS_RECEIVED, elems);
+
for (let l = 0; l < elems.length; l++) {
if (Feeds._counters_prev[l] && this.counterEquals(elems[l], this._counters_prev[l])) {
@@ -93,11 +95,13 @@ define(["dojo/_base/declare"], function (declare) {
this.hideOrShowFeeds(App.getInitParam("hide_read_feeds") == 1);
this._counters_prev = elems;
+
+ PluginHost.run(PluginHost.HOOK_COUNTERS_PROCESSED);
},
reloadCurrent: function(method) {
- console.log("reloadCurrent: " + method);
-
if (this.getActive() != undefined) {
+ console.log("reloadCurrent: " + method);
+
this.open({feed: this.getActive(), is_cat: this.activeIsCat(), method: method});
}
return false; // block unneeded form submits
@@ -196,12 +200,16 @@ define(["dojo/_base/declare"], function (declare) {
App.setLoadingProgress(50);
document.onkeydown = (event) => { return App.hotkeyHandler(event) };
+ document.onkeypress = (event) => { return App.hotkeyHandler(event) };
window.onresize = () => { Headlines.scrollHandler(); }
- if (!this.getActive()) {
- this.open({feed: -3});
+ const hash_feed_id = hash_get('f');
+ const hash_feed_is_cat = hash_get('c') == "1";
+
+ if (hash_feed_id != undefined) {
+ this.open({feed: hash_feed_id, is_cat: hash_feed_is_cat});
} else {
- this.open({feed: this.getActive(), is_cat: this.activeIsCat()});
+ this.open({feed: -3});
}
this.hideOrShowFeeds(App.getInitParam("hide_read_feeds") == 1);
@@ -245,6 +253,8 @@ define(["dojo/_base/declare"], function (declare) {
return this._active_feed_id;
},
setActive: function(id, is_cat) {
+ console.log('setActive', id, is_cat);
+
hash_set('f', id);
hash_set('c', is_cat ? 1 : 0);
@@ -542,6 +552,11 @@ define(["dojo/_base/declare"], function (declare) {
execute: function () {
if (this.validate()) {
Feeds._search_query = this.attr('value');
+
+ // disallow empty queries
+ if (!Feeds._search_query.query)
+ Feeds._search_query = false;
+
this.hide();
Feeds.reloadCurrent();
}
@@ -549,6 +564,21 @@ define(["dojo/_base/declare"], function (declare) {
href: query
});
+ const tmph = dojo.connect(dialog, 'onLoad', function () {
+ dojo.disconnect(tmph);
+
+ if (Feeds._search_query) {
+ if (Feeds._search_query.query)
+ dijit.byId('search_query')
+ .attr('value', Feeds._search_query.query);
+
+ if (Feeds._search_query.search_language)
+ dijit.byId('search_language')
+ .attr('value', Feeds._search_query.search_language);
+ }
+
+ });
+
dialog.show();
},
updateRandom: function() {
diff --git a/js/Headlines.js b/js/Headlines.js
index 1414dd3c7..3c5ab2ee6 100755
--- a/js/Headlines.js
+++ b/js/Headlines.js
@@ -153,35 +153,59 @@ define(["dojo/_base/declare"], function (declare) {
click: function (event, id, in_body) {
in_body = in_body || false;
- if (App.isCombinedMode()) {
+ if (event.shiftKey && Article.getActive()) {
+ Headlines.select('none');
- if (!in_body && (event.ctrlKey || id == Article.getActive() || App.getInitParam("cdm_expanded"))) {
- Article.openInNewWindow(id);
- Headlines.toggleUnread(id, 0);
- return false;
- }
+ const ids = Headlines.getRange(Article.getActive(), id);
- if (Article.getActive() != id) {
- Article.setActive(id);
+ console.log(Article.getActive(), id, ids);
- if (!App.getInitParam("cdm_expanded"))
- Article.cdmScrollToId(id);
- } else if (in_body) {
- Headlines.toggleUnread(id, 0);
- }
-
- return in_body;
+ for (let i = 0; i < ids.length; i++)
+ Headlines.select('all', ids[i]);
+ } else if (event.ctrlKey) {
+ Headlines.select('invert', id);
} else {
- if (event.ctrlKey) {
- Article.openInNewWindow(id);
- Headlines.toggleUnread(id, 0);
+ if (App.isCombinedMode()) {
+
+ if (event.altKey && !in_body) {
+
+ Article.openInNewWindow(id);
+ Headlines.toggleUnread(id, 0);
+
+ } else if (Article.getActive() != id) {
+
+ Headlines.select('none');
+ Article.setActive(id);
+
+ if (App.getInitParam("cdm_expanded")) {
+ if (!in_body)
+ Article.openInNewWindow(id);
+
+ Headlines.toggleUnread(id, 0);
+ } else {
+ Article.cdmScrollToId(id);
+ }
+
+ } else if (in_body) {
+ Headlines.toggleUnread(id, 0);
+ } else { /* !in body */
+ Article.openInNewWindow(id);
+ }
+
+ return in_body;
} else {
- Article.view(id);
+ if (event.altKey) {
+ Article.openInNewWindow(id);
+ Headlines.toggleUnread(id, 0);
+ } else {
+ Headlines.select('none');
+ Article.view(id);
+ }
}
-
- return false;
}
+
+ return false;
},
initScrollHandler: function () {
$("headlines-frame").onscroll = (event) => {
@@ -997,6 +1021,33 @@ define(["dojo/_base/declare"], function (declare) {
row.removeClassName("Selected");
}
},
+ getRange: function (start, stop) {
+ if (start == stop)
+ return [start];
+
+ const rows = $$("#headlines-frame > div[id*=RROW]");
+ const results = [];
+ let collecting = false;
+
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
+ const id = row.getAttribute('data-article-id');
+
+ if (id == start || id == stop) {
+ if (!collecting) {
+ collecting = true;
+ } else {
+ results.push(id);
+ break;
+ }
+ }
+
+ if (collecting)
+ results.push(id);
+ }
+
+ return results;
+ },
select: function (mode, articleId) {
// mode = all,none,unread,invert,marked,published
let query = "#headlines-frame > div[id*=RROW]";
diff --git a/js/PluginHost.js b/js/PluginHost.js
index f76b73464..71596ad31 100644
--- a/js/PluginHost.js
+++ b/js/PluginHost.js
@@ -13,6 +13,8 @@ PluginHost = {
HOOK_FLOATING_TITLE: 10,
HOOK_INIT_COMPLETE: 11,
HOOK_HEADLINE_RENDERED: 12,
+ HOOK_COUNTERS_RECEIVED: 13,
+ HOOK_COUNTERS_PROCESSED: 14,
hooks: [],
register: function (name, callback) {
if (typeof(this.hooks[name]) == 'undefined')
@@ -27,6 +29,11 @@ PluginHost = {
for (let i = 0; i < this.hooks[name].length; i++) {
this.hooks[name][i](args);
}
+ },
+ unregister: function (name, callback) {
+ for (var i = 0; i < this.hooks[name].length; i++)
+ if (this.hooks[name][i] == callback)
+ this.hooks[name].splice(i, 1);
}
};
diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js
index c2c7751bf..3a5e33b2b 100644
--- a/js/PrefFeedTree.js
+++ b/js/PrefFeedTree.js
@@ -275,9 +275,9 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
if ($(label))
if (checkbox.checked)
- $(label).removeClassName('insensitive');
+ $(label).removeClassName('text-muted');
else
- $(label).addClassName('insensitive');
+ $(label).addClassName('text-muted');
},
execute: function () {
diff --git a/js/PrefUsers.js b/js/PrefUsers.js
index 4f24f67cf..55dc43dfa 100644
--- a/js/PrefUsers.js
+++ b/js/PrefUsers.js
@@ -70,7 +70,7 @@ define(["dojo/_base/declare"], function (declare) {
xhrPost("backend.php", {op: "pref-users", method: "resetPass", id: id}, (transport) => {
Notify.close();
- alert(transport.responseText);
+ Notify.info(transport.responseText, true);
});
}
diff --git a/js/Toolbar.js b/js/Toolbar.js
new file mode 100755
index 000000000..6d2c20058
--- /dev/null
+++ b/js/Toolbar.js
@@ -0,0 +1,14 @@
+/* global dijit */
+define(["dojo/_base/declare", "dijit/Toolbar"], function (declare) {
+ return declare("fox.Toolbar", dijit.Toolbar, {
+ _onContainerKeydown: function(/* Event */ e) {
+ return; // Stop dijit.Toolbar from interpreting keystrokes
+ },
+ _onContainerKeypress: function(/* Event */ e) {
+ return; // Stop dijit.Toolbar from interpreting keystrokes
+ },
+ focus: function() {
+ return; // Stop dijit.Toolbar from focusing the first child on click
+ },
+ });
+});
diff --git a/js/form/ComboButton.js b/js/form/ComboButton.js
new file mode 100755
index 000000000..1084cda9c
--- /dev/null
+++ b/js/form/ComboButton.js
@@ -0,0 +1,12 @@
+/* global dijit */
+define(["dojo/_base/declare", "dijit/form/ComboButton"], function (declare) {
+ return declare("fox.form.ComboButton", dijit.form.ComboButton, {
+ startup: function() {
+ this.inherited(arguments);
+ this.dropDown.autoFocus = true; // Allow dropdown menu to be focused on click
+ },
+ focus: function() {
+ return; // Stop dijit.form.ComboButton from keeping focus after closing the menu
+ },
+ });
+});
diff --git a/js/form/DropDownButton.js b/js/form/DropDownButton.js
new file mode 100755
index 000000000..0c182772a
--- /dev/null
+++ b/js/form/DropDownButton.js
@@ -0,0 +1,12 @@
+/* global dijit */
+define(["dojo/_base/declare", "dijit/form/DropDownButton"], function (declare) {
+ return declare("fox.form.DropDownButton", dijit.form.DropDownButton, {
+ startup: function() {
+ this.inherited(arguments);
+ this.dropDown.autoFocus = true; // Allow dropdown menu to be focused on click
+ },
+ focus: function() {
+ return; // Stop dijit.form.DropDownButton from keeping focus after closing the menu
+ },
+ });
+});
diff --git a/js/form/Select.js b/js/form/Select.js
new file mode 100755
index 000000000..c62db1821
--- /dev/null
+++ b/js/form/Select.js
@@ -0,0 +1,8 @@
+/* global dijit */
+define(["dojo/_base/declare", "dijit/form/Select"], function (declare) {
+ return declare("fox.form.Select", dijit.form.Select, {
+ focus: function() {
+ return; // Stop dijit.form.Select from keeping focus after closing the menu
+ },
+ });
+});
diff --git a/js/prefs.js b/js/prefs.js
index b4ac9976e..844ce8c8a 100755
--- a/js/prefs.js
+++ b/js/prefs.js
@@ -53,7 +53,11 @@ require(["dojo/_base/kernel",
"fox/PrefFilterStore",
"fox/PrefFeedTree",
"fox/PrefFilterTree",
- "fox/PrefLabelTree"], function (dojo, declare, ready, parser, AppBase) {
+ "fox/PrefLabelTree",
+ "fox/Toolbar",
+ "fox/form/Select",
+ "fox/form/ComboButton",
+ "fox/form/DropDownButton"], function (dojo, declare, ready, parser, AppBase) {
ready(function () {
try {
@@ -78,6 +82,7 @@ require(["dojo/_base/kernel",
this.enableCsrfSupport();
document.onkeydown = (event) => { return App.hotkeyHandler(event) };
+ document.onkeypress = (event) => { return App.hotkeyHandler(event) };
App.setLoadingProgress(50);
Notify.close();
@@ -117,6 +122,10 @@ require(["dojo/_base/kernel",
hotkeyHandler: function (event) {
if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return;
+ // Arrow buttons and escape are not reported via keypress, handle them via keydown.
+ // escape = 27, left = 37, up = 38, right = 39, down = 40
+ if (event.type == "keydown" && event.which != 27 && (event.which < 37 || event.which > 40)) return;
+
const action_name = App.keyeventToAction(event);
if (action_name) {
diff --git a/js/tt-rss.js b/js/tt-rss.js
index 99b44549b..a31404426 100644
--- a/js/tt-rss.js
+++ b/js/tt-rss.js
@@ -54,7 +54,11 @@ require(["dojo/_base/kernel",
"fox/Headlines",
"fox/Article",
"fox/FeedStoreModel",
- "fox/FeedTree"], function (dojo, declare, ready, parser, AppBase) {
+ "fox/FeedTree",
+ "fox/Toolbar",
+ "fox/form/Select",
+ "fox/form/ComboButton",
+ "fox/form/DropDownButton"], function (dojo, declare, ready, parser, AppBase) {
ready(function () {
try {
@@ -144,13 +148,6 @@ require(["dojo/_base/kernel",
dijit.getEnclosingWidget(toolbar.order_by).attr('value',
App.getInitParam("default_view_order_by"));
- const hash_feed_id = hash_get('f');
- const hash_feed_is_cat = hash_get('c') == "1";
-
- if (hash_feed_id != undefined) {
- Feeds.setActive(hash_feed_id, hash_feed_is_cat);
- }
-
App.setLoadingProgress(50);
this._widescreen_mode = App.getInitParam("widescreen");
@@ -203,9 +200,13 @@ require(["dojo/_base/kernel",
isCombinedMode: function() {
return App.getInitParam("combined_display_mode");
},
- hotkeyHandler(event) {
+ hotkeyHandler: function(event) {
if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return;
+ // Arrow buttons and escape are not reported via keypress, handle them via keydown.
+ // escape = 27, left = 37, up = 38, right = 39, down = 40
+ if (event.type == "keydown" && event.which != 27 && (event.which < 37 || event.which > 40)) return;
+
const action_name = App.keyeventToAction(event);
if (action_name) {
@@ -412,6 +413,9 @@ require(["dojo/_base/kernel",
dijit.byId("feedTree").collapseCat(Feeds.getActive());
}
};
+ this.hotkey_actions["goto_read"] = function () {
+ Feeds.open({feed: -6});
+ };
this.hotkey_actions["goto_all"] = function () {
Feeds.open({feed: -4});
};