]> git.wh0rd.org - tt-rss.git/blob - tt-rss.js
code cleanups, show selected feed in feedlist, tell magpie to use UTF-8
[tt-rss.git] / tt-rss.js
1 /*
2 This program is Copyright (c) 2003-2005 Andrew Dolgov <cthulhoo@gmail.com>
3 Licensed under GPL v.2 or (at your preference) any later version.
4 */
5
6 var xmlhttp = false;
7 var xmlhttp_rpc = false;
8 var xmlhttp_view = false;
9
10 var total_unread = 0;
11 var first_run = true;
12
13 var active_post_id = false;
14 var active_feed_id = false;
15 var active_offset = false;
16
17 var total_feed_entries = false;
18
19 var _viewfeed_autoselect_first = false;
20 var _viewfeed_autoselect_last = false;
21
22 var search_query = "";
23
24 /*@cc_on @*/
25 /*@if (@_jscript_version >= 5)
26 // JScript gives us Conditional compilation, we can cope with old IE versions.
27 // and security blocked creation of the objects.
28 try {
29 xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
30 } catch (e) {
31 try {
32 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
33 xmlhttp_rpc = new ActiveXObject("Microsoft.XMLHTTP");
34 xmlhttp_view = new ActiveXObject("Microsoft.XMLHTTP");
35 } catch (E) {
36 xmlhttp = false;
37 xmlhttp_rpc = false;
38 xmlhttp_view = false;
39 }
40 }
41 @end @*/
42
43 if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
44 xmlhttp = new XMLHttpRequest();
45 xmlhttp_rpc = new XMLHttpRequest();
46 xmlhttp_view = new XMLHttpRequest();
47 }
48
49 function feedlist_callback() {
50 var container = document.getElementById('feeds');
51 if (xmlhttp.readyState == 4) {
52 container.innerHTML=xmlhttp.responseText;
53
54 if (first_run) {
55 scheduleFeedUpdate(false);
56 first_run = false;
57 } else {
58 notify("");
59 }
60 }
61 }
62
63 function viewfeed_callback() {
64 var container = document.getElementById('headlines');
65 if (xmlhttp.readyState == 4) {
66 container.innerHTML = xmlhttp.responseText;
67
68 var factive = document.getElementById("FACTIVE");
69 var funread = document.getElementById("FUNREAD");
70 var ftotal = document.getElementById("FTOTAL");
71
72 if (_viewfeed_autoselect_first == true) {
73 _viewfeed_autoselect_first = false;
74 view(getFirstVisibleHeadlineId(), active_feed_id);
75 }
76
77 if (_viewfeed_autoselect_last == true) {
78 _viewfeed_autoselect_last = false;
79 view(getLastVisibleHeadlineId(), active_feed_id);
80 }
81
82 if (ftotal && factive && funread) {
83 var feed_id = factive.innerHTML;
84
85 var feedr = document.getElementById("FEEDR-" + feed_id);
86 var feedt = document.getElementById("FEEDT-" + feed_id);
87 var feedu = document.getElementById("FEEDU-" + feed_id);
88
89 feedt.innerHTML = ftotal.innerHTML;
90 feedu.innerHTML = funread.innerHTML;
91
92 total_feed_entries = ftotal.innerHTML;
93
94 if (feedu.innerHTML > 0 && !feedr.className.match("Unread")) {
95 feedr.className = feedr.className + "Unread";
96 } else if (feedu.innerHTML <= 0) {
97 feedr.className = feedr.className.replace("Unread", "");
98 }
99
100 cleanSelected("feedsList");
101
102 feedr.className = feedr.className + "Selected";
103 }
104
105 var searchbox = document.getElementById("searchbox");
106 searchbox.value = search_query;
107
108 notify("");
109
110 }
111 }
112
113 function view_callback() {
114 var container = document.getElementById('content');
115 if (xmlhttp_view.readyState == 4) {
116 container.innerHTML=xmlhttp_view.responseText;
117 }
118 }
119
120 function refetch_callback() {
121
122 if (xmlhttp_rpc.readyState == 4) {
123 notify("All feeds updated");
124 var container = document.getElementById('feeds');
125 container.innerHTML = xmlhttp_rpc.responseText;
126 document.title = "Tiny Tiny RSS";
127 }
128 }
129
130 function scheduleFeedUpdate(force) {
131
132 notify("Updating feeds in background...");
133
134 document.title = "Tiny Tiny RSS - Updating...";
135
136 var query_str = "backend.php?op=rpc&subop=";
137
138 if (force) {
139 query_str = query_str + "forceUpdateAllFeeds";
140 } else {
141 query_str = query_str + "updateAllFeeds";
142 }
143
144 if (xmlhttp_ready(xmlhttp_rpc)) {
145 xmlhttp_rpc.open("GET", query_str, true);
146 xmlhttp_rpc.onreadystatechange=refetch_callback;
147 xmlhttp_rpc.send(null);
148 } else {
149 printLockingError();
150 }
151 }
152
153 function updateFeedList(silent, fetch) {
154
155 if (silent != true) {
156 notify("Loading feed list...");
157 }
158
159 var query_str = "backend.php?op=feeds";
160
161 if (fetch) query_str = query_str + "&fetch=yes";
162
163 if (xmlhttp_ready(xmlhttp)) {
164 xmlhttp.open("GET", query_str, true);
165 xmlhttp.onreadystatechange=feedlist_callback;
166 xmlhttp.send(null);
167 } else {
168 printLockingError();
169 }
170 }
171
172 function catchupPage(feed) {
173
174 if (!xmlhttp_ready(xmlhttp)) {
175 printLockingError();
176 return
177 }
178
179 var content = document.getElementById("headlinesList");
180
181 var rows = new Array();
182
183 for (i = 0; i < content.rows.length; i++) {
184 var row_id = content.rows[i].id.replace("RROW-", "");
185 if (row_id.length > 0) {
186 if (content.rows[i].className.match("Unread")) {
187 rows.push(row_id);
188 content.rows[i].className = content.rows[i].className.replace("Unread", "");
189 }
190 }
191 }
192
193 if (rows.length > 0) {
194
195 var feedr = document.getElementById("FEEDR-" + feed);
196 var feedu = document.getElementById("FEEDU-" + feed);
197
198 feedu.innerHTML = feedu.innerHTML - rows.length;
199
200 if (feedu.innerHTML > 0 && !feedr.className.match("Unread")) {
201 feedr.className = feedr.className + "Unread";
202 } else if (feedu.innerHTML <= 0) {
203 feedr.className = feedr.className.replace("Unread", "");
204 }
205
206 var query_str = "backend.php?op=rpc&subop=catchupPage&ids=" +
207 param_escape(rows.toString());
208
209 notify("Marking this page as read...");
210
211 xmlhttp.open("GET", query_str, true);
212 xmlhttp.onreadystatechange=notify_callback;
213 xmlhttp.send(null);
214
215 } else {
216 notify("No unread items on this page.");
217
218 }
219 }
220
221 function catchupAllFeeds() {
222
223 if (!xmlhttp_ready(xmlhttp)) {
224 printLockingError();
225 return
226 }
227 var query_str = "backend.php?op=feeds&subop=catchupAll";
228
229 notify("Marking all feeds as read...");
230
231 xmlhttp.open("GET", query_str, true);
232 xmlhttp.onreadystatechange=feedlist_callback;
233 xmlhttp.send(null);
234
235 }
236
237 function viewfeed(feed, skip, subop) {
238
239 enableHotkeys();
240
241 var searchbox = document.getElementById("searchbox");
242
243 if (searchbox) {
244 search_query = searchbox.value;
245 } else {
246 search_query = "";
247 }
248
249 /* if (active_feed_id == feed && subop != "ForceUpdate") {
250 notify("This feed is currently selected.");
251 return;
252 } */
253
254 if (skip < 0 || skip > total_feed_entries) {
255 return;
256 }
257
258 if (!xmlhttp_ready(xmlhttp)) {
259 printLockingError();
260 return
261 }
262
263 active_feed_id = feed;
264 active_post_id = false;
265 active_offset = skip;
266
267 var query = "backend.php?op=viewfeed&feed=" + param_escape(feed) +
268 "&skip=" + param_escape(skip) + "&subop=" + param_escape(subop);
269
270 if (search_query != "") {
271 query = query + "&search=" + param_escape(search_query);
272 }
273
274 xmlhttp.open("GET", query, true);
275 xmlhttp.onreadystatechange=viewfeed_callback;
276 xmlhttp.send(null);
277
278 notify("Loading headlines...");
279
280 }
281
282 function cleanSelected(element) {
283 var content = document.getElementById(element);
284
285 var rows = new Array();
286
287 for (i = 0; i < content.rows.length; i++) {
288 content.rows[i].className = content.rows[i].className.replace("Selected", "");
289 }
290
291 }
292
293 function view(id,feed_id) {
294
295 enableHotkeys();
296
297 if (!xmlhttp_ready(xmlhttp_view)) {
298 printLockingError();
299 return
300 }
301
302 var crow = document.getElementById("RROW-" + id);
303
304 if (crow.className.match("Unread")) {
305 var umark = document.getElementById("FEEDU-" + feed_id);
306 umark.innerHTML = umark.innerHTML - 1;
307 crow.className = crow.className.replace("Unread", "");
308
309 if (umark.innerHTML == "0") {
310 var feedr = document.getElementById("FEEDR-" + feed_id);
311 feedr.className = feedr.className.replace("Unread", "");
312 }
313
314 total_unread--;
315 }
316
317 cleanSelected("headlinesList");
318
319 crow.className = crow.className + "Selected";
320
321 var upd_img_pic = document.getElementById("FUPDPIC-" + id);
322
323 if (upd_img_pic) {
324 upd_img_pic.innerHTML = "";
325 }
326
327 document.getElementById('content').innerHTML='Loading, please wait...';
328
329 active_post_id = id;
330
331 xmlhttp_view.open("GET", "backend.php?op=view&id=" + param_escape(id), true);
332 xmlhttp_view.onreadystatechange=view_callback;
333 xmlhttp_view.send(null);
334
335
336 }
337
338 function timeout() {
339 scheduleFeedUpdate(true);
340 setTimeout("timeout()", 1800*1000);
341 }
342
343 function resetSearch() {
344 document.getElementById("searchbox").value = "";
345 viewfeed(active_feed_id, 0, "");
346 }
347
348 function search(feed) {
349 viewfeed(feed, 0, "");
350 }
351
352 function localPiggieFunction(enable) {
353 if (enable) {
354 var query_str = "backend.php?op=feeds&subop=piggie";
355
356 if (xmlhttp_ready(xmlhttp)) {
357
358 xmlhttp.open("GET", query_str, true);
359 xmlhttp.onreadystatechange=feedlist_callback;
360 xmlhttp.send(null);
361 }
362 }
363 }
364
365 function relativeid_callback() {
366
367 if (xmlhttp_rpc.readyState == 4) {
368 notify(xmlhttp_rpc.responseText);
369 }
370
371 }
372
373 function getVisibleHeadlineIds() {
374
375 var content = document.getElementById("headlinesList");
376
377 var rows = new Array();
378
379 for (i = 0; i < content.rows.length; i++) {
380 var row_id = content.rows[i].id.replace("RROW-", "");
381 if (row_id.length > 0) {
382 rows.push(row_id);
383 }
384 }
385 return rows;
386 }
387
388 function getFirstVisibleHeadlineId() {
389 var rows = getVisibleHeadlineIds();
390 return rows[0];
391 }
392
393 function getLastVisibleHeadlineId() {
394 var rows = getVisibleHeadlineIds();
395 return rows[rows.length-1];
396 }
397
398 function moveToPost(mode) {
399
400 var rows = getVisibleHeadlineIds();
401
402 var prev_id;
403 var next_id;
404
405 if (active_post_id == false) {
406 next_id = getFirstVisibleHeadlineId();
407 prev_id = getLastVisibleHeadlineId();
408 } else {
409 for (var i = 0; i < rows.length; i++) {
410 if (rows[i] == active_post_id) {
411 prev_id = rows[i-1];
412 next_id = rows[i+1];
413 }
414 }
415 }
416
417 var content = document.getElementById("headlinesList");
418
419 if (mode == "next") {
420 if (next_id != undefined) {
421 view(next_id, active_feed_id);
422 } else {
423 _viewfeed_autoselect_first = true;
424 viewfeed(active_feed_id, active_offset+15);
425 }
426 }
427
428 if (mode == "prev") {
429 if ( prev_id != undefined) {
430 view(prev_id, active_feed_id);
431 } else {
432 _viewfeed_autoselect_last = true;
433 viewfeed(active_feed_id, active_offset-15);
434 }
435 }
436
437 }
438
439 function localHotkeyHandler(keycode) {
440
441 if (keycode == 78) {
442 return moveToPost('next');
443 }
444
445 if (keycode == 80) {
446 return moveToPost('prev');
447 }
448
449 if (keycode == 82) {
450 return scheduleFeedUpdate(true);
451 }
452
453 if (keycode == 85) {
454 return viewfeed(active_feed_id, active_offset, "ForceUpdate");
455 }
456
457 // notify("KC: " + keycode);
458
459 }
460
461
462 function init() {
463
464 // IE kludge
465
466 if (xmlhttp && !xmlhttp_rpc) {
467 xmlhttp_rpc = xmlhttp;
468 xmlhttp_view = xmlhttp;
469 }
470
471 if (!xmlhttp || !xmlhttp_rpc || !xmlhttp_view) {
472 document.getElementById("headlines").innerHTML =
473 "<b>Fatal error:</b> This program needs XmlHttpRequest " +
474 "to function properly. Your browser doesn't seem to support it.";
475 return;
476 }
477
478 updateFeedList(false, false);
479 document.onkeydown = hotkey_handler;
480 setTimeout("timeout()", 1800*1000);
481 }