ios version
[wl-mobile.git] / www / js / view.js
1 /*
2  * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later.
3  * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4  */
5
6 var View = new function() {
7         var self = this;
8         //self.minOffset = 1000;
9         self.categories = {
10                         autor: 'Autorzy', 
11                         rodzaj: 'Rodzaje',
12                         gatunek: 'Gatunki',
13                         epoka: 'Epoki'
14         };
15         self.category_msc = {
16                 autor: 'autorze',
17                 rodzaj: 'rodzaju',
18                 gatunek: 'gatunku',
19                 epoka: 'epoce'
20         };
21
22         self.init = function(success, error) {
23                 debug('View.init');
24
25                 self._searchbox = document.getElementById("searchbox");
26                 self._searchinput = document.getElementById("search");
27                 self._content = document.getElementById("content");
28                 self._back = document.getElementById("back-button");
29
30                 self.current = '';
31                 self.currentView = '';
32                 self.currentPar = '';
33                 self.currentTitle = '';
34
35                 self.checkNightMode();
36
37                 success && success();
38         };
39
40         this.go = function() {
41                 document.getElementById("cover").style.display = 'none';
42                 self.at_spinner = false;
43                 self.enter('');
44         };
45
46
47         this.sanitize = function(text) {
48                 return text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
49         };
50
51         this.showSearch = function() {
52                 self._searchbox.style.display = "block";
53         };
54
55         this.hideSearch = function() {
56                 self._searchbox.style.display = "none";
57         };
58
59         this.spinner = function(text) {
60                 if (!text)
61                         text = "Ładowanie";
62                 if (self.at_spinner) {
63                         document.getElementById("spinnertext").innerHTML = text;
64                 }
65                 else {
66                         self._content.innerHTML = "<div class='spinner'><img src='img/spinner.png' /><div id='spinnertext'>" + text +"</div></div>";
67                         self.at_spinner = true;
68                 }
69                 setOffset(0);
70         };
71
72         this.content = function(text, offset) {
73                 debug('content');
74                 self.at_spinner = false;
75
76                 self._content.innerHTML = '';
77                 self._content.innerHTML = text;
78                 setOffset(offset);
79         }
80
81         this.enter = function(url, offset) {
82                 debug('View.enter: ' + url);
83
84                 var view = 'Index';
85                 var arg = null;
86
87                 if (url.length) {
88                         var slash_index = url.indexOf('/');
89                         if (slash_index != -1) {
90                                 view = url.substr(0, slash_index);
91                                 arg = url.substr(slash_index + 1);
92                         }
93                         else {
94                                 view = url;
95                         }
96                 }
97                 debug('View.enter: ' + view + ' ' + arg);
98                 self.current = url;
99                 self.currentView = view;
100                 self.currentPar = arg;
101                 self['enter' + view](arg, offset);
102                 Menu.refresh();
103         }
104         
105         this.enterIndex = function(arg, offset) {
106                 debug('enterIndex');            
107                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
108                 self.showSearch();
109                 self.currentTitle = "Początek";
110                 var html = "";
111
112                 html += "<div class='buttons'>";
113                 html += Links.button('Last', '', 'Ostatnio czytane');
114                 html += Links.button('Bookmarks', '', 'Zakładki');
115
116                 for (category in self.categories)
117                         html += Links.button('Category', category, self.categories[category], 0);
118                 html += "</div>";
119                 
120                 html += "</div>" +"";
121                                 /*"<p id='logo'><img src='img/logo-wl-nq8.png' alt='Wolne Lektury' /><br/>\n" +
122                                 "szkolna biblioteka internetowa" +
123                                 "</p>";*/
124                 self.content(html, offset);
125         };
126         
127         this.enterBook = function(id, offset) {
128                 id = parseInt(id);
129                 debug('enterBook: ' + id);
130                 Menu.setInfoButton("BookInfo", "O utworze", true);
131                 self.showSearch();
132
133                 Catalogue.withBook(id, function(book) {
134                         self.currentTitle = book.authors + ', ' + book.title;
135
136                         Catalogue.withChildren(id, function(children) {
137                                 var html = "<h1><span class='subheader'>";
138                                 html += book.authors;
139                                 html += "</span>" + book.title + "</h1>\n";
140                                 if (book.html_file) {
141                                         html += "<div class='buttons'>" + Links.button('BookText', id, "Czytaj tekst") + "</div>";
142                                 }
143                                 if (children.length) {
144                                         html += "<div class='buttons'>";
145                                         for (c in children) {
146                                                 child = children[c];
147                                                 html += Links.bookLink(child);
148                                         }
149                                         html += "</div>";
150                                 }
151                                 self.content(html, offset);                             
152                         });
153                 }, function() {
154                         History.goBack();
155                 });
156         };
157         
158         this.enterBookText = function(id, offset) {
159                 self.hideSearch();
160                 self.spinner("Otwieranie utworu");
161                 debug('enterBookText: ' + id);
162                 Menu.setInfoButton("BookInfo", "O utworze", true);
163                 id = parseInt(id);
164
165                 setTimeout("History.addRead("+id+");", 0);
166                 
167                 FileRepo.withHtml(id, function(data) {
168                         self.content(data, offset);
169                 }, function(err) {
170                         alert("Błąd pobierania: nie udało się pobrać treści utworu.");
171                         History.goBack();
172                 });
173                 Catalogue.withBook(id, function(book) {
174                         self.currentTitle = book.authors + ', ' + book.title;
175                 });
176         };
177
178
179         this.enterLast = function(ignored, offset) {
180                 debug("enterLast");
181                 self.showSearch();
182                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
183                 self.currentTitle = 'Ostatnio czytane';
184                 var html = "<h1><span class='subheader'>Ostatnio czytane</h1>\n";
185
186                 var last_read = History.lastRead();
187                 var some_books = false;
188
189                 html += "<div class='buttons'>";
190                 var add_books = function() {
191                         if (last_read.length) {
192                                 var id = last_read.shift();
193                                 Catalogue.withBook(id, function(book) {
194                                         html += Links.bookLink(book);
195                                         some_books = true;
196                                         add_books();
197                                 }, function() {
198                                         add_books();
199                                 });
200                         }
201                         else {
202                                 if (!some_books) {
203                                         html += "<p>Nie przeczytano żadnych utworów.</p>";
204                                 }
205                                 html += "</div>";
206                                 self.content(html, offset);
207                         }
208                 };
209                 add_books();
210         };
211
212
213         this.enterBookmarks = function(ignored, offset) {
214                 debug("enterBookmarks");
215                 self.showSearch();
216                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
217                 self.currentTitle = 'Zakładki';
218                 var html = "<h1><span class='subheader'>Zakładki</h1>\n";
219
220                 var bookmarks = History.bookmarks();
221                 if (!bookmarks.length) {
222                         html += "<p>Nie utworzono żadnych zakładek.</p>";
223                         self.content(html, offset);
224                         return;
225                 }
226
227                 html += "<div class='buttons bookmarks'>";
228                 for (i in bookmarks) {
229                         var bm = bookmarks[i];
230
231                         var text = bm.name;
232                         text += "<div class='sub'>" + bm.title + "</div>";
233                         html += Links.deleteButton(bm.id);
234                         html += Links.button(bm.view, bm.par, text, bm.offset);
235                 }
236                 html += "</div>";
237                 self.content(html, offset);
238         };
239
240         this.onBookmarkChange = function() {
241                 // TODO: preserve offset
242                 if (self.currentView == 'Bookmarks') {
243                         self.enterBookmarks();
244                 }
245         };
246
247         this.enterTag = function(id, offset) {
248                 id = parseInt(id);
249                 debug('enterTag: ' + id);
250                 Menu.setInfoButton("TagInfo", "O...", true);
251                 self.showSearch();
252
253                 self.spinner("Otwieranie listy utworów");
254
255                 Catalogue.withTag(id, function(tag) {
256                         Menu.setInfoButton("TagInfo", "O " + self.category_msc[tag.category], true);
257                         self.currentTitle = tag.category + ': ' + tag.name;
258                         var html = "<h1><span class='subheader upper'>" + tag.category + ': </span>' + tag.name + "</h1>\n";
259                         html += "<div class='buttons'>";
260                         if (tag.books) {
261                                 Catalogue.withBooks(tag.books, function(books) {
262                                         for (var i in books) {
263                                                 var book = books[i];
264                                                 html += Links.bookLink(book);
265                                         }
266                                         html += "</div>";
267                                         self.content(html, offset);
268                                 });
269                         }
270                 }, function() {
271                         History.goBack();
272                 });
273         };
274
275
276         this.enterCategory = function(category, offset) {
277                 debug('enterCategory: ' + category);
278                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
279                 self.spinner("Otwieranie katalogu");
280                 self.showSearch();
281                 self.currentTitle = self.categories[category];
282
283                 Catalogue.withCategory(category, function(tags) {
284                         var html = "<h1>" + self.categories[category] + "</h1>\n";
285                         html += "<div class='buttons'>";
286                         for (i in tags) {
287                                 tag = tags[i];
288                                 html += Links.button('Tag', tag.id, tag.name);
289                         }
290                         html += "</div>";
291                         self.content(html, offset);
292                 });
293         };
294
295
296         this.enterSearch = function(query, offset) {
297                 debug('enterSearch: ' + query);
298                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
299                 self.currentTitle = 'Szukaj: ' + query;
300                 self.showSearch();
301
302                 var html = "<h1><span class='subheader'>Szukana fraza:</span>" + View.sanitize(query) + "</h1>\n";
303
304                 if (query.length < 2) {
305                         html += "<p>Szukana fraza musi mieć co najmniej dwa znaki</p>";
306                         self.content(html, offset);
307                         return;
308                 }
309
310                 Catalogue.withSearch(query, function(results) {
311                         if (results.length == 1) {
312                             var result = results[0];
313                             if (result.view == 'Book' && result.item.html_file) {
314                                 self.enter(Links.href('BookText', result.item.id));
315                             }
316                             else {
317                                         self.enter(Links.href(result.view, result.item.id));
318                                 }
319                                 return;
320                         }
321                         if (results.length == 0) {
322                                 html += "<p>Brak wyników wyszukiwania</p>";
323                         }
324                         else {
325                                 html += "<div class='buttons'>";
326                                 for (var i in results) {
327                                         var result = results[i];
328                                         if (result.view == 'Book')
329                                                 html += Links.bookLink(result.item)
330                                         else
331                                                 html += Links.button(result.view, result.item.id, result.item.name+"<div class='sub'>"+result.item.category+"</div>");
332                                 }
333                                 html += "</div>";
334                         }
335                         self.content(html, offset);
336                 });
337         };
338
339
340         /* info */
341
342         this.enterProjectInfo = function(arg, offset) {
343                 debug('enterProjectInfo');
344                 Menu.setInfoButton("ProjectInfo", "O projekcie", false);
345                 self.hideSearch();
346                 self.currentTitle = "O projekcie";
347
348                 var html = "";
349
350                 html += '<div class="info">';
351
352
353                 html += "<p style='text-align:center'><img src='img/logo-wl.png' /></p>";
354                 html += "<p>Biblioteka internetowa Wolne Lektury "+
355 " udostępnia w swoich zbiorach lektury szkolne zalecane do użytku przez" + 
356 " Ministerstwo Edukacji Narodowej i inne dzieła literatury.</p>";
357
358                 html += "<p style='text-align:center'><img src='img/logo-fnp.png' /></p>";
359
360                 html += "<img style='float:left;' src='img/procent.png' />" +
361                         "<p style='margin-left: 50px'>" + 
362                         "Przekaż 1% podatku na rozwój Wolnych Lektur.<br/>" +
363                         "Fundacja Nowoczesna Polska<br/>" +
364                         "KRS 0000070056</p>";
365
366                 html += "<p>Większość pozycji w bibliotece należy do domeny publicznej "+
367                         "co oznacza, że nie są już chronione majatkowym prawem autorskim, "+
368                         "a więc można je swobodnie wykorzystywać, publikować i rozpowszechniać. "+
369                         "Publikujemy również kilka utworów, które autorzy udostępnili na wolnej licencji "+
370                         "<a href='http://creativecommons.org/licenses/by-sa/3.0/deed.pl'>"+
371                         "Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL</a>.</p>";
372
373                 html += "<p style='text-align:center'><img src='img/cc-by-sa.png' /></p>";
374
375                 html += "<p>Copyright © 2011 Fundacja Nowoczesna Polska. Aplikacja jest wolnym oprogramowaniem "+
376                                 "dostępnym na licencji GNU Affero GPL w wersji 3 lub późniejszej.</p>";
377
378                 html += "<p>Więcej informacji o projekcie znajduje sie na stronie <a href='http://www.wolnelektury.pl'>http://www.wolnelektury.pl</a>.</p>";
379
380                 html += '</div>';
381
382
383                 self.content(html, offset);
384         };
385         
386         
387         this.enterBookInfo = function(id, offset) {
388                 id = parseInt(id);
389                 debug('enterBookInfo: ' + id);
390                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
391                 self.hideSearch();
392
393                 Catalogue.withBook(id, function(book) {
394                         self.currentTitle = "Informacje o: " + book.title;
395
396                         var html = '<h2>' + book.authors + ', ' + book.title + '</h2>';
397
398                         var url = WL + '/api/book/' + id + '/info.html';
399
400                         var xhr = new XMLHttpRequest();
401                         xhr.open("GET", url);
402                         xhr.onload = function() {
403                                 debug('BookInfo: fetched by ajax: ' + url);
404
405                                 html += '<div class="info">';
406                                 html += xhr.responseText;
407                                 html += '</div>';
408
409                                 self.content(html, offset);
410                         }
411                         xhr.onerror = function(e) {
412                                 self.content("Brak informacji.", offset);
413                         }
414                         xhr.send();
415                 }, function() {
416                         History.goBack();
417                 });
418         };
419
420
421         this.enterTagInfo = function(id, offset) {
422                 id = parseInt(id);
423                 debug('enterTagInfo: ' + id);
424                 Menu.setInfoButton("ProjectInfo", "O projekcie", true);
425                 self.hideSearch();
426
427                 Catalogue.withTag(id, function(tag) {
428                         self.currentTitle = "Informacje o " + tag.name;
429                         var html = '<h2>' + tag.name + '</h2>';
430
431                         var url = WL + '/api/tag/' + id + '/info.html';
432
433                         var xhr = new XMLHttpRequest();
434                         xhr.open("GET", url);
435                         xhr.onload = function() {
436                                 debug('TagInfo: fetched by ajax: ' + url);
437
438                                 html += '<div class="info">';
439                                 html += xhr.responseText;
440                                 html += '</div>';
441
442                                 self.content(html, offset);
443                         }
444                         xhr.onerror = function(e) {
445                                 self.content("Brak informacji.", offset);
446                         }
447                         xhr.send();
448                 }, function() {
449                         History.goBack();
450                 });
451         };
452
453
454         /* search form submit callback */
455         this.search = function() {
456                 History.visit('Search/' + self._searchinput.value);
457                 self._content.focus()
458                 return false;
459         }
460         
461
462         self.getNightMode = function() {
463                 night_mode = window.localStorage.getItem('View.night_mode');
464                 if (night_mode === undefined)
465                         return false;
466                 else
467                         return !!night_mode;
468         };
469
470         self.checkNightMode = function() {
471         night_mode = self.getNightMode();
472                 if (night_mode) {
473                         document.body.setAttribute("class", "night-mode");
474                 }
475                 else {
476                         document.body.setAttribute("class", "");
477                 }
478         };
479
480         self.setNightMode = function(night_mode) {
481                 night_mode = night_mode ? "1" :  "";
482         window.localStorage.setItem('View.night_mode', night_mode);
483         self.checkNightMode();
484         };
485
486         self.toggleNightMode = function(night_mode) {
487                 self.setNightMode(!self.getNightMode());
488         };
489
490         self.showBack = function(show) {
491                 if (show)
492                         self._back.style.display = 'inline-block';
493                 else
494                         self._back.style.display = 'none';
495         }
496 }