]> git.wh0rd.org - tt-rss.git/blame - FeedTree.js
improve headline caching, update cache after toggleMark/togglePub()
[tt-rss.git] / FeedTree.js
CommitLineData
05f224a3
AD
1dojo.provide("fox.FeedTree");
2dojo.provide("fox.FeedStoreModel");
3
4dojo.require("dijit.Tree");
997429c2 5dojo.require("dijit.Menu");
05f224a3
AD
6
7dojo.declare("fox.FeedStoreModel", dijit.tree.ForestStoreModel, {
1beea800
AD
8 getItemsInCategory: function (id) {
9 if (!this.store._itemsByIdentity) return undefined;
10
11 cat = this.store._itemsByIdentity['CAT:' + id];
12
13 if (cat && cat.items)
14 return cat.items;
15 else
16 return undefined;
17
18 },
05f224a3
AD
19 getItemById: function(id) {
20 return this.store._itemsByIdentity[id];
21 },
22 getFeedValue: function(feed, is_cat, key) {
b8aa9ca7
AD
23 if (!this.store._itemsByIdentity) return undefined;
24
05f224a3
AD
25 if (is_cat)
26 treeItem = this.store._itemsByIdentity['CAT:' + feed];
27 else
28 treeItem = this.store._itemsByIdentity['FEED:' + feed];
29
30 if (treeItem)
31 return this.store.getValue(treeItem, key);
32 },
33 getFeedName: function(feed, is_cat) {
34 return this.getFeedValue(feed, is_cat, 'name');
35 },
36 getFeedUnread: function(feed, is_cat) {
37 var unread = parseInt(this.getFeedValue(feed, is_cat, 'unread'));
38 return (isNaN(unread)) ? 0 : unread;
39 },
40 setFeedUnread: function(feed, is_cat, unread) {
41 return this.setFeedValue(feed, is_cat, 'unread', parseInt(unread));
42 },
43 setFeedValue: function(feed, is_cat, key, value) {
44 if (!value) value = '';
b8aa9ca7 45 if (!this.store._itemsByIdentity) return undefined;
05f224a3
AD
46
47 if (is_cat)
48 treeItem = this.store._itemsByIdentity['CAT:' + feed];
49 else
50 treeItem = this.store._itemsByIdentity['FEED:' + feed];
51
52 if (treeItem)
53 return this.store.setValue(treeItem, key, value);
54 },
692de159
AD
55 getNextUnreadFeed: function (feed, is_cat) {
56 if (is_cat) {
57 treeItem = this.store._itemsByIdentity['CAT:' + feed];
58 items = this.store._arrayOfTopLevelItems;
59 } else {
60 treeItem = this.store._itemsByIdentity['FEED:' + feed];
61 items = this.store._arrayOfAllItems;
62 }
63
64 for (var i = 0; i < items.length; i++) {
65 if (items[i] == treeItem) {
66
67 for (j = i+1; j < items.length; j++) {
68 var unread = this.store.getValue(items[j], 'unread');
69 var id = this.store.getValue(items[j], 'id');
70
71 if (unread > 0 && (is_cat || id.match("FEED:"))) return items[j];
72 }
73
74 for (j = 0; j < i; j++) {
75 var unread = this.store.getValue(items[j], 'unread');
76 var id = this.store.getValue(items[j], 'id');
77
78 if (unread > 0 && (is_cat || id.match("FEED:"))) return items[j];
79 }
80 }
81 }
82
83 return null;
84 },
85 hasCats: function() {
86 if (this.store && this.store._itemsByIdentity)
87 return this.store._itemsByIdentity['CAT:-1'] != undefined;
88 else
89 return false;
90 },
05f224a3
AD
91});
92
93dojo.declare("fox.FeedTree", dijit.Tree, {
94 _createTreeNode: function(args) {
95 var tnode = new dijit._TreeNode(args);
997429c2 96
05f224a3
AD
97 if (args.item.icon)
98 tnode.iconNode.src = args.item.icon[0];
99
997429c2
AD
100 var id = args.item.id[0];
101 var bare_id = parseInt(id.substr(id.indexOf(':')+1));
102
9fe80bcd
AD
103 if (bare_id < -10) {
104 var span = dojo.doc.createElement('span');
105 var fg_color = args.item.fg_color[0];
106 var bg_color = args.item.bg_color[0];
107
108 span.innerHTML = "&alpha;";
109 span.className = 'labelColorIndicator';
110 span.setStyle({
111 color: fg_color,
112 backgroundColor: bg_color});
113
114 dojo.place(span, tnode.iconNode, 'replace');
115 }
116
997429c2
AD
117 if (id.match("FEED:") && bare_id > 0) {
118 var menu = new dijit.Menu();
119 menu.row_id = bare_id;
120
121 menu.addChild(new dijit.MenuItem({
122 label: __("Edit feed"),
123 onClick: function() {
f9c388f5 124 editFeed(this.getParent().row_id);
997429c2
AD
125 }}));
126
127 menu.addChild(new dijit.MenuItem({
128 label: __("Update feed"),
129 onClick: function() {
130 scheduleFeedUpdate(this.getParent().row_id, false);
131 }}));
132
133 menu.bindDomNode(tnode.domNode);
134 tnode._menu = menu;
135 }
136
947daa10 137 //tnode.labelNode.innerHTML = args.label;
05f224a3
AD
138 return tnode;
139 },
140 getIconClass: function (item, opened) {
141 return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feedIcon";
142 },
143 getLabelClass: function (item, opened) {
144 return (item.unread == 0) ? "dijitTreeLabel" : "dijitTreeLabel Unread";
145 },
146 getRowClass: function (item, opened) {
147 return (!item.error || item.error == '') ? "dijitTreeRow" :
148 "dijitTreeRow Error";
149 },
150 getLabel: function(item) {
cb2c7faa
AD
151 var name = String(item.name);
152
153 /* Horrible */
906fc5b7
AD
154 name = name.replace(/&quot;/g, "\"");
155 name = name.replace(/&amp;/g, "&");
156 name = name.replace(/&mdash;/g, "-");
157 name = name.replace(/&lt;/g, "<");
158 name = name.replace(/&gt;/g, ">");
cb2c7faa 159
05f224a3 160 if (item.unread > 0) {
cb2c7faa 161 return name + " (" + item.unread + ")";
05f224a3 162 } else {
cb2c7faa 163 return name;
05f224a3
AD
164 }
165 },
166 selectFeed: function(feed, is_cat) {
167 if (is_cat)
168 treeNode = this._itemNodesMap['CAT:' + feed];
169 else
170 treeNode = this._itemNodesMap['FEED:' + feed];
171
172 if (treeNode) {
173 treeNode = treeNode[0];
174 if (!is_cat) this._expandNode(treeNode);
175 this._selectNode(treeNode);
176 }
177 },
178 setFeedIcon: function(feed, is_cat, src) {
179 if (is_cat)
180 treeNode = this._itemNodesMap['CAT:' + feed];
181 else
182 treeNode = this._itemNodesMap['FEED:' + feed];
183
184 if (treeNode) {
185 treeNode = treeNode[0];
186 treeNode.iconNode.src = src;
187 return true;
188 }
189 return false;
190 },
191 setFeedExpandoIcon: function(feed, is_cat, src) {
192 if (is_cat)
193 treeNode = this._itemNodesMap['CAT:' + feed];
194 else
195 treeNode = this._itemNodesMap['FEED:' + feed];
196
197 if (treeNode) {
198 treeNode = treeNode[0];
199 treeNode.expandoNode.src = src;
200 return true;
201 }
202
203 return false;
204 },
205 hasCats: function() {
692de159 206 return this.model.hasCats();
05f224a3
AD
207 },
208 hideRead: function (hide, show_special) {
209 if (this.hasCats()) {
210
211 var tree = this;
212 var cats = this.model.store._arrayOfTopLevelItems;
213
214 cats.each(function(cat) {
215 var cat_unread = tree.hideReadFeeds(cat.items, hide, show_special);
216
217 var id = String(cat.id);
218 var node = tree._itemNodesMap[id];
219 var bare_id = parseInt(id.substr(id.indexOf(":")+1));
220
221 if (node) {
222 var check_unread = tree.model.getFeedUnread(bare_id, true);
223
224 if (hide && cat_unread == 0 && check_unread == 0) {
225 Effect.Fade(node[0].rowNode, {duration : 0.3,
226 queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
227 } else {
228 Element.show(node[0].rowNode);
229 ++cat_unread;
230 }
231 }
232 });
05f224a3
AD
233
234 } else {
235 this.hideReadFeeds(this.model.store._arrayOfTopLevelItems, hide,
236 show_special);
237 }
238 },
239 hideReadFeeds: function (items, hide, show_special) {
240 var tree = this;
241 var cat_unread = 0;
242
243 items.each(function(feed) {
244 var id = String(feed.id);
245 var bare_id = parseInt(feed.bare_id);;
246
247 var unread = feed.unread[0];
248 var node = tree._itemNodesMap[id];
249
250 if (node) {
251 if (hide && unread == 0 && (bare_id > 0 || !show_special)) {
252 Effect.Fade(node[0].rowNode, {duration : 0.3,
253 queue: { position: 'end', scope: 'FFADE-' + id, limit: 1 }});
254 } else {
255 Element.show(node[0].rowNode);
256 ++cat_unread;
257 }
258 }
259 });
260
261 return cat_unread;
262 },
7613280a
AD
263 collapseCat: function(id) {
264 if (!this.model.hasCats()) return;
265
266 var tree = this;
267
268 var node = tree._itemNodesMap['CAT:' + id][0];
269 var item = tree.model.store._itemsByIdentity['CAT:' + id];
270
271 if (node && item) {
272 var hidden = tree.model.store.getValue(item, 'hidden');
273
274 if (hidden)
275 tree._expandNode(node);
276 else
277 tree._collapseNode(node);
278
279 tree.model.store.setValue(item, 'hidden', !hidden);
280 }
281 },
1a709d21
AD
282 collapseHiddenCats: function() {
283 if (!this.model.hasCats()) return;
284
285 var cats = this.model.store._arrayOfTopLevelItems;
286 var tree = this;
287
288 dojo.forEach(cats, function(cat) {
289 var hidden = tree.model.store.getValue(cat, 'hidden');
290 var id = tree.model.store.getValue(cat, 'id');
291 var node = tree._itemNodesMap[id][0];
292
293 if (hidden)
294 tree._collapseNode(node);
295 else
296 tree._expandNode(node);
297
298 });
299 },
d026d372
AD
300 getNextFeed: function (feed, is_cat) {
301 if (is_cat) {
302 treeItem = this.model.store._itemsByIdentity['CAT:' + feed];
303 } else {
304 treeItem = this.model.store._itemsByIdentity['FEED:' + feed];
305 }
306
307 items = this.model.store._arrayOfAllItems;
308 var item = items[0];
309
310 for (var i = 0; i < items.length; i++) {
311 if (items[i] == treeItem) {
312
313 for (j = i+1; j < items.length; j++) {
314 var id = String(items[j].id);
315 var box = this._itemNodesMap[id];
316
317 if (box) {
c2b2869c
AD
318 var row = box[0].rowNode;
319 var cat = box[0].rowNode.parentNode.parentNode;
d026d372 320
c2b2869c 321 if (Element.visible(cat) && Element.visible(row)) {
d026d372
AD
322 item = items[j];
323 break;
324 }
325 }
326 }
327 break;
328 }
329 }
330
331 if (item) {
332 return [this.model.store.getValue(item, 'bare_id'),
333 !this.model.store.getValue(item, 'id').match('FEED:')];
334 } else {
335 return false;
336 }
337 },
338 getPreviousFeed: function (feed, is_cat) {
339 if (is_cat) {
340 treeItem = this.model.store._itemsByIdentity['CAT:' + feed];
341 } else {
342 treeItem = this.model.store._itemsByIdentity['FEED:' + feed];
343 }
344
345 items = this.model.store._arrayOfAllItems;
346 var item = items[0];
347
348 for (var i = 0; i < items.length; i++) {
349 if (items[i] == treeItem) {
350
351 for (j = i-1; j > 0; j--) {
352 var id = String(items[j].id);
353 var box = this._itemNodesMap[id];
354
355 if (box) {
c2b2869c
AD
356 var row = box[0].rowNode;
357 var cat = box[0].rowNode.parentNode.parentNode;
d026d372 358
c2b2869c 359 if (Element.visible(cat) && Element.visible(row)) {
d026d372
AD
360 item = items[j];
361 break;
362 }
363 }
c2b2869c 364
d026d372
AD
365 }
366 break;
367 }
368 }
369
370 if (item) {
371 return [this.model.store.getValue(item, 'bare_id'),
372 !this.model.store.getValue(item, 'id').match('FEED:')];
373 } else {
374 return false;
375 }
376
377 },
378
05f224a3 379});