initial implementation of feedlist based on dijit.Tree

master
Andrew Dolgov 14 years ago
parent 6e4f4ce14b
commit 13e785e069

@ -50,7 +50,8 @@
if ((!$op || $op == "rpc" || $op == "rss" || if ((!$op || $op == "rpc" || $op == "rss" ||
($op == "view" && $mode != "zoom") || ($op == "view" && $mode != "zoom") ||
$op == "digestSend" || $op == "dlg" || $op == "viewfeed" || $op == "publish" || $op == "digestSend" || $op == "dlg" ||
$op == "viewfeed" || $op == "publish" ||
$op == "globalUpdateFeeds") && !$_REQUEST["noxml"]) { $op == "globalUpdateFeeds") && !$_REQUEST["noxml"]) {
header("Content-Type: application/xml; charset=utf-8"); header("Content-Type: application/xml; charset=utf-8");
@ -160,10 +161,7 @@
break; // rpc break; // rpc
case "feeds": case "feeds":
if (ENABLE_GZIP_OUTPUT) { $print_exec_time = true;
ob_start("ob_gzhandler");
}
$tags = $_REQUEST["tags"]; $tags = $_REQUEST["tags"];
$subop = $_REQUEST["subop"]; $subop = $_REQUEST["subop"];
@ -208,7 +206,8 @@
} }
outputFeedList($link, $tags); print json_encode(outputFeedList($link, $tags));
break; // feeds break; // feeds
case "view": case "view":

