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/Feeds.js1
-rwxr-xr-xjs/Headlines.js93
-rw-r--r--js/PrefFeedTree.js4
-rw-r--r--js/PrefUsers.js2
-rwxr-xr-xjs/prefs.js1
-rw-r--r--js/tt-rss.js4
8 files changed, 129 insertions, 54 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/Feeds.js b/js/Feeds.js
index 401d669a7..ba63aac47 100644
--- a/js/Feeds.js
+++ b/js/Feeds.js
@@ -196,6 +196,7 @@ 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()) {
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/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/prefs.js b/js/prefs.js
index b4ac9976e..ae6286330 100755
--- a/js/prefs.js
+++ b/js/prefs.js
@@ -78,6 +78,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();
diff --git a/js/tt-rss.js b/js/tt-rss.js
index 99b44549b..a46fc17e4 100644
--- a/js/tt-rss.js
+++ b/js/tt-rss.js
@@ -206,6 +206,10 @@ require(["dojo/_base/kernel",
hotkeyHandler(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) {