1 var SCHEMA_VERSION = 3;
3 var offline_mode = false;
5 var localServer = false;
8 function view_offline(id, feed_id) {
12 showArticleInHeadlines(id);
14 db.execute("UPDATE articles SET unread = 0 WHERE id = ?", [id]);
16 var rs = db.execute("SELECT * FROM articles WHERE id = ?", [id]);
18 if (rs.isValidRow()) {
20 var tmp = "<div class=\"postReply\">";
22 tmp += "<div class=\"postHeader\" onmouseover=\"enable_resize(true)\" "+
23 "onmouseout=\"enable_resize(false)\">";
25 tmp += "<div class=\"postDate\">"+rs.fieldByName("updated")+"</div>";
27 if (rs.fieldByName("link") != "") {
28 tmp += "<div clear='both'><a target=\"_blank\" "+
29 "href=\"" + rs.fieldByName("link") + "\">" +
30 rs.fieldByName("title") + "</a></div>";
32 tmp += "<div clear='both'>" + rs.fieldByName("title") + "</div>";
35 tmp += "<div style='float : right'> "+
36 "<img src='images/tag.png' class='tagsPic' alt='Tags' title='Tags'>";
37 tmp += rs.fieldByName("tags");
40 tmp += "<div clear='both'>"+
41 "<a target=\"_blank\" "+
42 "href=\"" + rs.fieldByName("comments") + "\">" +
43 __("comments") + "</a></div>";
47 tmp += "<div class=\"postContent\">"
48 tmp += rs.fieldByName("content");
54 update_local_feedlist_counters();
62 exception_error("view_offline", e);
66 function viewfeed_offline(feed_id, subop, is_cat, subop_param, skip_history, offset) {
70 if (!offset) offset = 0;
72 loading_set_progress(100);
74 clean_feed_selections();
76 setActiveFeedId(feed_id, is_cat);
79 var feedr = document.getElementById("FEEDR-" + feed_id);
80 if (feedr && !feedr.className.match("Selected")) {
81 feedr.className = feedr.className + "Selected";
84 var feedr = document.getElementById("FCAT-" + feed_id);
85 if (feedr && !feedr.className.match("Selected")) {
86 feedr.className = feedr.className + "Selected";
90 disableContainerChildren("headlinesToolbar", false);
91 Form.enable("main_toolbar_form");
93 var f = document.getElementById("headlines-frame");
95 if (reply.offset == 0) {
96 debug("resetting headlines scrollTop");
104 rs = db.execute("SELECT title FROM feeds WHERE id = ?", [feed_id]);
106 if (rs.isValidRow() || feed_id == -1 || feed_id == -4) {
108 feed_title = rs.field(0);
111 feed_title = __("Starred articles");
115 feed_title = __("All articles");
119 tmp += "<div id=\"headlinesContainer\">";
121 tmp += "<div class=\"headlinesSubToolbar\">";
122 tmp += "<div id=\"subtoolbar_ftitle\">";
126 var sel_all_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, '', true)";
127 var sel_unread_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true)";
128 var sel_none_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false)";
129 var sel_inv_link = "javascript:invertHeadlineSelection()";
131 tmp += __('Select:')+
132 " <a href=\""+sel_all_link+"\">"+__('All')+"</a>, "+
133 "<a href=\""+sel_unread_link+"\">"+__('Unread')+"</a>, "+
134 "<a href=\""+sel_inv_link+"\">"+__('Invert')+"</a>, "+
135 "<a href=\""+sel_none_link+"\">"+__('None')+"</a>";
137 tmp += " ";
141 tmp += "<div id=\"headlinesInnerContainer\" onscroll=\"headlines_scroll_handler()\">";
143 tmp += "<table class=\"headlinesList\" id=\"headlinesList\" cellspacing=\"0\">";
149 var toolbar_form = document.forms["main_toolbar_form"];
151 var limit = toolbar_form.limit[toolbar_form.limit.selectedIndex].value;
152 var view_mode = toolbar_form.view_mode[toolbar_form.view_mode.selectedIndex].value;
154 var limit_qpart = "";
155 var strategy_qpart = "";
157 var offset_qpart = "";
160 limit_qpart = "LIMIT " + limit;
163 if (view_mode == "all_articles") {
165 } else if (view_mode == "adaptive") {
166 if (get_local_feed_unread(feed_id) > 0) {
167 mode_qpart = "unread = 1";
171 } else if (view_mode == "marked") {
172 mode_qpart = "marked = 1";
173 } else if (view_mode == "unread") {
174 mode_qpart = "unread = 1";
180 strategy_qpart = "feed_id = " + feed_id;
181 } else if (feed_id == -1) {
182 strategy_qpart = "marked = 1";
183 } else if (feed_id == -4) {
184 strategy_qpart = "1";
188 offset_qpart = "OFFSET " + (offset*30);
193 var query = "SELECT * FROM articles WHERE " +
195 " AND " + mode_qpart +
196 " ORDER BY updated DESC "+
200 var rs = db.execute(query);
202 var line_num = offset*30;
204 while (rs.isValidRow()) {
206 var id = rs.fieldByName("id");
207 var feed_id = rs.fieldByName("feed_id");
211 var row_class = (line_num % 2) ? "even" : "odd";
213 if (rs.fieldByName("unread") == "1") {
214 row_class += "Unread";
217 if (rs.fieldByName("marked") == "1") {
218 marked_pic = "<img id=\"FMPIC-"+id+"\" "+
219 "src=\"images/mark_set.png\" class=\"markedPic\""+
220 "alt=\"Unstar article\" onclick='javascript:tMark("+id+")'>";
222 marked_pic = "<img id=\"FMPIC-"+id+"\" "+
223 "src=\"images/mark_unset.png\" class=\"markedPic\""+
224 "alt=\"Star article\" onclick='javascript:tMark("+id+")'>";
227 var mouseover_attrs = "onmouseover='postMouseIn($id)' "+
228 "onmouseout='postMouseOut($id)'";
230 tmp += "<tr class='"+row_class+"' id='RROW-"+id+"' "+mouseover_attrs+">";
232 tmp += "<td class='hlUpdPic'> </td>";
234 tmp += "<td class='hlSelectRow'>"+
235 "<input type=\"checkbox\" onclick=\"tSR(this)\" id=\"RCHK-"+id+"\"></td>";
237 tmp += "<td class='hlMarkedPic'>"+marked_pic+"</td>";
239 tmp += "<td onclick='view("+id+","+feed_id+")' "+
240 "class='hlContent' valign='middle'>";
242 tmp += "<a target=\"_blank\" id=\"RTITLE-$id\" href=\"" +
243 rs.fieldByName("link") + "\"" +
244 "onclick=\"return view("+id+","+feed_id+");\">"+
245 rs.fieldByName("title");
247 var content_preview = truncate_string(strip_tags(rs.fieldByName("content")),
250 tmp += "<span class=\"contentPreview\"> - "+content_preview+"</span>";
256 tmp += "<td class=\"hlUpdated\" onclick='view("+id+","+feed_id+")'>"+
257 "<nobr>"+rs.fieldByName("updated").substring(0,16)+"</nobr></td>";
269 tmp += "</div></div>";
273 var container = document.getElementById("headlines-frame");
274 container.innerHTML = tmp;
276 var ids = getSelectedArticleIds2();
278 var container = document.getElementById("headlinesList");
279 container.innerHTML = container.innerHTML + tmp;
281 for (var i = 0; i < ids.length; i++) {
282 markHeadline(ids[i]);
291 exception_error("viewfeed_offline", e);
295 function render_offline_feedlist() {
297 var tmp = "<ul class=\"feedList\" id=\"feedList\">";
299 var unread = get_local_feed_unread(-4);
301 global_unread = unread;
304 tmp += printFeedEntry(-4, __("All articles"), "feed", unread,
307 var unread = get_local_feed_unread(-1);
309 tmp += printFeedEntry(-1, __("Starred articles"), "feed", unread,
310 "images/mark_set.png");
312 tmp += "<li><hr/></li>";
314 var rs = db.execute("SELECT feeds.id,feeds.title,has_icon,COUNT(articles.id) "+
315 "FROM feeds LEFT JOIN articles ON (feed_id = feeds.id) "+
316 "WHERE unread = 1 OR unread IS NULL GROUP BY feeds.id "+
317 "ORDER BY feeds.title");
319 while (rs.isValidRow()) {
321 var id = rs.field(0);
322 var title = rs.field(1);
323 var has_icon = rs.field(2);
324 var unread = rs.field(3);
329 icon = "icons/" + id + ".ico";
335 var row_class = "feed";
338 row_class += "Unread";
339 fctr_class = "feedCtrHasUnread";
341 fctr_class = "feedCtrNoUnread";
344 tmp += printFeedEntry(id, title, "feed", unread, icon);
353 render_feedlist(tmp);
355 exception_error("render_offline_feedlist", e);
359 function init_offline() {
363 Element.hide("dispSwitchPrompt");
364 Element.hide("feedBrowserPrompt");
365 Element.hide("quickMenuChooser");
367 var tb_form = document.getElementById("main_toolbar_form");
369 Element.hide(tb_form.update);
371 var rs = db.execute("SELECT key, value FROM init_params");
373 while (rs.isValidRow()) {
374 init_params[rs.field(0)] = rs.field(1);
380 render_offline_feedlist();
384 exception_error("init_offline", e);
388 function offline_download_parse(stage, transport) {
390 if (transport.responseXML) {
394 var feeds = transport.responseXML.getElementsByTagName("feed");
396 if (feeds.length > 0) {
397 db.execute("DELETE FROM feeds");
400 for (var i = 0; i < feeds.length; i++) {
401 var id = feeds[i].getAttribute("id");
402 var has_icon = feeds[i].getAttribute("has_icon");
403 var title = feeds[i].firstChild.nodeValue;
405 db.execute("INSERT INTO feeds (id,title,has_icon)"+
407 [id, title, has_icon]);
410 window.setTimeout("update_offline_data("+(stage+1)+")", 60*1000);
413 var articles = transport.responseXML.getElementsByTagName("article");
415 var articles_found = 0;
417 for (var i = 0; i < articles.length; i++) {
418 var a = eval("("+articles[i].firstChild.nodeValue+")");
422 var date = new Date();
423 var ts = Math.round(date.getTime() / 1000);
425 db.execute("DELETE FROM articles WHERE id = ?", [a.id]);
426 db.execute("INSERT INTO articles "+
427 "(id, feed_id, title, link, guid, updated, content, "+
428 "unread, marked, tags, added, comments) "+
429 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
430 [a.id, a.feed_id, a.title, a.link, a.guid, a.updated,
431 a.content, a.unread, a.marked, a.tags, ts,
437 if (articles_found > 0) {
438 window.setTimeout("update_offline_data("+(stage+1)+")", 60*1000);
440 window.setTimeout("update_offline_data(0)", 1800*1000);
442 var date = new Date();
443 var ts = Math.round(date.getTime() / 1000);
445 db.execute("DELETE FROM articles WHERE added < ? - 2592000", [ts]);
452 exception_error("offline_download_parse", e);
456 function update_offline_data(stage) {
459 if (!stage) stage = 0;
461 debug("update_offline_data: stage " + stage);
463 // notify_progress("Loading, please wait... (" + stage +")", true);
465 var query = "backend.php?op=rpc&subop=download&stage=" + stage;
467 var rs = db.execute("SELECT MAX(id), MIN(id) FROM articles");
469 if (rs.isValidRow() && rs.field(0)) {
470 var offline_dl_max_id = rs.field(0);
471 var offline_dl_min_id = rs.field(1);
473 query = query + "&cidt=" + offline_dl_max_id;
474 query = query + "&cidb=" + offline_dl_min_id;
479 new Ajax.Request(query, {
480 onComplete: function(transport) {
481 offline_download_parse(stage, transport);
482 debug("update_offline_data: done " + stage);
486 exception_error("initiate_offline_download", e);
490 function set_feedlist_counter(id, ctr) {
493 var feedctr = document.getElementById("FEEDCTR-" + id);
494 var feedu = document.getElementById("FEEDU-" + id);
495 var feedr = document.getElementById("FEEDR-" + id);
497 if (feedctr && feedu && feedr) {
499 var row_needs_hl = (ctr > 0 && ctr > parseInt(feedu.innerHTML));
501 feedu.innerHTML = ctr;
504 feedctr.className = "feedCtrHasUnread";
505 if (!feedr.className.match("Unread")) {
506 var is_selected = feedr.className.match("Selected");
508 feedr.className = feedr.className.replace("Selected", "");
509 feedr.className = feedr.className.replace("Unread", "");
511 feedr.className = feedr.className + "Unread";
514 feedr.className = feedr.className + "Selected";
520 new Effect.Highlight(feedr, {duration: 1, startcolor: "#fff7d5",
521 queue: { position:'end', scope: 'EFQ-' + id, limit: 1 } } );
524 feedctr.className = "feedCtrNoUnread";
525 feedr.className = feedr.className.replace("Unread", "");
530 exception_error("set_feedlist_counter", e);
534 function update_local_feedlist_counters() {
538 var rs = db.execute("SELECT feeds.id,COUNT(articles.id) "+
539 "FROM feeds LEFT JOIN articles ON (feed_id = feeds.id) "+
540 "WHERE unread = 1 OR unread IS NULL GROUP BY feeds.id "+
541 "ORDER BY feeds.title");
543 while (rs.isValidRow()) {
544 var id = rs.field(0);
545 var ctr = rs.field(1);
547 set_feedlist_counter(id, ctr);
554 set_feedlist_counter(-4, get_local_feed_unread(-4));
555 set_feedlist_counter(-1, get_local_feed_unread(-1));
557 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
559 global_unread = get_local_feed_unread(-4);
563 exception_error("update_local_feedlist_counters", e);
567 function get_local_feed_unread(id) {
572 rs = db.execute("SELECT SUM(unread) FROM articles");
573 } else if (id == -1) {
574 rs = db.execute("SELECT SUM(unread) FROM articles WHERE marked = 1");
576 rs = db.execute("SELECT SUM(unread) FROM articles WHERE feed_id = ?", [id]);
581 if (rs.isValidRow()) {
592 exception_error("get_local_feed_unread", e);
596 function init_gears() {
599 if (window.google && google.gears) {
600 localServer = google.gears.factory.create("beta.localserver");
601 store = localServer.createManagedStore("tt-rss");
602 db = google.gears.factory.create('beta.database');
605 db.execute("CREATE TABLE IF NOT EXISTS version (schema_version text)");
607 var rs = db.execute("SELECT schema_version FROM version");
611 if (rs.isValidRow()) {
612 version = rs.field(0);
617 if (version != SCHEMA_VERSION) {
618 db.execute("DROP TABLE IF EXISTS init_params");
619 db.execute("DROP TABLE IF EXISTS cache");
620 db.execute("DROP TABLE IF EXISTS feeds");
621 db.execute("DROP TABLE IF EXISTS articles");
622 db.execute("DROP TABLE IF EXISTS version");
623 db.execute("CREATE TABLE IF NOT EXISTS version (schema_version text)");
624 db.execute("INSERT INTO version (schema_version) VALUES (?)",
628 db.execute("CREATE TABLE IF NOT EXISTS init_params (key text, value text)");
630 db.execute("CREATE TABLE IF NOT EXISTS cache (id text, article text, param text, added text)");
631 db.execute("CREATE TABLE IF NOT EXISTS feeds (id integer, title text, has_icon integer)");
632 db.execute("CREATE TABLE IF NOT EXISTS articles (id integer, feed_id integer, title text, link text, guid text, updated text, content text, tags text, unread text, marked text, added text, comments text)");
633 window.setTimeout("update_offline_data(0)", 100);
640 exception_error("init_gears", e);