@ -13,7 +13,7 @@ var feeds_sort_by_unread = false;
var feedlist_sortable_enabled = false; var feedlist_sortable_enabled = false;
function toggle_sortable_feedlist(enabled) { function toggle_sortable_feedlist(enabled) {
try { /* try {
if (enabled) { if (enabled) {
Sortable.create('feedList', {onChange: feedlist_dragsorted, only: "feedCat"}); Sortable.create('feedList', {onChange: feedlist_dragsorted, only: "feedCat"});
@ -23,7 +23,7 @@ function toggle_sortable_feedlist(enabled) {
} catch (e) { } catch (e) {
exception_error("toggle_sortable_feedlist", e); exception_error("toggle_sortable_feedlist", e);
} } */
} }
function viewCategory(cat) { function viewCategory(cat) {
@ -31,7 +31,7 @@ function viewCategory(cat) {
return false; return false;
} }
function render_feedlist(data) { /* function render_feedlist(data) {
try { try {
var f = $("feeds-frame"); var f = $("feeds-frame");
@ -43,7 +43,7 @@ function render_feedlist(data) {
} catch (e) { } catch (e) {
exception_error("render_feedlist", e); exception_error("render_feedlist", e);
} }
} } */
function viewNextFeedPage() { function viewNextFeedPage() {
try { try {
@ -580,7 +580,11 @@ function parse_counters(reply, scheduled_call) {
continue; continue;
} }
if (kind && kind == "cat") { var treeItem;
setFeedUnread(id, (kind == "cat"), ctr);
/* if (kind && kind == "cat") {
var catctr = $("FCATCTR-" + id); var catctr = $("FCATCTR-" + id);
if (catctr) { if (catctr) {
catctr.innerHTML = "(" + ctr + ")"; catctr.innerHTML = "(" + ctr + ")";
@ -678,7 +682,7 @@ function parse_counters(reply, scheduled_call) {
feedctr.removeClassName("Unread"); feedctr.removeClassName("Unread");
feedr.removeClassName("Unread"); feedr.removeClassName("Unread");
} }
} } */
} }
hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
@ -692,7 +696,7 @@ function parse_counters(reply, scheduled_call) {
if (feeds_stored != 0 && feeds_found != 0) { if (feeds_stored != 0 && feeds_found != 0) {
console.log("Subscribed feed number changed, refreshing feedlist"); console.log("Subscribed feed number changed, refreshing feedlist");
setTimeout('updateFeedList(false, false)', 50); setTimeout('updateFeedList()', 50);
} }
} else { } else {
/* var fl = $("feeds-frame").innerHTML; /* var fl = $("feeds-frame").innerHTML;
@ -807,7 +811,7 @@ function resort_feedlist() {
function hideOrShowFeeds(hide) { function hideOrShowFeeds(hide) {
try { /* try {
if ($("FCATLIST--1")) { if ($("FCATLIST--1")) {
@ -823,7 +827,7 @@ function hideOrShowFeeds(hide) {
} catch (e) { } catch (e) {
exception_error("hideOrShowFeeds", e); exception_error("hideOrShowFeeds", e);
} } */
} }
function hideOrShowFeedsCategory(cat_id, hide) { function hideOrShowFeedsCategory(cat_id, hide) {
@ -994,4 +998,17 @@ function feedsSortByUnread() {
return feeds_sort_by_unread; 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);
}
}

@ -4306,43 +4306,46 @@
function outputFeedList($link, $tags = false) { function outputFeedList($link, $tags = false) {
print "<ul class=\"feedList\" id=\"feedList\">"; $feedlist = array();
$enable_cats = get_pref($link, 'ENABLE_FEED_CATS');
$feedlist['identifier'] = 'id';
$feedlist['label'] = 'name';
$feedlist['items'] = array();
$owner_uid = $_SESSION["uid"]; $owner_uid = $_SESSION["uid"];
/* virtual feeds */ /* virtual feeds */
if (get_pref($link, 'ENABLE_FEED_CATS')) { if ($enable_cats) {
$cat_hidden = get_pref($link, "_COLLAPSED_SPECIAL"); $cat_hidden = get_pref($link, "_COLLAPSED_SPECIAL");
$cat = feedlist_init_cat($link, -1, $cat_hidden);
printCategoryHeader($link, -1, $cat_hidden, false); } else {
$cat['items'] = array();
} }
foreach (array(-4, -3, -1, -2, 0) as $i) { foreach (array(-4, -3, -1, -2, 0) as $i) {
printFeedEntry($i, "virt", false, false, array_push($cat['items'], feedlist_init_feed($link, $i));
false, $link);
} }
if (get_pref($link, 'ENABLE_FEED_CATS')) { if ($enable_cats) {
print "</ul></li>"; array_push($feedlist['items'], $cat);
} else {
$feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
} }
if (!$tags) { if (!$tags) {
$result = db_query($link, "SELECT * FROM $result = db_query($link, "SELECT * FROM
ttrss_labels2 WHERE owner_uid = '$owner_uid' ORDER by caption"); ttrss_labels2 WHERE owner_uid = '$owner_uid' ORDER by caption");
if (db_num_rows($result) > 0) { if (db_num_rows($result) > 0) {
if (get_pref($link, 'ENABLE_FEED_CATS')) { if (get_pref($link, 'ENABLE_FEED_CATS')) {
$cat_hidden = get_pref($link, "_COLLAPSED_LABELS"); $cat_hidden = get_pref($link, "_COLLAPSED_LABELS");
$cat = feedlist_init_cat($link, -2, $cat_hidden);
printCategoryHeader($link, -2, $cat_hidden, true);
} else { } else {
print "<li><hr></li>"; $cat['items'] = array();
} }
} }
@ -4351,23 +4354,14 @@
$label_id = -$line['id'] - 11; $label_id = -$line['id'] - 11;
$count = getFeedUnread($link, $label_id); $count = getFeedUnread($link, $label_id);
printFeedEntry($label_id, array_push($cat['items'], feedlist_init_feed($link, $label_id,
"label", $line["caption"], false, $count));
$count, false, $link,
false, false, false,
$line['fg_color'], $line['bg_color']);
}
if (db_num_rows($result) > 0) {
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "</ul>";
} }
}
if (!get_pref($link, 'ENABLE_FEED_CATS')) { if ($enable_cats) {
print "<li><hr></li>"; array_push($feedlist['items'], $cat);
} else {
$feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
} }
if (get_pref($link, 'ENABLE_FEED_CATS')) { if (get_pref($link, 'ENABLE_FEED_CATS')) {
@ -4386,7 +4380,7 @@
$age_qpart = getMaxAgeSubquery(); $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, ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated_noms,
cat_id,last_error, cat_id,last_error,
ttrss_feed_categories.title AS category, ttrss_feed_categories.title AS category,
@ -4407,12 +4401,13 @@
/* real feeds */ /* real feeds */
$lnum = 0;
$total_unread = 0;
$category = ""; $category = "";
if (!$enable_cats)
$cat['items'] = array();
else
$cat = false;
while ($line = db_fetch_assoc($result)) { while ($line = db_fetch_assoc($result)) {
$feed = htmlspecialchars(trim($line["title"])); $feed = htmlspecialchars(trim($line["title"]));
@ -4422,46 +4417,11 @@
$feed_id = $line["id"]; $feed_id = $line["id"];
$unread = $line["unread"]; $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"]; $cat_id = $line["cat_id"];
$tmp_category = $line["category"]; $tmp_category = $line["category"];
if (!$tmp_category) $tmp_category = __("Uncategorized");
if (!$tmp_category) { if ($category != $tmp_category && $enable_cats) {
$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 "</ul></li>";
}
$category = $tmp_category; $category = $tmp_category;
@ -4472,20 +4432,20 @@
$collapsed = get_pref($link, "_COLLAPSED_UNCAT"); $collapsed = get_pref($link, "_COLLAPSED_UNCAT");
} }
$cat_id = (int) $cat_id; if ($cat) array_push($feedlist['items'], $cat);
printCategoryHeader($link, $cat_id, $collapsed, true);
$cat = feedlist_init_cat($link, $cat_id, $collapsed);
} }
printFeedEntry($feed_id, $class, $feed, $unread, array_push($cat['items'], feedlist_init_feed($link, $feed_id,
false, $link, $rtl_content, $feed, $unread));
$last_updated, $line["last_error"]); }
++$lnum; if (!$enable_cats) {
$feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
} }
if (db_num_rows($result) == 0) { /* if (db_num_rows($result) == 0) {
if (!get_pref($link, 'ENABLE_FEED_CATS')) { if (!get_pref($link, 'ENABLE_FEED_CATS')) {
print "<li style='text-align : center'><a href=\"#\" print "<li style='text-align : center'><a href=\"#\"
@ -4500,24 +4460,15 @@
print "</ul>"; print "</ul>";
} }
} } */
} else { } else {
// tags // 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')) { if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "<li class=\"feedCat\">".__('Tags')."</li>"; # print "<li class=\"feedCat\">".__('Tags')."</li>";
print "<ul class=\"feedCatList\">"; # print "<ul class=\"feedCatList\">";
} }
$age_qpart = getMaxAgeSubquery(); $age_qpart = getMaxAgeSubquery();
@ -4540,22 +4491,24 @@
$unread = $tags[$tag]; $unread = $tags[$tag];
$class = "tag"; $class = "tag";
printFeedEntry($tag, $class, $tag, $unread, "images/tag.png", $link); # printFeedEntry($tag, $class, $tag, $unread, "images/tag.png", $link);
} }
if (db_num_rows($result) == 0) { if (db_num_rows($result) == 0) {
print "<li>No tags to display.</li>"; # print "<li>No tags to display.</li>";
} }
if (get_pref($link, 'ENABLE_FEED_CATS')) { if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "</ul>"; # print "</ul>";
} }
} }
print "</ul>"; # print "</ul>";
return $feedlist;
} }
function get_article_tags($link, $id, $owner_uid = 0) { function get_article_tags($link, $id, $owner_uid = 0) {
@ -6819,7 +6772,9 @@
function generate_dashboard_feed($link) { function generate_dashboard_feed($link) {
print "<headlines id=\"-5\" is_cat=\"\">"; print "<headlines id=\"-5\" is_cat=\"\">";
print '<![CDATA[<div id="headlinesContainer">'; print "<toolbar><![CDATA[]]></toolbar>";
print '<content><![CDATA[';
print "<div class='whiteBox'>".__('No feed selected.'); print "<div class='whiteBox'>".__('No feed selected.');
@ -6845,7 +6800,7 @@
} }
print "</span></p>"; print "</span></p>";
print "</div>]]>"; print "]]></content>";
print "</headlines>"; print "</headlines>";
print "<headlines-info><![CDATA["; print "<headlines-info><![CDATA[";
@ -7181,4 +7136,40 @@
return $tags_deleted; return $tags_deleted;
} }
function feedlist_init_cat($link, $cat_id, $hidden = false) {
$obj = array();
if ($cat_id > 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;
}
?> ?>

@ -1803,3 +1803,9 @@ div.fatalError textarea {
#content-insert { #content-insert {
padding : 0px; padding : 0px;
} }
.dijitTreeLabel.Unread {
font-weight : bold;
}

