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