diff --git a/backend.php b/backend.php index ee68d9779..8e8fc91d1 100644 --- a/backend.php +++ b/backend.php @@ -50,7 +50,8 @@ if ((!$op || $op == "rpc" || $op == "rss" || ($op == "view" && $mode != "zoom") || - $op == "digestSend" || $op == "dlg" || $op == "viewfeed" || $op == "publish" || + $op == "digestSend" || $op == "dlg" || + $op == "viewfeed" || $op == "publish" || $op == "globalUpdateFeeds") && !$_REQUEST["noxml"]) { header("Content-Type: application/xml; charset=utf-8"); @@ -160,10 +161,7 @@ break; // rpc case "feeds": - if (ENABLE_GZIP_OUTPUT) { - ob_start("ob_gzhandler"); - } - + $print_exec_time = true; $tags = $_REQUEST["tags"]; $subop = $_REQUEST["subop"]; @@ -208,7 +206,8 @@ } - outputFeedList($link, $tags); + print json_encode(outputFeedList($link, $tags)); + break; // feeds case "view": diff --git a/feedlist.js b/feedlist.js index 47d310404..5b6467852 100644 --- a/feedlist.js +++ b/feedlist.js @@ -13,7 +13,7 @@ var feeds_sort_by_unread = false; var feedlist_sortable_enabled = false; function toggle_sortable_feedlist(enabled) { - try { +/* try { if (enabled) { Sortable.create('feedList', {onChange: feedlist_dragsorted, only: "feedCat"}); @@ -23,7 +23,7 @@ function toggle_sortable_feedlist(enabled) { } catch (e) { exception_error("toggle_sortable_feedlist", e); - } + } */ } function viewCategory(cat) { @@ -31,7 +31,7 @@ function viewCategory(cat) { return false; } -function render_feedlist(data) { +/* function render_feedlist(data) { try { var f = $("feeds-frame"); @@ -43,7 +43,7 @@ function render_feedlist(data) { } catch (e) { exception_error("render_feedlist", e); } -} +} */ function viewNextFeedPage() { try { @@ -579,8 +579,12 @@ function parse_counters(reply, scheduled_call) { feeds_found = ctr; continue; } + + var treeItem; + + setFeedUnread(id, (kind == "cat"), ctr); - if (kind && kind == "cat") { +/* if (kind && kind == "cat") { var catctr = $("FCATCTR-" + id); if (catctr) { catctr.innerHTML = "(" + ctr + ")"; @@ -678,8 +682,8 @@ function parse_counters(reply, scheduled_call) { feedctr.removeClassName("Unread"); feedr.removeClassName("Unread"); } - } - } + } */ + } hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); @@ -692,7 +696,7 @@ function parse_counters(reply, scheduled_call) { if (feeds_stored != 0 && feeds_found != 0) { console.log("Subscribed feed number changed, refreshing feedlist"); - setTimeout('updateFeedList(false, false)', 50); + setTimeout('updateFeedList()', 50); } } else { /* var fl = $("feeds-frame").innerHTML; @@ -807,7 +811,7 @@ function resort_feedlist() { function hideOrShowFeeds(hide) { - try { +/* try { if ($("FCATLIST--1")) { @@ -823,7 +827,7 @@ function hideOrShowFeeds(hide) { } catch (e) { exception_error("hideOrShowFeeds", e); - } + } */ } function hideOrShowFeedsCategory(cat_id, hide) { @@ -994,4 +998,17 @@ function feedsSortByUnread() { return feeds_sort_by_unread; } +function setFeedUnread(feed, is_cat, unread) { + try { + if (is_cat) + treeItem = treeModel.store._itemsByIdentity['CAT:' + feed]; + else + treeItem = treeModel.store._itemsByIdentity['FEED:' + feed]; + + if (treeItem) + treeModel.store.setValue(treeItem, 'unread', parseInt(unread)); + } catch (e) { + exception_error("setFeedUnread", e); + } +} diff --git a/functions.php b/functions.php index 67e3087ec..17bb9774f 100644 --- a/functions.php +++ b/functions.php @@ -4306,68 +4306,62 @@ function outputFeedList($link, $tags = false) { - print ""; + if ($enable_cats) { + array_push($feedlist['items'], $cat); + } else { + $feedlist['items'] = array_merge($feedlist['items'], $cat['items']); } if (!$tags) { - - $result = db_query($link, "SELECT * FROM - ttrss_labels2 WHERE owner_uid = '$owner_uid' ORDER by caption"); + $result = db_query($link, "SELECT * FROM + ttrss_labels2 WHERE owner_uid = '$owner_uid' ORDER by caption"); - if (db_num_rows($result) > 0) { - if (get_pref($link, 'ENABLE_FEED_CATS')) { - - $cat_hidden = get_pref($link, "_COLLAPSED_LABELS"); - - printCategoryHeader($link, -2, $cat_hidden, true); - - } else { - print "

  • "; - } + if (db_num_rows($result) > 0) { + if (get_pref($link, 'ENABLE_FEED_CATS')) { + $cat_hidden = get_pref($link, "_COLLAPSED_LABELS"); + $cat = feedlist_init_cat($link, -2, $cat_hidden); + } else { + $cat['items'] = array(); } - - while ($line = db_fetch_assoc($result)) { - - $label_id = -$line['id'] - 11; - $count = getFeedUnread($link, $label_id); + } - printFeedEntry($label_id, - "label", $line["caption"], - $count, false, $link, - false, false, false, - $line['fg_color'], $line['bg_color']); - - } + while ($line = db_fetch_assoc($result)) { - if (db_num_rows($result) > 0) { - if (get_pref($link, 'ENABLE_FEED_CATS')) { - print ""; - } - } + $label_id = -$line['id'] - 11; + $count = getFeedUnread($link, $label_id); + array_push($cat['items'], feedlist_init_feed($link, $label_id, + false, $count)); + } - if (!get_pref($link, 'ENABLE_FEED_CATS')) { - print "

  • "; + if ($enable_cats) { + array_push($feedlist['items'], $cat); + } else { + $feedlist['items'] = array_merge($feedlist['items'], $cat['items']); } if (get_pref($link, 'ENABLE_FEED_CATS')) { @@ -4386,7 +4380,7 @@ $age_qpart = getMaxAgeSubquery(); - $query = "SELECT ttrss_feeds.*, + $query = "SELECT ttrss_feeds.id, ttrss_feeds.title, ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated_noms, cat_id,last_error, ttrss_feed_categories.title AS category, @@ -4407,12 +4401,13 @@ /* real feeds */ - $lnum = 0; - - $total_unread = 0; - $category = ""; - + + if (!$enable_cats) + $cat['items'] = array(); + else + $cat = false; + while ($line = db_fetch_assoc($result)) { $feed = htmlspecialchars(trim($line["title"])); @@ -4421,48 +4416,13 @@ $feed_id = $line["id"]; $unread = $line["unread"]; - - $subop = $_REQUEST["subop"]; - - $last_updated = make_local_datetime($link, $line['last_updated_noms'], - false); - - $rtl_content = sql_bool_to_bool($line["rtl_content"]); - - if ($rtl_content) { - $rtl_tag = "dir=\"RTL\""; - } else { - $rtl_tag = ""; - } $cat_id = $line["cat_id"]; - $tmp_category = $line["category"]; + if (!$tmp_category) $tmp_category = __("Uncategorized"); - if (!$tmp_category) { - $tmp_category = __("Uncategorized"); - } - - // $class = ($lnum % 2) ? "even" : "odd"; - - if ($line["last_error"]) { - $class = "error"; - } else { - $class = "feed"; - } - - if ($actid == $feed_id) { - $class .= " Selected"; - } - - $total_unread += $unread; - - if ($category != $tmp_category && get_pref($link, 'ENABLE_FEED_CATS')) { - - if ($category) { - print ""; - } - + if ($category != $tmp_category && $enable_cats) { + $category = $tmp_category; $collapsed = sql_bool_to_bool($line["collapsed"]); @@ -4472,20 +4432,20 @@ $collapsed = get_pref($link, "_COLLAPSED_UNCAT"); } - $cat_id = (int) $cat_id; - - printCategoryHeader($link, $cat_id, $collapsed, true); + if ($cat) array_push($feedlist['items'], $cat); + $cat = feedlist_init_cat($link, $cat_id, $collapsed); } - - printFeedEntry($feed_id, $class, $feed, $unread, - false, $link, $rtl_content, - $last_updated, $line["last_error"]); - - ++$lnum; + + array_push($cat['items'], feedlist_init_feed($link, $feed_id, + $feed, $unread)); } - if (db_num_rows($result) == 0) { + if (!$enable_cats) { + $feedlist['items'] = array_merge($feedlist['items'], $cat['items']); + } + +/* if (db_num_rows($result) == 0) { if (!get_pref($link, 'ENABLE_FEED_CATS')) { print "
  • "; } - } + } */ } else { // tags -/* $result = db_query($link, "SELECT tag_name,count(ttrss_entries.id) AS count - FROM ttrss_tags,ttrss_entries,ttrss_user_entries WHERE - post_int_id = ttrss_user_entries.int_id AND - unread = true AND ref_id = ttrss_entries.id - AND ttrss_tags.owner_uid = '$owner_uid' GROUP BY tag_name - UNION - select tag_name,0 as count FROM ttrss_tags WHERE owner_uid = '$owner_uid' - ORDER BY tag_name"); */ - if (get_pref($link, 'ENABLE_FEED_CATS')) { - print "
  • ".__('Tags')."
  • "; - print ""; } } - print ""; +# print ""; + + return $feedlist; } function get_article_tags($link, $id, $owner_uid = 0) { @@ -6819,7 +6772,9 @@ function generate_dashboard_feed($link) { print ""; - print ''; + print ""; + + print '".__('No feed selected.'); @@ -6845,7 +6800,7 @@ } print "

    "; - print "]]>"; + print "]]>
    "; print "
    "; print " 0) { + $cat_unread = ccache_find($link, $cat_id, $_SESSION["uid"], true); + } else if ($cat_id == 0 || $cat_id == -2) { + $cat_unread = getCategoryUnread($link, $cat_id); + } + + $obj['id'] = 'CAT:' . $cat_id; + $obj['items'] = array(); + $obj['name'] = getCategoryTitle($link, $cat_id); + $obj['type'] = 'feed'; + $obj['unread'] = (int) $cat_unread; + $obj['hidden'] = $hidden; + + return $obj; + } + + function feedlist_init_feed($link, $feed_id, $title = false, $unread = false) { + $obj = array(); + + if (!$title) + $title = getFeedTitle($link, $feed_id, false); + + if (!$unread) + $unread = getFeedUnread($link, $feed_id, false); + + $obj['id'] = 'FEED:' . $feed_id; + $obj['name'] = $title; + $obj['unread'] = (int) $unread; + $obj['type'] = 'feed'; + + return $obj; + } + ?> diff --git a/tt-rss.css b/tt-rss.css index 5200301e4..aedec4ffa 100644 --- a/tt-rss.css +++ b/tt-rss.css @@ -1803,3 +1803,9 @@ div.fatalError textarea { #content-insert { padding : 0px; } + +.dijitTreeLabel.Unread { + font-weight : bold; +} + + diff --git a/tt-rss.js b/tt-rss.js index b0e747a0c..133a93abb 100644 --- a/tt-rss.js +++ b/tt-rss.js @@ -10,6 +10,7 @@ var hotkey_prefix_pressed = false; var init_params = {}; var _force_scheduled_update = false; var last_scheduled_update = false; +var treeModel; var _rpc_seq = 0; @@ -97,9 +98,9 @@ function dlg_frefresh_callback(transport, deleted_feed) { function updateFeedList() { try { - //console.log("updateFeedList"); + console.log("updateFeedList"); - var query_str = "backend.php?op=feeds"; +/* var query_str = "backend.php?op=feeds"; if (display_tags) { query_str = query_str + "&tags=1"; @@ -113,7 +114,7 @@ function updateFeedList() { parameters: query_str, onComplete: function(transport) { render_feedlist(transport.responseText); - } }); + } }); */ } catch (e) { exception_error("updateFeedList", e); @@ -244,8 +245,52 @@ function init() { dojo.require("dijit.layout.ContentPane"); dojo.require("dijit.Dialog"); dojo.require("dijit.form.Button"); - - //return remove_splash(); + dojo.require("dojo.data.ItemFileReadStore"); + dojo.require("dojo.data.ItemFileWriteStore"); + dojo.require("dijit.Tree"); + + dojo.addOnLoad(function() { + + var store = new dojo.data.ItemFileWriteStore({ + url: "backend.php?op=feeds"}); + + treeModel = new dijit.tree.ForestStoreModel({ + store: store, + query: { + "type": "feed" + }, + rootId: "root", + rootLabel: "Feeds", + childrenAttrs: ["items"] + }); + + var tree = new dijit.Tree({ + model: treeModel, + _createTreeNode: function(args) { + var tnode = new dijit._TreeNode(args); + tnode.labelNode.innerHTML = args.label; + return tnode; + }, + getLabelClass: function (item, opened) { + return (item.unread == 0) ? "dijitTreeLabel" : "dijitTreeLabel Unread"; + }, + getLabel: function(item) { + if (item.unread > 0) { + return item.name + " (" + item.unread + ")"; + } else { + return item.name; + } + }, + onClick: function (item, node) { + var id = String(item.id); + var is_cat = id.match("^CAT:"); + var feed = id.substr(id.indexOf(":")+1); + viewfeed(feed, '', is_cat); + }, + showRoot: false, + }, "feedTree"); + + }); if (!genericSanityCheck()) return; @@ -278,7 +323,8 @@ function init_second_stage() { feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1; - setTimeout('updateFeedList(false, false)', 50); + remove_splash(); + feedlist_init(); console.log("second stage ok"); diff --git a/tt-rss.php b/tt-rss.php index 1abda3b53..07fb1c24d 100644 --- a/tt-rss.php +++ b/tt-rss.php @@ -124,7 +124,7 @@
    -
     
    +