]> git.wh0rd.org Git - tt-rss.git/blob - js/feedlist.js
allow request_counters() in bw_limit mode
[tt-rss.git] / js / feedlist.js
1 var _infscroll_disable = 0;
2 var _infscroll_request_sent = 0;
3 var _search_query = false;
4 var _viewfeed_last = 0;
5
6 var counter_timeout_id = false;
7
8 var counters_last_request = 0;
9
10 function viewCategory(cat) {
11         viewfeed(cat, '', true);
12         return false;
13 }
14
15 function loadMoreHeadlines() {
16         try {
17                 console.log("loadMoreHeadlines");
18
19                 var offset = 0;
20
21                 var view_mode = document.forms["main_toolbar_form"].view_mode.value;
22                 var num_unread = getFeedUnread(getActiveFeedId(), activeFeedIsCat());
23                 var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
24                 var num_all = $$("#headlines-frame > div[id*=RROW]").length;
25
26                 // TODO implement marked & published
27
28                 if (view_mode == "marked") {
29                         console.warn("loadMoreHeadlines: marked is not implemented, falling back.");
30                         offset = num_all;
31                 } else if (view_mode == "published") {
32                         console.warn("loadMoreHeadlines: published is not implemented, falling back.");
33                         offset = num_all;
34                 } else if (view_mode == "unread") {
35                         offset = num_unread;
36                 } else if (view_mode == "adaptive") {
37                         if (num_unread > 0)
38                                 offset = unread_in_buffer;
39                         else
40                                 offset = num_all;
41                 } else {
42                         offset = num_all;
43                 }
44
45                 viewfeed(getActiveFeedId(), '', activeFeedIsCat(), offset, false, true);
46
47         } catch (e) {
48                 exception_error("viewNextFeedPage", e);
49         }
50 }
51
52
53 function viewfeed(feed, method, is_cat, offset, background, infscroll_req) {
54         try {
55                 if (is_cat == undefined)
56                         is_cat = false;
57                 else
58                         is_cat = !!is_cat;
59
60                 if (method == undefined) method = '';
61                 if (offset == undefined) offset = 0;
62                 if (background == undefined) background = false;
63                 if (infscroll_req == undefined) infscroll_req = false;
64
65                 last_requested_article = 0;
66
67                 var cached_headlines = false;
68
69                 if (feed == getActiveFeedId()) {
70                         cache_delete("feed:" + feed + ":" + is_cat);
71                 } else {
72                         cached_headlines = cache_get("feed:" + feed + ":" + is_cat);
73
74                         // switching to a different feed, we might as well catchup stuff visible
75                         // in headlines buffer (if any)
76                         // disabled for now because this behavior is considered confusing -fox
77                         /* if (!background && isCdmMode() && getInitParam("cdm_auto_catchup") == 1 && parseInt(getActiveFeedId()) > 0) {
78
79                                 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
80                                         function(child) {
81                                                 var hf = $("headlines-frame");
82
83                                                 if (hf.scrollTop + hf.offsetHeight >=
84                                                                 child.offsetTop + child.offsetHeight) {
85
86                                                         var id = child.id.replace("RROW-", "");
87
88                                                         if (catchup_id_batch.indexOf(id) == -1)
89                                                                 catchup_id_batch.push(id);
90
91                                                 }
92
93                                                 if (catchup_id_batch.length > 0) {
94                                                         window.clearTimeout(catchup_timeout_id);
95
96                                                         if (!_infscroll_request_sent) {
97                                                                 catchup_timeout_id = window.setTimeout('catchupBatchedArticles()',
98                                                                         2000);
99                                                         }
100                                                 }
101
102                                         });
103                         } */
104                 }
105
106                 if (offset == 0 && !background)
107                         dijit.byId("content-tabs").selectChild(
108                                 dijit.byId("content-tabs").getChildren()[0]);
109
110                 if (!background) {
111                         _viewfeed_last = get_timestamp();
112
113                         if (getActiveFeedId() != feed || offset == 0) {
114                                 active_post_id = 0;
115                                 _infscroll_disable = 0;
116                         }
117
118                         if (!offset && !method && cached_headlines && !background) {
119                                 try {
120                                         render_local_headlines(feed, is_cat, JSON.parse(cached_headlines));
121                                         return;
122                                 } catch (e) {
123                                         console.warn("render_local_headlines failed: " + e);
124                                 }
125                         }
126
127                         if (offset != 0 && !method) {
128                                 var timestamp = get_timestamp();
129
130                                 if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
131                                         //console.log("infscroll request in progress, aborting");
132                                         return;
133                                 }
134
135                                 _infscroll_request_sent = timestamp;
136                         }
137
138                         hideAuxDlg();
139                 }
140
141                 Form.enable("main_toolbar_form");
142
143                 var toolbar_query = Form.serialize("main_toolbar_form");
144
145                 var query = "?op=feeds&method=view&feed=" + feed + "&" +
146                         toolbar_query + "&m=" + param_escape(method);
147
148                 if (!background) {
149                         if (_search_query) {
150                                 force_nocache = true;
151                                 query = query + "&" + _search_query;
152                                 _search_query = false;
153                         }
154
155                         if (offset != 0) {
156                                 query = query + "&skip=" + offset;
157
158                                 // to prevent duplicate feed titles when showing grouped vfeeds
159                                 if (vgroup_last_feed) {
160                                         query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
161                                 }
162                         }
163
164                         Form.enable("main_toolbar_form");
165
166                         if (!offset)
167                                 if (!is_cat) {
168                                         if (!setFeedExpandoIcon(feed, is_cat, 'images/indicator_white.gif'))
169                                                 notify_progress("Loading, please wait...", true);
170                                 } else {
171                                         notify_progress("Loading, please wait...", true);
172                                 }
173                 }
174
175                 query += "&cat=" + is_cat;
176                 query += "&include_children=" + dijit.byId("include_children").attr("checked");
177
178                 console.log(query);
179
180                 new Ajax.Request("backend.php", {
181                         parameters: query,
182                         onComplete: function(transport) {
183                                 setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif');
184                                 headlines_callback2(transport, offset, background, infscroll_req);
185                         } });
186
187         } catch (e) {
188                 exception_error("viewfeed", e);
189         }
190 }
191
192 function feedlist_init() {
193         try {
194                 console.log("in feedlist init");
195
196                 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
197                 document.onkeydown = hotkey_handler;
198                 setTimeout("hotkey_prefix_timeout()", 5*1000);
199
200                  if (!getActiveFeedId()) {
201                         setTimeout("viewfeed(-3)", 100);
202                 }
203
204                 console.log("T:" +
205                                 getInitParam("cdm_auto_catchup") + " " + getFeedUnread(-3));
206
207                 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
208
209                 setTimeout("timeout()", 5000);
210                 setTimeout("precache_headlines_idle()", 15000);
211
212         } catch (e) {
213                 exception_error("feedlist/init", e);
214         }
215 }
216
217 function request_counters_real() {
218         try {
219                 console.log("requesting counters...");
220
221                 var query = "?op=rpc&method=getAllCounters&seq=" + next_seq();
222
223                 query = query + "&omode=flc";
224
225                 new Ajax.Request("backend.php", {
226                         parameters: query,
227                         onComplete: function(transport) {
228                                 try {
229                                         handle_rpc_json(transport);
230                                 } catch (e) {
231                                         exception_error("viewfeed/getcounters", e);
232                                 }
233                         } });
234
235         } catch (e) {
236                 exception_error("request_counters_real", e);
237         }
238 }
239
240
241 function request_counters() {
242
243         try {
244
245                 //if (getInitParam("bw_limit") == "1") return;
246
247                 var date = new Date();
248                 var timestamp = Math.round(date.getTime() / 1000);
249
250                 if (timestamp - counters_last_request > 5) {
251                         console.log("scheduling request of counters...");
252
253                         window.clearTimeout(counter_timeout_id);
254                         counter_timeout_id = window.setTimeout("request_counters_real()", 1000);
255
256                         counters_last_request = timestamp;
257                 } else {
258                         console.log("request_counters: rate limit reached: " + (timestamp - counters_last_request));
259                 }
260
261         } catch (e) {
262                 exception_error("request_counters", e);
263         }
264 }
265
266 function displayNewContentPrompt(id) {
267         try {
268
269                 var msg = "<a href='#' onclick='viewCurrentFeed()'>" +
270                         __("New articles available in this feed (click to show)") + "</a>";
271
272                 msg = msg.replace("%s", getFeedName(id));
273
274                 $('auxDlg').innerHTML = msg;
275
276                 new Effect.Appear('auxDlg', {duration : 0.5});
277
278         } catch (e) {
279                 exception_error("displayNewContentPrompt", e);
280         }
281 }
282
283 function parse_counters(elems, scheduled_call) {
284         try {
285                 for (var l = 0; l < elems.length; l++) {
286
287                         var id = elems[l].id;
288                         var kind = elems[l].kind;
289                         var ctr = parseInt(elems[l].counter);
290                         var error = elems[l].error;
291                         var has_img = elems[l].has_img;
292                         var updated = elems[l].updated;
293                         var child_unread = parseInt(elems[l].child_counter);
294
295                         if (id == "global-unread") {
296                                 global_unread = ctr;
297                                 updateTitle();
298                                 continue;
299                         }
300
301                         if (id == "subscribed-feeds") {
302                                 feeds_found = ctr;
303                                 continue;
304                         }
305
306                         // TODO: enable new content notification for categories
307
308                         if (!activeFeedIsCat() && id == getActiveFeedId()
309                                         && ctr > getFeedUnread(id) && scheduled_call) {
310                                 displayNewContentPrompt(id);
311                         }
312
313                         if (getFeedUnread(id, (kind == "cat")) != ctr)
314                                 cache_delete("feed:" + id + ":" + (kind == "cat"));
315
316                         setFeedUnread(id, (kind == "cat"), ctr);
317
318                         if (kind != "cat") {
319                                 setFeedValue(id, false, 'error', error);
320                                 setFeedValue(id, false, 'updated', updated);
321
322                                 if (id > 0) {
323                                         if (has_img) {
324                                                 setFeedIcon(id, false,
325                                                         getInitParam("icons_url") + "/" + id + ".ico");
326                                         } else {
327                                                 setFeedIcon(id, false, 'images/blank_icon.gif');
328                                         }
329                                 }
330                         } else {
331                                 setCatParam(id, child_unread);
332                         }
333                 }
334
335                 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
336
337         } catch (e) {
338                 exception_error("parse_counters", e);
339         }
340 }
341
342 function getFeedUnread(feed, is_cat) {
343         try {
344                 var tree = dijit.byId("feedTree");
345
346                 if (tree && tree.model)
347                         return tree.model.getFeedUnread(feed, is_cat);
348
349         } catch (e) {
350                 //
351         }
352
353         return -1;
354 }
355
356 function getFeedCategory(feed) {
357         try {
358                 var tree = dijit.byId("feedTree");
359
360                 if (tree && tree.model)
361                         return tree.getFeedCategory(feed);
362
363         } catch (e) {
364                 //
365         }
366
367         return false;
368 }
369
370 function hideOrShowFeeds(hide) {
371         var tree = dijit.byId("feedTree");
372
373         if (tree)
374                 return tree.hideRead(hide, getInitParam("hide_read_shows_special"));
375 }
376
377 function getFeedName(feed, is_cat) {
378         var tree = dijit.byId("feedTree");
379
380         if (tree && tree.model)
381                 return tree.model.getFeedValue(feed, is_cat, 'name');
382 }
383
384 function getFeedValue(feed, is_cat, key) {
385         try {
386                 var tree = dijit.byId("feedTree");
387
388                 if (tree && tree.model)
389                         return tree.model.getFeedValue(feed, is_cat, key);
390
391         } catch (e) {
392                 //
393         }
394         return '';
395 }
396
397 function setFeedUnread(feed, is_cat, unread) {
398         try {
399                 var tree = dijit.byId("feedTree");
400
401                 if (tree && tree.model)
402                         return tree.model.setFeedUnread(feed, is_cat, unread);
403
404         } catch (e) {
405                 exception_error("setFeedUnread", e);
406         }
407 }
408
409 function setFeedValue(feed, is_cat, key, value) {
410         try {
411                 var tree = dijit.byId("feedTree");
412
413                 if (tree && tree.model)
414                         return tree.model.setFeedValue(feed, is_cat, key, value);
415
416         } catch (e) {
417                 //
418         }
419 }
420
421 function setCatParam(cat, value) {
422         try {
423                 var tree = dijit.byId("feedTree");
424
425                 if (tree && tree.model)
426                         return tree.setCatParam(cat, value);
427
428         } catch (e) {
429                 //
430         }
431 }
432
433
434 function selectFeed(feed, is_cat) {
435         try {
436                 var tree = dijit.byId("feedTree");
437
438                 if (tree) return tree.selectFeed(feed, is_cat);
439
440         } catch (e) {
441                 exception_error("selectFeed", e);
442         }
443 }
444
445 function setFeedIcon(feed, is_cat, src) {
446         try {
447                 var tree = dijit.byId("feedTree");
448
449                 if (tree) return tree.setFeedIcon(feed, is_cat, src);
450
451         } catch (e) {
452                 exception_error("setFeedIcon", e);
453         }
454 }
455
456 function setFeedExpandoIcon(feed, is_cat, src) {
457         try {
458                 var tree = dijit.byId("feedTree");
459
460                 if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
461
462         } catch (e) {
463                 exception_error("setFeedIcon", e);
464         }
465         return false;
466 }
467
468 function getNextUnreadFeed(feed, is_cat) {
469         try {
470                 var tree = dijit.byId("feedTree");
471                 var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
472
473                 if (nuf)
474                         return tree.model.store.getValue(nuf, 'bare_id');
475
476         } catch (e) {
477                 exception_error("getNextUnreadFeed", e);
478         }
479 }
480
481 function catchupCurrentFeed() {
482         return catchupFeed(getActiveFeedId(), activeFeedIsCat());
483 }
484
485 function catchupFeedInGroup(id) {
486         try {
487
488                 var title = getFeedName(id);
489
490                 var str = __("Mark all articles in %s as read?").replace("%s", title);
491
492                 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
493                         return viewCurrentFeed('MarkAllReadGR:' + id);
494                 }
495
496         } catch (e) {
497                 exception_error("catchupFeedInGroup", e);
498         }
499 }
500
501 function catchupFeed(feed, is_cat) {
502         try {
503                 if (is_cat == undefined) is_cat = false;
504
505                 var str = __("Mark all articles in %s as read?");
506                 var fn = getFeedName(feed, is_cat);
507
508                 str = str.replace("%s", fn);
509
510                 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
511                         return;
512                 }
513
514                 var max_id = 0;
515
516                 if (feed == getActiveFeedId() && is_cat == activeFeedIsCat()) {
517                         $$("#headlines-frame > div[id*=RROW]").each(
518                                 function(child) {
519                                         var id = parseInt(child.id.replace("RROW-", ""));
520
521                                         if (id > max_id) max_id = id;
522                                 }
523                         );
524                 }
525
526                 var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
527                         feed + "&is_cat=" + is_cat + "&max_id=" + max_id;
528
529                 console.log(catchup_query);
530
531                 notify_progress("Loading, please wait...", true);
532
533                 new Ajax.Request("backend.php", {
534                         parameters: catchup_query,
535                         onComplete: function(transport) {
536                                         handle_rpc_json(transport);
537
538                                         if (feed == getActiveFeedId() && is_cat == activeFeedIsCat()) {
539
540                                                 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
541                                                         function(child) {
542                                                                 child.removeClassName("Unread");
543                                                         }
544                                                 );
545                                         }
546
547                                         var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
548
549                                         if (show_next_feed) {
550                                                 var nuf = getNextUnreadFeed(feed, is_cat);
551
552                                                 if (nuf) {
553                                                         viewfeed(nuf, '', is_cat);
554                                                 }
555                                         }
556
557                                         notify("");
558                                 } });
559
560         } catch (e) {
561                 exception_error("catchupFeed", e);
562         }
563 }
564
565 function decrementFeedCounter(feed, is_cat) {
566         try {
567                 var ctr = getFeedUnread(feed, is_cat);
568
569                 if (ctr > 0) {
570                         setFeedUnread(feed, is_cat, ctr - 1);
571
572                         if (!is_cat) {
573                                 var cat = parseInt(getFeedCategory(feed));
574
575                                 if (!isNaN(cat)) {
576                                         ctr = getFeedUnread(cat, true);
577
578                                         if (ctr > 0) {
579                                                 setFeedUnread(cat, true, ctr - 1);
580                                         }
581                                 }
582                         }
583                 }
584
585                 cache_delete("feed:" + feed + ":" + is_cat);
586
587         } catch (e) {
588                 exception_error("decrement_feed_counter", e);
589         }
590 }