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