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