diff --git a/assets/js/all.min.js b/assets/js/all.min.js index da80452..f635222 100644 --- a/assets/js/all.min.js +++ b/assets/js/all.min.js @@ -1,12 +1,12 @@ var Miniflux={};Miniflux.App=function(){return{Run:function(){Miniflux.Event.ListenKeyboardEvents();Miniflux.Event.ListenMouseEvents()},MozillaAuth:function(e){navigator.id.watch({onlogin:function(a){var b=new XMLHttpRequest;b.open("POST","?action="+e+"&token="+a,!0);b.setRequestHeader("Connection","close");b.onload=function(){window.location.href=this.responseText};b.send("token="+a)},onlogout:function(){}});navigator.id.request()}}}(); -Miniflux.Feed=function(){function e(b){if(b=document.getElementById("loading-feed-"+b)){b.innerHTML="";var a=document.createElement("img");a.src="assets/img/refresh.gif";b.appendChild(a)}}function a(){for(var a=document.getElementsByTagName("a"),d=0,e=a.length;dd.length;){var a=b.shift();d.push(a);Miniflux.Feed.Update(a,function(a){a=d.indexOf(a.feed_id);0<=a&&d.splice(a,1); -0==b.length&&0==d.length&&(clearInterval(e),window.location.href="?action=unread")})}},100)}}}(); +Miniflux.Feed=function(){function e(b){if(b=document.getElementById("loading-feed-"+b)){var a=document.createElement("img");a.src="assets/img/refresh.gif";b.appendChild(a)}}function a(){for(var a=document.getElementsByTagName("a"),d=0,e=a.length;dd.length;){var a=b.shift();d.push(a);Miniflux.Feed.Update(a,function(a){a=d.indexOf(a.feed_id);0<=a&&d.splice(a,1);0==b.length&& +0==d.length&&(clearInterval(e),window.location.href="?action=unread")})}},100)}}}(); Miniflux.Item=function(){function e(c){var b=document.getElementById("item-"+c);b||(b=document.getElementById("current-item"),b.getAttribute("data-item-id")!=c&&(b=!1));return b}function a(c){if((c=document.getElementById("bookmark-"+c))&&c.getAttribute("data-reverse-label")){var b=c.innerHTML;c.innerHTML=c.getAttribute("data-reverse-label");c.setAttribute("data-reverse-label",b)}}function b(c){if(c=document.getElementById("status-"+c)){var b=c.innerHTML;c.innerHTML=c.getAttribute("data-reverse-label"); c.setAttribute("data-reverse-label",b)}}function d(c){"mouse"!=Miniflux.Event.lastEventType&&Miniflux.Nav.SelectNextItem();c.parentNode.removeChild(c);if(c=document.getElementById("page-counter"))counter=parseInt(c.textContent.trim(),10)-1,0==counter?window.location="?action=unread":(c.textContent=counter+" ",document.title="miniflux ("+counter+")",document.getElementById("nav-counter").textContent="("+counter+")")}function f(c){var a=new XMLHttpRequest;a.onload=function(){if(Miniflux.Nav.IsListing()){var a= -e(c);if(a)if(a.getAttribute("data-hide"))d(a);else{a.setAttribute("data-item-status","read");b(c);if(a=document.getElementById("show-"+c)){a.className="read";var h=document.createElement("span");h.id="read-icon-"+c;h.appendChild(document.createTextNode("\u2611 "));a.parentNode.insertBefore(h,a)}(a=document.getElementById("status-"+c))&&a.setAttribute("data-action","mark-unread")}}};a.open("POST","?action=mark-item-read&id="+c,!0);a.send()}function k(c){var a=new XMLHttpRequest;a.onload=function(){if(Miniflux.Nav.IsListing()){var a= +e(c);if(a)if(a.getAttribute("data-hide"))d(a);else{a.setAttribute("data-item-status","read");b(c);if(a=document.getElementById("show-"+c)){a.className="read";var g=document.createElement("span");g.id="read-icon-"+c;g.appendChild(document.createTextNode("\u2611 "));a.parentNode.insertBefore(g,a)}(a=document.getElementById("status-"+c))&&a.setAttribute("data-action","mark-unread")}}};a.open("POST","?action=mark-item-read&id="+c,!0);a.send()}function k(c){var a=new XMLHttpRequest;a.onload=function(){if(Miniflux.Nav.IsListing()){var a= e(c);if(a)if(a.getAttribute("data-hide"))d(a);else{a.setAttribute("data-item-status","unread");b(c);if(a=document.getElementById("show-"+c))a.className="";(a=document.getElementById("read-icon-"+c))&&a.parentNode.removeChild(a);(a=document.getElementById("status-"+c))&&a.setAttribute("data-action","mark-read")}}};a.open("POST","?action=mark-item-unread&id="+c,!0);a.send()}function l(c,b){var d=c.getAttribute("data-item-id"),e=new XMLHttpRequest;e.onload=function(){c.setAttribute("data-item-bookmark", -b);if(b)if(Miniflux.Nav.IsListing()){if(g=document.getElementById("show-"+d)){var e=document.createElement("span");e.id="bookmark-icon-"+d;e.appendChild(document.createTextNode("\u2605 "));g.parentNode.insertBefore(e,g)}a(d)}else{var g=document.getElementById("bookmark-"+d);g&&(g.innerHTML="\u2605")}else if(Miniflux.Nav.IsListing())(e=document.getElementById("bookmark-icon-"+d))&&e.parentNode.removeChild(e),a(d);else if(e=document.getElementById("bookmark-"+d))e.innerHTML="\u2606"};e.open("POST", +b);if(b)if(Miniflux.Nav.IsListing()){if(h=document.getElementById("show-"+d)){var e=document.createElement("span");e.id="bookmark-icon-"+d;e.appendChild(document.createTextNode("\u2605 "));h.parentNode.insertBefore(e,h)}a(d)}else{var h=document.getElementById("bookmark-"+d);h&&(h.innerHTML="\u2605")}else if(Miniflux.Nav.IsListing())(e=document.getElementById("bookmark-icon-"+d))&&e.parentNode.removeChild(e),a(d);else if(e=document.getElementById("bookmark-"+d))e.innerHTML="\u2606"};e.open("POST", "?action=bookmark&id="+d+"&value="+b,!0);e.send()}return{Get:e,MarkAsRead:f,MarkAsUnread:k,SwitchBookmark:function(c){"1"==c.getAttribute("data-item-bookmark")?l(c,0):l(c,1)},SwitchStatus:function(c){var a=c.getAttribute("data-item-id");c=c.getAttribute("data-item-status");"read"==c?k(a):"unread"==c&&f(a)},ChangeStatus:function(c,a){switch(a){case "read":f(c);break;case "unread":k(c)}},Show:function(c){(c=document.getElementById("show-"+c))&&c.click()},OpenOriginal:function(c){var a=document.getElementById("original-"+ c);a&&("unread"==e(c).getAttribute("data-item-status")&&f(c),a.removeAttribute("data-action"),a.click())},DownloadContent:function(){var a=document.getElementById("download-item");if(a){var b=a.getAttribute("data-item-id"),d=a.getAttribute("data-before-message"),e=document.createElement("img");e.src="./assets/img/refresh.gif";a.innerHTML="";a.className="downloading";a.appendChild(e);a.appendChild(document.createTextNode(" "+d));var f=new XMLHttpRequest;f.onload=function(){var b=JSON.parse(f.responseText); if(b.result){var d=document.getElementById("item-content");d&&(d.innerHTML=b.content);a&&(b=a.getAttribute("data-after-message"),a.innerHTML="",a.appendChild(document.createTextNode(" "+b)))}else a&&(b=a.getAttribute("data-failure-message"),a.innerHTML="",a.appendChild(document.createTextNode(" "+b)))};f.open("POST","?action=download-item&id="+b,!0);f.send()}},MarkListingAsRead:function(a){for(var b=document.getElementsByTagName("article"),d=[],e=0,f=b.length;e $id, 'result' => $result)); + Response\json(array( + 'feed_id' => $feed_id, + 'result' => Model\Feed\refresh($feed_id), + 'items_count' => Model\Feed\count_items($feed_id), + )); }); // Display all feeds @@ -194,7 +197,7 @@ Router\get_action('feeds', function() { } Response\html(Template\layout('feeds', array( - 'feeds' => Model\Feed\get_all_w_counts(), + 'feeds' => Model\Feed\get_all_item_counts(), 'nothing_to_read' => Request\int_param('nothing_to_read'), 'menu' => 'feeds', 'title' => t('Subscriptions') diff --git a/models/feed.php b/models/feed.php index ae48475..7c650aa 100644 --- a/models/feed.php +++ b/models/feed.php @@ -157,11 +157,11 @@ function refresh($feed_id) // Update the `last_checked` column each time, HTTP cache or not update_last_checked($feed_id); - + if (! $resource->isModified()) { update_parsing_error($feed_id, 0); \Model\Config\write_debug(); - return get_feed_unread_counts($feed_id); + return true; } $parser = $reader->getParser(); @@ -182,7 +182,7 @@ function refresh($feed_id) } $result = $parser->execute(); - + if ($result !== false) { update_parsing_error($feed_id, 0); @@ -190,7 +190,7 @@ function refresh($feed_id) \Model\Item\update_all($feed_id, $result->items, $parser->grabber); \Model\Config\write_debug(); - return get_feed_unread_counts($feed_id); + return true; } } @@ -244,56 +244,81 @@ function get_all() ->findAll(); } -// Returns item unread and total counts, indexed by feed_id -// setting $feed_id returns counts for just that feed -function get_feed_unread_counts($feed_id = 0) +// Get all feeds with the number unread/total items +function get_all_item_counts() { - $query = Database::get('db') + $counts = Database::get('db') ->table('items') - ->columns('feed_id', 'status', 'count(status) AS item_count') + ->columns('feed_id', 'status', 'count(*) as item_count') ->in('status', array('read', 'unread')) - ->groupBy('feed_id', 'status'); - if ($feed_id) $query->eq('feed_id', $feed_id); - $rq = $query->findAll(); + ->groupBy('feed_id', 'status') + ->findAll(); - $itemcnts = array(); - foreach($rq as $rec) { - if (!array_key_exists($rec['feed_id'], $itemcnts)) - $itemcnts[$rec['feed_id']] = array('items_unread' => 0, 'items_total' => 0); - if ($rec['status'] == 'unread') - $itemcnts[$rec['feed_id']]['items_unread'] = $rec['item_count']; - $itemcnts[$rec['feed_id']]['items_total'] += $rec['item_count']; - } - if ($feed_id) - // return the counts for the singe feed requested - if(! array_key_exists($feed_id, $itemcnts)) - return array('items_unread' => 0, 'items_total' => 0); - else - return $itemcnts[$feed_id]; - else - // return the counts for all feeds - return $itemcnts; -} + $feeds = Database::get('db') + ->table('feeds') + ->asc('title') + ->findAll(); -// Get all feeds with counts of items_unread and items_total for each feed -function get_all_w_counts() -{ - // get unread and total item counts by feed id - $cnts = get_feed_unread_counts(); - // get all feeds - $rq = get_all(); - // for loop re-processes return array by appending items_unread and items_total fields - foreach ($rq as $rec_no => $rec) { - // determine if there are item counts for this feed - if (array_key_exists($rec['id'], $cnts)) { - // yes, append unread and total counts to the feed record - $rq[$rec_no] = array_merge($rec, $cnts[$rec['id']]); - } else { - // no this is an empty feed, so append unread and total counts = 0 - $rq[$rec_no] = array_merge($rec, array('items_unread' => 0, 'items_total' => 0)); + $item_counts = array(); + + foreach ($counts as &$count) { + + if (! isset($item_counts[$count['feed_id']])) { + $item_counts[$count['feed_id']] = array( + 'items_unread' => 0, + 'items_total' => 0, + ); + } + + $item_counts[$count['feed_id']]['items_total'] += $count['item_count']; + + if ($count['status'] === 'unread') { + $item_counts[$count['feed_id']]['items_unread'] = $count['item_count']; } } - return $rq; + + foreach ($feeds as &$feed) { + + if (isset($item_counts[$feed['id']])) { + $feed += $item_counts[$feed['id']]; + } + else { + $feed += array( + 'items_unread' => 0, + 'items_total' => 0, + ); + } + } + + return $feeds; +} + +// Get unread/total count for one feed +function count_items($feed_id) +{ + $counts = Database::get('db') + ->table('items') + ->columns('status', 'count(*) as item_count') + ->in('status', array('read', 'unread')) + ->eq('feed_id', $feed_id) + ->groupBy('status') + ->findAll(); + + $result = array( + 'items_unread' => 0, + 'items_total' => 0, + ); + + foreach ($counts as &$count) { + + if ($count['status'] === 'unread') { + $result['items_unread'] = (int) $count['item_count']; + } + + $result['items_total'] += $count['item_count']; + } + + return $result; } // Get one feed diff --git a/templates/feeds.php b/templates/feeds.php index 02a33df..fe1c094 100644 --- a/templates/feeds.php +++ b/templates/feeds.php @@ -25,10 +25,13 @@ - () + + () + +