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