MP3 in OPDS
[wolnelektury.git] / src / wolnelektury / static / js / main.js
1 // JS Menu
2 (function () {
3   let button = $('.js-menu');
4   let menu = $('.l-navigation');
5   let menuLinks = menu.find('a');
6
7   button.on('click', function() {
8     if(!$(this).hasClass('is-active')) {
9       $(this).addClass('is-active');
10       menu.addClass('is-open');
11       $('body').addClass('is-open');
12       button.find('.bar').addClass('animate');
13       menuLinks.attr('tabindex', 0);
14     } else {
15       $(this).removeClass('is-active');
16       menu.removeClass('is-open');
17       $('body').removeClass('is-open');
18       button.find('.bar').removeClass('animate');
19       menuLinks.attr('tabindex', -1);
20     }
21   });
22
23   $(document).keyup(function(e) {
24     if (e.keyCode === 27) {
25       button.removeClass('is-active');
26       menu.removeClass('is-open');
27       $('body').removeClass('is-open');
28       button.find('.bar').removeClass('animate');
29       menuLinks.attr('tabindex', -1);
30     }
31   });
32 })();
33
34 // User menu.
35 (function() {
36     let button = $('.l-navigation__actions .user');
37     let menu = $('#user-menu');
38     let menuLinks = menu.find('a');
39
40     button.on('click', function() {
41         if (!menu.hasClass('is-open')) {
42             menu.addClass('is-open');
43             menuLinks.attr('tabindex', 0);
44         } else {
45             menu.removeClass('is-open');
46             menuLinks.attr('tabindex', -1)
47         }
48         return false;
49     });
50
51     $(document).keyup(function(e) {
52         if (e.keyCode === 27) {
53             menu.removeClass('is-open');
54             menuLinks.attr('tabindex', -1);
55         }
56     });
57
58     $(document).click(function() {
59       menu.removeClass('is-open');
60       menuLinks.attr('tabindex', -1);
61     });
62
63 })();
64
65 // Ebook/Audiobook Btns
66 (function() {
67   let button = $('.c-media__btn button:not(.l-button--media--full)');
68   let popupLayer = $('.c-media__popup');
69   let closeButton = $('.c-media__popup__close');
70   let playButton = $('.c-player__btn--md');
71   let chaptersButton = $('.c-player__chapters span');
72   let select = $('.c-select');
73   let selectItem = $('.c-select li');
74   let volumeButton = $('.icon-volume');
75
76   button.on('click', function () {
77     let target = $(this).attr('id');
78     $('[data-popup=' + target).addClass('is-open');
79     $('body').addClass('popup-open');
80   });
81
82   closeButton.on('click', function() {
83     $(this).closest('.c-media__popup').removeClass('is-open');
84     $('body').removeClass('popup-open');
85   });
86
87   popupLayer.on('click', function(e) {
88     let _this = $(this);
89     if($(e.target).is(popupLayer)) {
90       _this.removeClass('is-open');
91       $('body').removeClass('popup-open');
92     }
93   });
94
95   chaptersButton.on('click', function() {
96     $(this).parent().toggleClass('is-active');
97   });
98
99   select.on('click', function() {
100     $(this).toggleClass('is-active');
101   });
102
103   selectItem.on('click', function() {
104     selectItem.removeClass('is-active');
105     $(this).addClass('is-active');
106   });
107
108   $(document).keyup(function(e) {
109     if (e.keyCode === 27) {
110       $('.c-media__popup').removeClass('is-open');
111     }
112   });
113 })();
114
115 // Homepage books sliders
116 (function () {
117   let shelfSlider = $('.l-your-books__shelf .l-books');
118   let shelfNextSlide = $('.l-your-books__shelf .js-next-slide');
119   let shelfPrevSlide = $('.l-your-books__shelf .js-prev-slide');
120   let shelfCollapse = $('.l-your-books__shelf .js-collapse');
121
122   shelfSlider.slick({
123     slidesToScroll: 1,
124     slidesToShow: 4,
125     infinite: false,
126     dots: false,
127     arrows: false,
128     autoplay: false,
129     responsive: [
130       {
131         breakpoint: 768,
132         settings: {
133           centerMode: false,
134           slidesToShow: 1
135         }
136       }
137     ]
138   });
139
140   shelfNextSlide.on('click', function (event) {
141     event.preventDefault();
142     shelfSlider.slick('slickNext');
143   });
144
145   shelfPrevSlide.on('click', function (event) {
146     event.preventDefault();
147     shelfSlider.slick('slickPrev');
148   });
149
150   shelfCollapse.on('click', function (event) {
151     event.preventDefault();
152     shelfSlider.slick('slickPrev');
153   });
154
155
156     $('.js-collections').each(function() {
157         //return;
158         let collectionsSlider = $('.l-books', this);
159         if (collectionsSlider.children().length < 2) return;
160
161         // remove flexbox
162         collectionsSlider.css('display', 'block');
163         
164         let collectionsNextSlide = $('.js-next-slide', this);
165         let collectionsPrevSlide = $('.js-prev-slide', this);
166
167   collectionsSlider.slick({
168       //prevArrow, nextArrow,
169
170       slidesToScroll: 1,
171       slidesToShow: 1,
172       infinite: false,
173       dots: false,
174       arrows: false,
175       autoplay: false,
176
177       swipeToSlide: true,
178       centerMode: false,
179       mobileFirst: true,
180       responsive: [
181           {
182               breakpoint: 360 - .01,
183               settings: {
184                   slidesToShow: 2,
185               }
186           },
187           {
188               breakpoint: 520 - .01,
189               settings: {
190                   slidesToShow: 3
191               }
192           },
193           {
194               breakpoint: 680 - .01,
195               settings: {
196                   slidesToShow: 4
197               }
198           },
199           {
200               breakpoint: 840 - .01,
201               settings: {
202                   slidesToShow: 5
203               }
204           },
205           {
206               breakpoint: 1172 - .01,
207               settings: {
208                   slidesToShow: 5,
209                   variableWidth: true,
210               }
211           },
212       ]
213   });
214
215   collectionsNextSlide.on('click', function (event) {
216     event.preventDefault();
217     collectionsSlider.slick('slickNext');
218   });
219
220   collectionsPrevSlide.on('click', function (event) {
221     event.preventDefault();
222     collectionsSlider.slick('slickPrev');
223   });
224     });
225   let newBooksSlider = $('.js-new-books-slider .l-books');
226   let newBooksNextSlide = $('.js-new-books-slider .js-next-slide');
227   let newBooksPrevSlide = $('.js-new-books-slider .js-prev-slide');
228
229   newBooksSlider.slick({
230     slidesToScroll: 1,
231     slidesToShow: 5,
232     infinite: false,
233     dots: false,
234     arrows: false,
235     autoplay: false,
236     responsive: [
237       {
238         breakpoint: 768,
239         settings: {
240           centerMode: false,
241           slidesToShow: 2
242         }
243       }
244     ]
245   });
246
247   newBooksNextSlide.on('click', function (event) {
248     event.preventDefault();
249     newBooksSlider.slick('slickNext');
250   });
251
252   newBooksPrevSlide.on('click', function (event) {
253     event.preventDefault();
254     newBooksSlider.slick('slickPrev');
255   });
256 })();
257
258 // Quotes slider
259 (function () {
260   let slider = $('.l-author__quotes__slider');
261
262   slider.slick({
263     slidesToScroll: 1,
264     slidesToShow: 1,
265     infinite: true,
266     dots: true,
267     arrows: false,
268     autoplay: true,
269     autoplaySpeed: 3000
270   });
271
272
273   let sliderHomepage = $('.l-quotes');
274   sliderHomepage.slick({
275     slidesToShow: 1,
276     centerMode: false,
277     infinite: true,
278     dots: true,
279     arrows: false,
280     autoplay: true,
281     autoplaySpeed: 4000,
282   });
283
284 })();
285
286
287
288
289 // Carousel
290 (function () {
291   let slider = $('.p-homepage__info__box--carousel');
292
293   slider.slick({
294     slidesToScroll: 1,
295     slidesToShow: 1,
296     infinite: true,
297     dots: true,
298     arrows: false,
299     autoplay: true,
300     autoplaySpeed: 5000
301   });
302
303
304
305 })();
306
307
308
309 // Text overlay toggler
310 (function () {
311   let overlays = $('.l-article__overlay');
312   let button = $('.l-article__read-more');
313
314   overlays.each(function () {
315     let maxHeight = $(this).attr('data-max-height');
316     if($(this).outerHeight() > maxHeight) {
317       $(this).css({'maxHeight': maxHeight+'px'}).addClass('is-active');
318     } else {
319       $(this).next('.l-article__read-more').hide();
320     }
321   });
322
323   button.on('click', function() {
324     let dataLabel = $(this).attr('data-label');
325     let dataAction = $(this).attr('data-action');
326     $(this).parent().parent().find('.l-article__overlay').toggleClass('is-clicked');
327     if($(this).text() === dataLabel) {
328       $(this).text(dataAction);
329     } else {
330       $(this).text(dataLabel);
331     }
332   });
333 })();
334
335 (function() {
336     $('.l-checkout__payments__box button').on('click', function() {
337         let container = $(this).closest('.l-checkout__payments');
338         $('input', container).val($(this).val());
339         $('.is-active', container).removeClass('is-active');
340         $(this).closest('.l-checkout__payments__box').addClass('is-active');
341         $('#kwota').val('');
342         return false;
343     });
344     
345 })();
346
347
348 //Copy function
349 (function() {
350   let $copy = $('.js-copy');
351
352   $copy.on('click', function() {
353     let $copyText = $(this).closest('.l-checkout__info__item').find('input');
354     $copyText.select();
355     document.execCommand('copy');
356   });
357 })();
358
359
360
361 // Likes
362 (function() {
363
364     ids = new Set(); 
365     $(".icon-like").each(
366         (i, e)=>{
367             ids.add($(e).attr('data-book'));
368         }
369     );
370     ids = [...ids].join(',');
371
372     state = {
373         liked: [],
374     };
375     
376     $(document).on('click', '.icon-like', function(e) {
377         e.preventDefault();
378         let liked = $(this).hasClass('icon-liked');
379         $btn = $(this);
380         if (liked) {
381             $.post({
382                 url: '/ludzie/lektura/' + $(this).attr('data-book-slug') + '/nie_lubie/',
383                 data: {'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},
384                 success: function() {
385                     delete state.liked[$btn.attr('data-book')];
386                     updateLiked($btn);
387                 }
388             })
389         } else {
390             $.post({
391                 url: '/ludzie/lektura/' + $(this).attr('data-book-slug') + '/lubie/',
392                 data: {'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},
393                 success: function() {
394                     state.liked[$btn.attr('data-book')] = [];
395                     updateLiked($btn);
396                 },
397                 error: function(e) {
398                     if (e.status == 403) {
399                         $('#login-link').click();
400                     }
401                 },
402             });
403         }
404     })
405
406     // TODO: DYNAMICALLY ADD
407    $(".add-set-tag input[name=name]").autocomplete({
408        source: '/ludzie/moje-tagi/',
409    }).on('autocompleteopen', function() {
410        $(this).closest('article').addClass('ac-hover');
411    }).on('autocompleteclose', function() {
412        $(this).closest('article').removeClass('ac-hover');
413    });
414     $(".add-set-tag").on("submit", function(e) {
415         e.preventDefault();
416         let $form = $(this);
417         $.post({
418             url: $form.attr("action"),
419             data: $form.serialize(),
420             success: (data) => {
421                 updateFromData(data);
422                 updateLikedAll();
423                 $('input[name=name]', $form).val('');
424             }
425         });
426     })
427
428     $(document).on("click", ".sets .close", function() {
429         let bookId = $(this).closest("[data-book]").attr('data-book');
430         $.post({
431             url: '/ludzie/usun-tag/',
432             data: {
433                 csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
434                 book: bookId,
435                 slug: $(this).parent().attr('data-set'),
436             },
437             success: (data) => {
438                 updateFromData(data);
439                 updateLikedAll();
440             }
441         });
442     })
443
444     
445     function refreshAll(ids) {
446         $.ajax('/ludzie/ulubione/?ids=' + ids, {
447             success: function(result) {
448                 updateFromData(result);
449                 updateLikedAll();
450             },
451         });
452     }
453     refreshAll(ids);
454     $.refreshLikes = refreshAll;
455
456     function updateFromData(data) {
457         for (pk in data) {
458             if (data[pk] === null) {
459                 delete state.liked[pk];
460             } else {
461                 state.liked[pk] = data[pk];
462             }
463         }
464     }
465     
466     function updateLikedAll() {
467         $(".icon-like").each(
468             (i, e) => {
469                 updateLiked(e);
470             }
471         )
472     }
473
474     function updateLiked(e) {
475         let bookId = $(e).attr('data-book');
476         let liked = bookId in state.liked;
477         $(e).toggleClass('icon-liked', liked);
478         let $bookContainer = $('.book-container-' + bookId);
479         $bookContainer.toggleClass('book-liked', liked);
480         let $sets = $(".sets", $bookContainer);
481         $sets.empty();
482         $.each(state.liked[bookId], (i,e) => {
483             let $set = $("<span>");
484             $set.attr("data-set", e.slug);
485             let $setA = $("<a>").appendTo($set);
486             $setA.attr("href", e.url);
487             $setA.text(e.name);
488             let $setX = $("<a class='close'></a>").appendTo($set);
489             $sets.append($set);
490         });
491     }
492     
493 })();
494
495
496
497 // Toggle a class on long press.
498 (function() {
499     const TIME = 250;
500     let timer;
501
502     $("[data-longpress]").on("touchstart", (e) => {
503         $e = $(e.currentTarget);
504         timer = setTimeout(() => {
505             $e.toggleClass($e.attr('data-longpress'));
506         }, TIME);
507     });
508
509     $("[data-longpress]").on("touchend", () => {
510         clearTimeout(timer);
511     });
512 })();
513
514
515
516 // Update search form filters.
517 (function() {
518     $('.j-form-auto').each(function() {
519         let $form = $(this);
520         $('input', $form).change(function() {$form.submit()});
521         $('select', $form).change(function() {$form.submit()});
522         $('textarea', $form).change(function() {$form.submit()});
523     });
524
525     
526     // experiments
527     $(".experiment input").on('change', function() {
528         let name = $(this).attr('name');
529         let val = $(this).val();
530         document.cookie = 'EXPERIMENT_' + name + '=' + val + '; path=/; max-age=31536000';
531         window.location.reload(true);
532     });
533
534     $('.c-lang').on('click', function() {
535         !$(this).toggleClass('is-open');
536     });
537
538
539
540
541
542     $(".c-media__settings > i").on('click', function() {
543         $(".c-media__settings").toggleClass('active');
544     });
545
546 })();