@ -10,6 +10,7 @@ var hotkey_prefix_pressed = false;
var init_params = {}; var init_params = {};
var _force_scheduled_update = false; var _force_scheduled_update = false;
var last_scheduled_update = false; var last_scheduled_update = false;
var treeModel;
var _rpc_seq = 0; var _rpc_seq = 0;
@ -97,9 +98,9 @@ function dlg_frefresh_callback(transport, deleted_feed) {
function updateFeedList() { function updateFeedList() {
try { try {
//console.log("updateFeedList"); console.log("updateFeedList");
var query_str = "backend.php?op=feeds"; /* var query_str = "backend.php?op=feeds";
if (display_tags) { if (display_tags) {
query_str = query_str + "&tags=1"; query_str = query_str + "&tags=1";
@ -113,7 +114,7 @@ function updateFeedList() {
parameters: query_str, parameters: query_str,
onComplete: function(transport) { onComplete: function(transport) {
render_feedlist(transport.responseText); render_feedlist(transport.responseText);
} }); } }); */
} catch (e) { } catch (e) {
exception_error("updateFeedList", e); exception_error("updateFeedList", e);
@ -244,8 +245,52 @@ function init() {
dojo.require("dijit.layout.ContentPane"); dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.Dialog"); dojo.require("dijit.Dialog");
dojo.require("dijit.form.Button"); dojo.require("dijit.form.Button");
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");
//return remove_splash(); });
if (!genericSanityCheck()) if (!genericSanityCheck())
return; return;
@ -278,7 +323,8 @@ function init_second_stage() {
feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1; feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1;
setTimeout('updateFeedList(false, false)', 50); remove_splash();
feedlist_init();
console.log("second stage ok"); console.log("second stage ok");

@ -124,7 +124,7 @@
<a id="dispSwitchPrompt" <a id="dispSwitchPrompt"
href="javascript:toggleTags()"><?php echo __("tag cloud") ?></a> href="javascript:toggleTags()"><?php echo __("tag cloud") ?></a>
</div> </div>
<div id="feeds-frame">&nbsp;</div> <div id="feeds-frame"><div id="feedTree"></div></div>
</div> </div>
<div dojoType="dijit.layout.BorderContainer" region="center" id="content-wrap"> <div dojoType="dijit.layout.BorderContainer" region="center" id="content-wrap">

Loading…
Cancel
Save