feedlist.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. var _infscroll_disable = 0;
  2. var _infscroll_request_sent = 0;
  3. var _search_query = false;
  4. var _viewfeed_last = 0;
  5. var _viewfeed_timeout = false;
  6. var counters_last_request = 0;
  7. function viewCategory(cat) {
  8. viewfeed({feed: cat, is_cat: true});
  9. return false;
  10. }
  11. function loadMoreHeadlines() {
  12. try {
  13. console.log("loadMoreHeadlines");
  14. var offset = 0;
  15. var view_mode = document.forms["main_toolbar_form"].view_mode.value;
  16. var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
  17. var num_all = $$("#headlines-frame > div[id*=RROW]").length;
  18. var num_unread = getFeedUnread(getActiveFeedId(), activeFeedIsCat());
  19. // TODO implement marked & published
  20. if (view_mode == "marked") {
  21. console.warn("loadMoreHeadlines: marked is not implemented, falling back.");
  22. offset = num_all;
  23. } else if (view_mode == "published") {
  24. console.warn("loadMoreHeadlines: published is not implemented, falling back.");
  25. offset = num_all;
  26. } else if (view_mode == "unread") {
  27. offset = unread_in_buffer;
  28. } else if (_search_query) {
  29. offset = num_all;
  30. } else if (view_mode == "adaptive" && !(getActiveFeedId() == -1 && !activeFeedIsCat())) {
  31. // ^ starred feed shows both unread & read articles in adaptive mode
  32. offset = num_unread > 0 ? unread_in_buffer : num_all;
  33. } else {
  34. offset = num_all;
  35. }
  36. console.log("offset: " + offset);
  37. viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat(), offset: offset, infscroll_req: true});
  38. } catch (e) {
  39. exception_error("viewNextFeedPage", e);
  40. }
  41. }
  42. function viewfeed(params) {
  43. try {
  44. var feed = params.feed;
  45. var is_cat = params.is_cat;
  46. var offset = params.offset;
  47. var background = params.background;
  48. var infscroll_req = params.infscroll_req;
  49. var can_wait = params.can_wait;
  50. var viewfeed_debug = params.viewfeed_debug;
  51. var method = params.method;
  52. if (is_cat == undefined)
  53. is_cat = false;
  54. else
  55. is_cat = !!is_cat;
  56. if (offset == undefined) offset = 0;
  57. if (background == undefined) background = false;
  58. if (infscroll_req == undefined) infscroll_req = false;
  59. last_requested_article = 0;
  60. if (feed != getActiveFeedId() || activeFeedIsCat() != is_cat) {
  61. if (!background && _search_query) _search_query = false;
  62. }
  63. if (!background) {
  64. _viewfeed_last = get_timestamp();
  65. if (getActiveFeedId() != feed || !infscroll_req) {
  66. setActiveArticleId(0);
  67. _infscroll_disable = 0;
  68. }
  69. if (infscroll_req) {
  70. var timestamp = get_timestamp();
  71. if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
  72. //console.log("infscroll request in progress, aborting");
  73. return;
  74. }
  75. _infscroll_request_sent = timestamp;
  76. }
  77. }
  78. Form.enable("main_toolbar_form");
  79. var toolbar_query = Form.serialize("main_toolbar_form");
  80. var query = "?op=feeds&method=view&feed=" + param_escape(feed) + "&" +
  81. toolbar_query;
  82. if (method) query += "&m=" + param_escape(method);
  83. if (offset > 0) {
  84. if (current_first_id) {
  85. query = query + "&fid=" + param_escape(current_first_id);
  86. }
  87. }
  88. if (!background) {
  89. if (_search_query) {
  90. force_nocache = true;
  91. query = query + "&" + _search_query;
  92. //_search_query = false;
  93. }
  94. if (offset != 0) {
  95. query = query + "&skip=" + offset;
  96. // to prevent duplicate feed titles when showing grouped vfeeds
  97. if (vgroup_last_feed) {
  98. query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
  99. }
  100. } else {
  101. if (!is_cat && feed == getActiveFeedId() && !params.method) {
  102. query = query + "&m=ForceUpdate";
  103. }
  104. }
  105. Form.enable("main_toolbar_form");
  106. if (!setFeedExpandoIcon(feed, is_cat,
  107. (is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
  108. notify_progress("Loading, please wait...", true);
  109. }
  110. query += "&cat=" + is_cat;
  111. console.log(query);
  112. if (can_wait && _viewfeed_timeout) {
  113. setFeedExpandoIcon(getActiveFeedId(), activeFeedIsCat(), 'images/blank_icon.gif');
  114. clearTimeout(_viewfeed_timeout);
  115. }
  116. setActiveFeedId(feed, is_cat);
  117. if (viewfeed_debug) {
  118. window.open("backend.php" + query + "&debug=1&csrf_token=" + getInitParam("csrf_token"));
  119. }
  120. timeout_ms = can_wait ? 250 : 0;
  121. _viewfeed_timeout = setTimeout(function() {
  122. new Ajax.Request("backend.php", {
  123. parameters: query,
  124. onComplete: function(transport) {
  125. setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif');
  126. headlines_callback2(transport, offset, background, infscroll_req);
  127. PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
  128. } });
  129. }, timeout_ms); // Wait 250ms
  130. } catch (e) {
  131. exception_error("viewfeed", e);
  132. }
  133. }
  134. function feedlist_init() {
  135. try {
  136. console.log("in feedlist init");
  137. loading_set_progress(50);
  138. document.onkeydown = hotkey_handler;
  139. setTimeout("hotkey_prefix_timeout()", 5*1000);
  140. if (!getActiveFeedId()) {
  141. viewfeed({feed: -3});
  142. } else {
  143. viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat()});
  144. }
  145. hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
  146. request_counters(true);
  147. timeout();
  148. } catch (e) {
  149. exception_error("feedlist/init", e);
  150. }
  151. }
  152. function request_counters(force) {
  153. try {
  154. var date = new Date();
  155. var timestamp = Math.round(date.getTime() / 1000);
  156. if (force || timestamp - counters_last_request > 5) {
  157. console.log("scheduling request of counters...");
  158. counters_last_request = timestamp;
  159. var query = "?op=rpc&method=getAllCounters&seq=" + next_seq();
  160. if (!force)
  161. query = query + "&last_article_id=" + getInitParam("last_article_id");
  162. console.log(query);
  163. new Ajax.Request("backend.php", {
  164. parameters: query,
  165. onComplete: function(transport) {
  166. try {
  167. handle_rpc_json(transport);
  168. } catch (e) {
  169. exception_error("request_counters", e);
  170. }
  171. } });
  172. } else {
  173. console.log("request_counters: rate limit reached: " + (timestamp - counters_last_request));
  174. }
  175. } catch (e) {
  176. exception_error("request_counters", e);
  177. }
  178. }
  179. function parse_counters(elems, scheduled_call) {
  180. try {
  181. for (var l = 0; l < elems.length; l++) {
  182. var id = elems[l].id;
  183. var kind = elems[l].kind;
  184. var ctr = parseInt(elems[l].counter);
  185. var error = elems[l].error;
  186. var has_img = elems[l].has_img;
  187. var updated = elems[l].updated;
  188. var auxctr = parseInt(elems[l].auxcounter);
  189. if (id == "global-unread") {
  190. global_unread = ctr;
  191. updateTitle();
  192. continue;
  193. }
  194. if (id == "subscribed-feeds") {
  195. feeds_found = ctr;
  196. continue;
  197. }
  198. if (getFeedUnread(id, (kind == "cat")) != ctr ||
  199. (kind == "cat")) {
  200. }
  201. setFeedUnread(id, (kind == "cat"), ctr);
  202. setFeedValue(id, (kind == "cat"), 'auxcounter', auxctr);
  203. if (kind != "cat") {
  204. setFeedValue(id, false, 'error', error);
  205. setFeedValue(id, false, 'updated', updated);
  206. if (id > 0) {
  207. if (has_img) {
  208. setFeedIcon(id, false,
  209. getInitParam("icons_url") + "/" + id + ".ico");
  210. } else {
  211. setFeedIcon(id, false, 'images/blank_icon.gif');
  212. }
  213. }
  214. }
  215. }
  216. hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
  217. } catch (e) {
  218. exception_error("parse_counters", e);
  219. }
  220. }
  221. function getFeedUnread(feed, is_cat) {
  222. try {
  223. var tree = dijit.byId("feedTree");
  224. if (tree && tree.model)
  225. return tree.model.getFeedUnread(feed, is_cat);
  226. } catch (e) {
  227. //
  228. }
  229. return -1;
  230. }
  231. function getFeedCategory(feed) {
  232. try {
  233. var tree = dijit.byId("feedTree");
  234. if (tree && tree.model)
  235. return tree.getFeedCategory(feed);
  236. } catch (e) {
  237. //
  238. }
  239. return false;
  240. }
  241. function hideOrShowFeeds(hide) {
  242. var tree = dijit.byId("feedTree");
  243. if (tree)
  244. return tree.hideRead(hide, getInitParam("hide_read_shows_special"));
  245. }
  246. function getFeedName(feed, is_cat) {
  247. var tree = dijit.byId("feedTree");
  248. if (tree && tree.model)
  249. return tree.model.getFeedValue(feed, is_cat, 'name');
  250. }
  251. function getFeedValue(feed, is_cat, key) {
  252. try {
  253. var tree = dijit.byId("feedTree");
  254. if (tree && tree.model)
  255. return tree.model.getFeedValue(feed, is_cat, key);
  256. } catch (e) {
  257. //
  258. }
  259. return '';
  260. }
  261. function setFeedUnread(feed, is_cat, unread) {
  262. try {
  263. var tree = dijit.byId("feedTree");
  264. if (tree && tree.model)
  265. return tree.model.setFeedUnread(feed, is_cat, unread);
  266. } catch (e) {
  267. exception_error("setFeedUnread", e);
  268. }
  269. }
  270. function setFeedValue(feed, is_cat, key, value) {
  271. try {
  272. var tree = dijit.byId("feedTree");
  273. if (tree && tree.model)
  274. return tree.model.setFeedValue(feed, is_cat, key, value);
  275. } catch (e) {
  276. //
  277. }
  278. }
  279. function selectFeed(feed, is_cat) {
  280. try {
  281. var tree = dijit.byId("feedTree");
  282. if (tree) return tree.selectFeed(feed, is_cat);
  283. } catch (e) {
  284. exception_error("selectFeed", e);
  285. }
  286. }
  287. function setFeedIcon(feed, is_cat, src) {
  288. try {
  289. var tree = dijit.byId("feedTree");
  290. if (tree) return tree.setFeedIcon(feed, is_cat, src);
  291. } catch (e) {
  292. exception_error("setFeedIcon", e);
  293. }
  294. }
  295. function setFeedExpandoIcon(feed, is_cat, src) {
  296. try {
  297. var tree = dijit.byId("feedTree");
  298. if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
  299. } catch (e) {
  300. exception_error("setFeedIcon", e);
  301. }
  302. return false;
  303. }
  304. function getNextUnreadFeed(feed, is_cat) {
  305. try {
  306. var tree = dijit.byId("feedTree");
  307. var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
  308. if (nuf)
  309. return tree.model.store.getValue(nuf, 'bare_id');
  310. } catch (e) {
  311. exception_error("getNextUnreadFeed", e);
  312. }
  313. }
  314. function catchupCurrentFeed(mode) {
  315. catchupFeed(getActiveFeedId(), activeFeedIsCat(), mode);
  316. }
  317. function catchupFeedInGroup(id) {
  318. try {
  319. var title = getFeedName(id);
  320. var str = __("Mark all articles in %s as read?").replace("%s", title);
  321. if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
  322. return viewCurrentFeed('MarkAllReadGR:' + id);
  323. }
  324. } catch (e) {
  325. exception_error("catchupFeedInGroup", e);
  326. }
  327. }
  328. function catchupFeed(feed, is_cat, mode) {
  329. try {
  330. if (is_cat == undefined) is_cat = false;
  331. var str = false;
  332. switch (mode) {
  333. case "1day":
  334. str = __("Mark all articles in %s older than 1 day as read?");
  335. break;
  336. case "1week":
  337. str = __("Mark all articles in %s older than 1 week as read?");
  338. break;
  339. case "2week":
  340. str = __("Mark all articles in %s older than 2 weeks as read?");
  341. break;
  342. default:
  343. str = __("Mark all articles in %s as read?");
  344. }
  345. var fn = getFeedName(feed, is_cat);
  346. str = str.replace("%s", fn);
  347. if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
  348. return;
  349. }
  350. var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
  351. feed + "&is_cat=" + is_cat + "&mode=" + mode;
  352. console.log(catchup_query);
  353. notify_progress("Loading, please wait...", true);
  354. new Ajax.Request("backend.php", {
  355. parameters: catchup_query,
  356. onComplete: function(transport) {
  357. handle_rpc_json(transport);
  358. var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
  359. if (show_next_feed) {
  360. var nuf = getNextUnreadFeed(feed, is_cat);
  361. if (nuf) {
  362. viewfeed({feed: nuf, is_cat: is_cat});
  363. }
  364. } else {
  365. if (feed == getActiveFeedId() && is_cat == activeFeedIsCat()) {
  366. viewCurrentFeed();
  367. }
  368. }
  369. notify("");
  370. } });
  371. } catch (e) {
  372. exception_error("catchupFeed", e);
  373. }
  374. }
  375. function decrementFeedCounter(feed, is_cat) {
  376. try {
  377. var ctr = getFeedUnread(feed, is_cat);
  378. if (ctr > 0) {
  379. setFeedUnread(feed, is_cat, ctr - 1);
  380. global_unread = global_unread - 1;
  381. updateTitle();
  382. if (!is_cat) {
  383. var cat = parseInt(getFeedCategory(feed));
  384. if (!isNaN(cat)) {
  385. ctr = getFeedUnread(cat, true);
  386. if (ctr > 0) {
  387. setFeedUnread(cat, true, ctr - 1);
  388. }
  389. }
  390. }
  391. }
  392. } catch (e) {
  393. exception_error("decrement_feed_counter", e);
  394. }
  395. }