From cde0e08f0783e2139b712c3d27cc5184aa3dd387 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Fri, 8 Apr 2016 20:51:46 +0200 Subject: Fix #850 --- CHANGELOG.md | 3 +- js/gui/KeyboardShortcuts.js | 99 ++++++++++++++++++++++-------------- templates/part.content.shortcuts.php | 4 ++ 3 files changed, 67 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28f59ad43..2a3bfcb96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -owncloud-news (8.2.1) +owncloud-news (8.3.0) * **Bugfix**: Do not abort full OPML import if one feed failed, #843 * **Bugfix**: Show error message when empty OPML file was imported, #924 +* **Enhancement**: Add a keyboard shortcut for opening the next five unread articles, #850 owncloud-news (8.2.0) * **Backwards incompatible change**: Move updater into separate repository at https://github.com/owncloud/news-updater and publish it on pypi diff --git a/js/gui/KeyboardShortcuts.js b/js/gui/KeyboardShortcuts.js index d05856152..62e4a8866 100644 --- a/js/gui/KeyboardShortcuts.js +++ b/js/gui/KeyboardShortcuts.js @@ -35,7 +35,8 @@ }; var markAllRead = function (navigationArea) { - var selector = '.active > .app-navigation-entry-menu .mark-read button'; + var selector = + '.active > .app-navigation-entry-menu .mark-read button'; var button = navigationArea.find(selector); if (button.length > 0) { button.trigger('click'); @@ -53,17 +54,32 @@ }; var scrollToNavigationElement = function (elem, scrollArea, toTop) { - if (elem.length === 0 || (!toTop && isInScrollView(elem, scrollArea))) { + if (elem.length === 0 || + (!toTop && isInScrollView(elem, scrollArea))) { return; } scrollArea.scrollTop( - elem.offset().top - scrollArea.offset().top + scrollArea.scrollTop() + elem.offset().top - scrollArea.offset().top + + scrollArea.scrollTop() ); }; + var openAllUnread = function (navigationArea, scrollArea) { + var unreadItems = $(scrollArea).find('.item:not(.read)'); + // only open a maximum of 10 new tabs + unreadItems.slice(0, 5).each(function (index, element) { + var url = $(element) + .find('.external:visible') + .attr('href'); + $(element).trigger('click'); // mark read + window.open(url, '_blank'); + }); + }; + var scrollToActiveNavigationEntry = function (navigationArea) { var element = navigationArea.find('.active'); - scrollToNavigationElement(element, navigationArea.children('ul'), true); + scrollToNavigationElement(element, + navigationArea.children('ul'), true); }; var reloadFeed = function (navigationArea) { @@ -89,9 +105,9 @@ var nextFeed = function (navigationArea) { var current = navigationArea.find('.active'); var elements = navigationArea.find('.explore-feed,' + - '.subscriptions-feed:visible,' + - '.starred-feed:visible,' + - '.feed:visible'); + '.subscriptions-feed:visible,' + + '.starred-feed:visible,' + + '.feed:visible'); if (current.hasClass('folder')) { while (current.length > 0) { @@ -107,13 +123,13 @@ return; } - // FIXME: O(n) runtime. If someone creates a nice and not fugly solution + // FIXME: O(n) runtime. If someone creates a nice non fugly solution // please create a PR - for (var i=0; i 0) { var subfeeds = previousFolder.find('.feed:visible'); if (subfeeds.length > 0) { - activateNavigationEntry($(subfeeds[subfeeds.length-1]), + activateNavigationEntry($(subfeeds[subfeeds.length - 1]), navigationArea); return; } @@ -206,7 +222,7 @@ var feeds = current.siblings('.feed'); if (feeds.length > 0) { - activateNavigationEntry($(feeds[feeds.length-1]), + activateNavigationEntry($(feeds[feeds.length - 1]), navigationArea); return; } @@ -221,13 +237,13 @@ return; } - // FIXME: O(n) runtime. If someone creates a nice and not fugly solution + // FIXME: O(n) runtime. If someone creates a nice non fugly solution // please create a PR - for (var i=elements.length-1; i>0; i-=1) { + for (var i = elements.length - 1; i > 0; i -= 1) { var element = elements[i]; if (element === current[0]) { - var previous = elements[i-1]; + var previous = elements[i - 1]; activateNavigationEntry($(previous), navigationArea); break; } @@ -279,7 +295,8 @@ // if you go to the next article in compact view, it should // expand the current one scrollArea.scrollTop( - item.offset().top - scrollArea.offset().top + scrollArea.scrollTop() + item.offset().top - scrollArea.offset().top + + scrollArea.scrollTop() ); if (expandItemInCompact) { @@ -301,8 +318,9 @@ // special treatment for items that have expand enabled: // if you click next and the first item has not been expaned and // is on the top, it should be expanded instead of the next one - if ((item.position().top === 0 && expandItemInCompact && - !item.hasClass('open')) || + if ((item.position().top === 0 && + expandItemInCompact && + !item.hasClass('open')) || item.position().top > 10) { scrollToItem(scrollArea, item, expandItemInCompact); @@ -357,7 +375,7 @@ var navigationArea = $('#app-navigation'); var isCompactView = $('#articles.compact').length > 0; var isExpandItem = $('#articles') - .attr('news-compact-expand') === 'true'; + .attr('news-compact-expand') === 'true'; var expandItemInCompact = isCompactView && isExpandItem; if (noInputFocused($(':focus')) && noModifierKey(event)) { @@ -367,94 +385,94 @@ event.preventDefault(); scrollToNextItem(scrollArea, expandItemInCompact); - // k, p, left arrow + // k, p, left arrow } else if ([75, 80, 37].indexOf(keyCode) >= 0) { event.preventDefault(); scrollToPreviousItem(navigationArea, scrollArea, - expandItemInCompact); + expandItemInCompact); - // u + // u } else if ([85].indexOf(keyCode) >= 0) { event.preventDefault(); toggleUnread(scrollArea); - // e + // e } else if ([69].indexOf(keyCode) >= 0) { event.preventDefault(); expandItem(scrollArea); - // s, i, l + // s, i, l } else if ([73, 83, 76].indexOf(keyCode) >= 0) { event.preventDefault(); toggleStar(scrollArea); - // h + // h } else if ([72].indexOf(keyCode) >= 0) { event.preventDefault(); toggleStar(scrollArea); scrollToNextItem(scrollArea); - // o + // o } else if ([79].indexOf(keyCode) >= 0) { event.preventDefault(); openLink(scrollArea); - // r + // r } else if ([82].indexOf(keyCode) >= 0) { event.preventDefault(); reloadFeed(navigationArea); - // f + // f } else if ([70].indexOf(keyCode) >= 0) { event.preventDefault(); nextFeed(navigationArea); - // d + // d } else if ([68].indexOf(keyCode) >= 0) { event.preventDefault(); previousFeed(navigationArea); - // c + // c } else if ([67].indexOf(keyCode) >= 0) { event.preventDefault(); previousFolder(navigationArea); - // a + // a } else if ([65].indexOf(keyCode) >= 0) { event.preventDefault(); scrollToActiveNavigationEntry(navigationArea); - // v + // v } else if ([86].indexOf(keyCode) >= 0) { event.preventDefault(); nextFolder(navigationArea); - // q + // q } else if ([81].indexOf(keyCode) >= 0) { event.preventDefault(); $('#searchbox').focus(); - // page up + // page up } else if ([33].indexOf(keyCode) >= 0) { tryReload(navigationArea, scrollArea); } - // everything with shift + // everything with shift } else if (noInputFocused($(':focus')) && event.shiftKey) { // shift + a @@ -463,6 +481,11 @@ event.preventDefault(); markAllRead(navigationArea); + // shoft + o + } else if ([79].indexOf(keyCode) >= 0) { + + openAllUnread(navigationArea, scrollArea); + } } }); diff --git a/templates/part.content.shortcuts.php b/templates/part.content.shortcuts.php index 82a39efe3..29ec039cb 100644 --- a/templates/part.content.shortcuts.php +++ b/templates/part.content.shortcuts.php @@ -73,6 +73,10 @@ shift + a t('Mark current article\'s feed/folder read')); ?> + + shift + o + t('Open the next 5 unread articles in new tabs')); ?> + \ No newline at end of file -- cgit v1.2.3