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