More views, and likes working.
authorRadek Czajka <rczajka@rczajka.pl>
Fri, 25 Nov 2022 14:41:33 +0000 (15:41 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Fri, 25 Nov 2022 14:41:33 +0000 (15:41 +0100)
19 files changed:
src/catalogue/templates/catalogue/2022/book_box.html
src/catalogue/templates/catalogue/2022/set_detail.html [new file with mode: 0644]
src/catalogue/views.py
src/messaging/templates/messaging/contact_detail.html
src/messaging/templates/messaging/contact_form.html
src/paypal/templates/paypal/cancel.html
src/pdcounter/templates/pdcounter/2022/author_detail.html [new file with mode: 0644]
src/pdcounter/templates/pdcounter/2022/book_detail.html [new file with mode: 0644]
src/pdcounter/views.py
src/social/forms.py
src/social/templates/social/2022/my_shelf.html [new file with mode: 0644]
src/social/urls.py
src/social/views.py
src/wolnelektury/settings/static.py
src/wolnelektury/static/2021/scripts/main.js
src/wolnelektury/static/2022/styles/local.scss
src/wolnelektury/templates/2022/base.html
src/wolnelektury/templates/2022/header.html
src/wolnelektury/templates/registration/login.html

index db6bfb1..dd3b8fd 100644 (file)
@@ -1,7 +1,7 @@
 {% load sorl_thumbnail %}
 
 {% load sorl_thumbnail %}
 
-<article class="l-books__item" data-pop="-{{ book.popularity.count }}">
-  <figure class="l-books__item__img" style="height:240px">
+<article class="l-books__item book-container-activator" data-pop="-{{ book.popularity.count }}" data-longpress="hover">
+  <figure class="l-books__item__img book-container book-container-{{ book.pk }}" style="height:240px" data-book="{{ book.pk }}">
     <a href="{{ book.get_absolute_url }}">
       {% if book.is_picture %}
         {% if book.image_file %}
     <a href="{{ book.get_absolute_url }}">
       {% if book.is_picture %}
         {% if book.image_file %}
         {% endif %}
       {% endif %}
     </a>
         {% endif %}
       {% endif %}
     </a>
+
+    <div class="set-tools">
+      <div class="sets"></div>
+      <form method="post" action="{% url 'social_add_set_tag' %}" class="add-set-tag">
+        {% csrf_token %} {# this needs to be copied in with JS #}
+        <input type="hidden" name="book" value="{{ book.id }}">
+        <input name="name" placeholder="nazwa półki" />
+        <button type="submit"></button>
+      </form>
+    </div>
+
   </figure>
   <div class="l-books__item__actions">
     {% if book.is_book %}
   </figure>
   <div class="l-books__item__actions">
     {% if book.is_book %}
@@ -26,7 +37,7 @@
     {% if book.is_picture %}
       <span class="icon icon-picture" title="obraz"></span>
     {% endif %}
     {% if book.is_picture %}
       <span class="icon icon-picture" title="obraz"></span>
     {% endif %}
-    <!-- a href="#" class="icon icon-like"></a -->
+    <a href="{{ book.get_absolute_url }}" class="icon icon-like" data-book="{{ book.pk }}" data-book-slug="{{ book.slug }}"></a>
   </div>
   <h3>
     {% for author in book.authors %}
   </div>
   <h3>
     {% for author in book.authors %}
diff --git a/src/catalogue/templates/catalogue/2022/set_detail.html b/src/catalogue/templates/catalogue/2022/set_detail.html
new file mode 100644 (file)
index 0000000..e835a86
--- /dev/null
@@ -0,0 +1,41 @@
+{% extends '2022/base.html' %}
+
+{% load choose_cites from social_tags %}
+
+
+{% block breadcrumbs %}
+  <a href="/ludzie/polka/"><span>Półka</span></a>
+{% endblock %}
+
+{% block main %}
+  <div class="l-section">
+    <div class="l-author__header">
+      <h1>{{ tags.0.name }}</h1>
+    </div>
+  </div>
+
+  <div class="l-section">
+    <div class="l-books__header">
+      <div class="l-books__input">
+        <i class="icon icon-filter"></i>
+        <input type="text" placeholder="filtry, tytuł" class="quick-filter" data-for="book-list">
+      </div>
+      <div class="l-books__sorting">
+        <span>Sortuj:</span>
+        <div>
+          <button data-order="data-pop">najpopularniejsze</button>
+          <button class="is-active">alfabetycznie</button>
+          <!--button>chronologicznie</button-->
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <div class="l-section l-section--col">
+    <div class="l-books__grid" id="book-list">
+      {% for book in object_list %}
+        {% include "catalogue/2022/book_box.html" %}
+      {% endfor %}
+    </div>
+  </div>
+{% endblock %}
index b57ba11..2955a5c 100644 (file)
@@ -148,10 +148,13 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
         result.update(extra)
 
     is_author = len(tags) == 1 and tags[0].category == 'author'
         result.update(extra)
 
     is_author = len(tags) == 1 and tags[0].category == 'author'
+    is_set = len(tags) == 1 and tags[0].category == 'set'
     is_theme = len(tags) == 1 and tags[0].category == 'theme'
     new_layout = request.EXPERIMENTS['layout']
     if is_author and new_layout.value:
         template = 'catalogue/2022/author_detail.html'
     is_theme = len(tags) == 1 and tags[0].category == 'theme'
     new_layout = request.EXPERIMENTS['layout']
     if is_author and new_layout.value:
         template = 'catalogue/2022/author_detail.html'
+    elif is_set and new_layout.value:
+        template = 'catalogue/2022/set_detail.html'
     elif is_theme and new_layout.value:
         template = 'catalogue/2022/theme_detail.html'
     else:
     elif is_theme and new_layout.value:
         template = 'catalogue/2022/theme_detail.html'
     else:
index 725f208..f1e606d 100644 (file)
@@ -1,4 +1,4 @@
-{% extends "base/base.html" %}
+{% extends request.EXPERIMENTS.layout.value|yesno:"2022/base_simple.html,base/base.html" %}
 
 {% block body %}
 
 
 {% block body %}
 
index 153490a..789042d 100644 (file)
@@ -1,10 +1,12 @@
-{% extends "base/base.html" %}
+{% extends request.EXPERIMENTS.layout.value|yesno:"2022/base_simple.html,base/base.html" %}
 
 {% block body %}
 
 
 {% block body %}
 
-<h1>Czy na pewno chcesz zrezygnować z otrzymywania e-maili na adres {{ object.email }}?</h1>
+  <h1>Rezygnacja z e-maili</h1>
 
 
-<form method="POST" action="">
+    <p>Czy na pewno chcesz zrezygnować z otrzymywania e-maili na adres {{ object.email }}?</p>
+
+  <form method="POST" action="">
        {% csrf_token %}
        <button type="submit">Tak, wypisz mnie</button>
 </form>
        {% csrf_token %}
        <button type="submit">Tak, wypisz mnie</button>
 </form>
index 4599799..9236051 100644 (file)
@@ -1,6 +1,7 @@
-{% extends "base/base.html" %}
+{% extends request.EXPERIMENTS.layout.value|yesno:"2022/base_simple.html,base/base.html" %}
 {% load i18n %}
 
 {% block body %}
 {% load i18n %}
 
 {% block body %}
+  <h1>Płatność nieudana</h1>
   <p>{% trans "Zrezygnowano z płatności :(" %}</p>
   <p>{% trans "Zrezygnowano z płatności :(" %}</p>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/src/pdcounter/templates/pdcounter/2022/author_detail.html b/src/pdcounter/templates/pdcounter/2022/author_detail.html
new file mode 100644 (file)
index 0000000..c1920d1
--- /dev/null
@@ -0,0 +1,54 @@
+{% extends "2022/base.html" %}
+{% load i18n %}
+{% load time_tags %}
+
+{% block settings %}
+  {% load title %}
+  {% title author.name %}
+{% endblock %}
+
+{% block breadcrumbs %}
+  <a href="/katalog/"><span>Katalog</span></a>
+  <a href="/katalog/autor/"><span>Autor</span></a>
+{% endblock %}
+
+{% block main %}
+  <div class="l-section">
+    <div class="l-author__header">
+      <h1>{{ author.name }}</h1>
+    </div>
+  </div>
+
+  <div class="l-section">
+
+
+    {% if author.alive %}
+      <p>
+        {% trans "This author's works are copyrighted." %}
+        {% trans "<a href='http://domenapubliczna.org/co-to-jest-domena-publiczna/'>Find out</a> why Internet libraries can't publish this author's works." %}
+      </p>
+    {% else %}
+      {% if author.in_pd %}
+        <p>{% trans "This author's works are in public domain, but they were not yet published on Internet library of Wolne Lektury." %}</p>
+      {% else %}
+        <div>
+          <p>
+            {% trans "This author's works will become part of public domain and will be allowed to be published without restrictions in" %}
+          </p>
+          <div class='countdown' data-until='{{ pd_counter|date_to_utc|utc_for_js }}'></div>
+          <p>
+            {% trans "<a href='http://domenapubliczna.org/co-to-jest-domena-publiczna/'>Find out</a> why Internet libraries can't publish this author's works." %}
+          </p>
+        </div>
+      {% endif %}
+    {% endif %}
+
+
+  </div>
+
+  <section class="l-section">
+    <div class="l-author">
+      {% include "catalogue/2022/author_box.html" %}
+    </div>
+  </section>
+{% endblock %}
diff --git a/src/pdcounter/templates/pdcounter/2022/book_detail.html b/src/pdcounter/templates/pdcounter/2022/book_detail.html
new file mode 100644 (file)
index 0000000..9f07b47
--- /dev/null
@@ -0,0 +1,54 @@
+{% extends '2022/base.html' %}
+{% load i18n %}
+{% load time_tags %}
+
+{% block global-content %}
+  <div class="l-container">
+    <div class="l-breadcrumb">
+      <a href="/"><span>Strona główna</span></a>
+      <a href="/katalog/lektury/"><span>Literatura</span></a>
+    </div>
+  </div>
+
+
+  <main class="l-main">
+    <section class="l-section">
+      <div class="l-content">
+        <header class="l-header">
+          <div class="l-header__content">
+            <p>{{ book.author }}</p>
+            <h1>{{ book.title }}</h1>
+            {% if book.translator %}
+              <p class="l-header__translators">
+                tłum.
+                {{ book.translator }}
+              </p>
+            {% endif %}
+          </div>
+        </header>
+        <article class="l-article">
+          {% if book.in_pd %}
+            <p>{% trans "This work is in public domain and will be published on Internet library of Wolne Lektury soon." %}</p>
+          {% else %}
+            {% if book.pd %}
+              <p>
+                {% trans "This work will become part of public domain and will be allowed to be published without restrictions in" %}
+              </p>
+              <div class='countdown' data-until='{{ pd_counter|date_to_utc|utc_for_js }}'></div>
+              <p>
+                {% trans "<a href='http://domenapubliczna.org/co-to-jest-domena-publiczna/'>Find out</a> why Internet libraries can't publish this work." %}
+              </p>
+            {% else %}
+              <p>
+                {% trans "This work is copyrighted." %}
+                {% trans "<a href='http://domenapubliczna.org/co-to-jest-domena-publiczna/'>Find out</a> why Internet libraries can't publish this work." %}
+              </p>
+            {% endif %}
+          {% endif %}
+        </article>
+      </div>
+    </section>
+  </main>
+
+
+{% endblock %}
index 5e3f3be..c782c0b 100644 (file)
@@ -18,7 +18,12 @@ def book_stub_detail(request, slug):
 
     form = PublishingSuggestForm(initial={"books": "%s — %s, \n" % (book.author, book.title)})
 
 
     form = PublishingSuggestForm(initial={"books": "%s — %s, \n" % (book.author, book.title)})
 
-    return render(request, 'pdcounter/book_stub_detail.html', {
+    if request.EXPERIMENTS['layout'].value:
+        template_name = 'pdcounter/2022/book_detail.html'
+    else:
+        template_name = 'pdcounter/book_detail.html'
+
+    return render(request, template_name, {
         'book': book,
         'pd_counter': pd_counter,
         'form': form,
         'book': book,
         'pd_counter': pd_counter,
         'form': form,
@@ -35,7 +40,12 @@ def author_detail(request, slug):
 
     form = PublishingSuggestForm(initial={"books": author.name + ", \n"})
 
 
     form = PublishingSuggestForm(initial={"books": author.name + ", \n"})
 
-    return render(request, 'pdcounter/author_detail.html', {
+    if request.EXPERIMENTS['layout'].value:
+        template_name = 'pdcounter/2022/author_detail.html'
+    else:
+        template_name = 'pdcounter/author_detail.html'
+
+    return render(request, template_name, {
         'author': author,
         'pd_counter': pd_counter,
         'form': form,
         'author': author,
         'pd_counter': pd_counter,
         'form': form,
index 1e2462a..8527915 100644 (file)
@@ -4,7 +4,7 @@
 from django import forms
 from django.utils.translation import gettext_lazy as _
 
 from django import forms
 from django.utils.translation import gettext_lazy as _
 
-from catalogue.models import Tag
+from catalogue.models import Book, Tag
 from catalogue import utils
 from social.utils import get_set, set_sets
 
 from catalogue import utils
 from social.utils import get_set, set_sets
 
@@ -49,3 +49,47 @@ class NewSetForm(forms.Form):
 
         new_set.save()
         return new_set
 
         new_set.save()
         return new_set
+
+
+class AddSetForm(forms.Form):
+    name = forms.CharField(max_length=50)
+    book = forms.IntegerField()
+
+    def save(self, user):
+        name = self.cleaned_data['name'].strip()
+        if not name: return
+        tag = get_set(user, name)
+        try:
+            book = Book.objects.get(id=self.cleaned_data['book'])
+        except Book.DoesNotExist:
+            return
+
+        try:
+            book.tag_relations.create(tag=tag)
+        except:
+            pass
+
+        return book, tag
+
+
+class RemoveSetForm(forms.Form):
+    slug = forms.CharField(max_length=50)
+    book = forms.IntegerField()
+
+    def save(self, user):
+        slug = self.cleaned_data['slug']
+        try:
+            tag = Tag.objects.get(user=user, slug=slug)
+        except Tag.DoesNotExist:
+            return
+        try:
+            book = Book.objects.get(id=self.cleaned_data['book'])
+        except Book.DoesNotExist:
+            return
+
+        try:
+            book.tag_relations.filter(tag=tag).delete()
+        except:
+            pass
+
+        return book, tag
diff --git a/src/social/templates/social/2022/my_shelf.html b/src/social/templates/social/2022/my_shelf.html
new file mode 100644 (file)
index 0000000..3dbd80d
--- /dev/null
@@ -0,0 +1,41 @@
+{% extends '2022/base.html' %}
+
+
+{% block settings %}
+  {% load title %}
+  {% title 'Półka' %}
+{% endblock %}
+
+{% block main %}
+  <div class="l-section">
+    <div class="l-author__header">
+      <h1>Półka</h1>
+    </div>
+  </div>
+
+  <div class="l-section">
+    <div class="l-books__header">
+      <div class="l-books__input">
+        <i class="icon icon-filter"></i>
+        <input type="text" placeholder="filtry, tytuł" class="quick-filter" data-for="book-list">
+      </div>
+      <div class="l-books__sorting">
+        <span>Sortuj:</span>
+        <div>
+          <button data-order="data-pop">najpopularniejsze</button>
+          <button class="is-active">alfabetycznie</button>
+          <!--button>chronologicznie</button-->
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <div class="l-section l-section--col">
+    <div class="l-books__grid" id="book-list">
+      {% for book in books %}
+        {% include "catalogue/2022/book_box.html" %}
+      {% endfor %}
+    </div>
+  </div>
+
+{% endblock %}
index e092ff0..dc34fb6 100644 (file)
@@ -8,7 +8,11 @@ from . import views
 
 urlpatterns = [
     path('lektura/<slug:slug>/lubie/', views.like_book, name='social_like_book'),
 
 urlpatterns = [
     path('lektura/<slug:slug>/lubie/', views.like_book, name='social_like_book'),
+    path('dodaj-tag/', views.AddSetView.as_view(), name='social_add_set_tag'),
+    path('usun-tag/', views.RemoveSetView.as_view(), name='social_remove_set_tag'),
+    path('moje-tagi/', views.my_tags, name='social_my_tags'),
     path('lektura/<slug:slug>/nie_lubie/', views.unlike_book, name='social_unlike_book'),
     path('lektura/<slug:slug>/polki/', never_cache(views.ObjectSetsFormView()), name='social_book_sets'),
     path('polka/', views.my_shelf, name='social_my_shelf'),
     path('lektura/<slug:slug>/nie_lubie/', views.unlike_book, name='social_unlike_book'),
     path('lektura/<slug:slug>/polki/', never_cache(views.ObjectSetsFormView()), name='social_book_sets'),
     path('polka/', views.my_shelf, name='social_my_shelf'),
+    path('ulubione/', views.my_liked),
 ]
 ]
index 8966159..d9627eb 100644 (file)
@@ -4,11 +4,14 @@
 from django.shortcuts import render, get_object_or_404, redirect
 from django.http import HttpResponseForbidden, JsonResponse
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import render, get_object_or_404, redirect
 from django.http import HttpResponseForbidden, JsonResponse
 from django.contrib.auth.decorators import login_required
+from django.views.decorators.cache import never_cache
 from django.views.decorators.http import require_POST
 from django.views.decorators.http import require_POST
+from django.views.generic.edit import FormView
 
 from ajaxable.utils import AjaxableFormView
 
 
 from ajaxable.utils import AjaxableFormView
 
-from catalogue.models import Book
+from catalogue.models import Book, Tag
+import catalogue.models.tag
 from social import forms
 from wolnelektury.utils import is_ajax
 
 from social import forms
 from wolnelektury.utils import is_ajax
 
@@ -32,6 +35,23 @@ def like_book(request, slug):
         return redirect(book)
 
 
         return redirect(book)
 
 
+class AddSetView(FormView):
+    form_class = forms.AddSetForm
+    template_name = 'forms/form_detail.html'
+
+    def form_valid(self, form):
+        book, tag = form.save(self.request.user)
+
+        if is_ajax(self.request):
+            return JsonResponse(get_sets_for_book_ids([book.id], self.request.user))
+        else:
+            return redirect(book)
+
+
+class RemoveSetView(AddSetView):
+    form_class = forms.RemoveSetForm
+
+
 @require_POST
 def unlike_book(request, slug):
     if not request.user.is_authenticated:
 @require_POST
 def unlike_book(request, slug):
     if not request.user.is_authenticated:
@@ -48,11 +68,64 @@ def unlike_book(request, slug):
 
 @login_required
 def my_shelf(request):
 
 @login_required
 def my_shelf(request):
-    return render(request, 'social/my_shelf.html', {
+    if request.EXPERIMENTS['layout'].value:
+        template_name = 'social/2022/my_shelf.html'
+    else:
+        template_name = 'social/my_shelf.html'
+    return render(request, template_name, {
         'books': Book.tagged.with_any(request.user.tag_set.all())
     })
 
 
         'books': Book.tagged.with_any(request.user.tag_set.all())
     })
 
 
+def get_sets_for_book_ids(book_ids, user):
+    data = {}
+    tagged = catalogue.models.tag.TagRelation.objects.filter(
+        tag__user=user,
+        #content_type= # for books,
+        object_id__in=book_ids
+    ).order_by('tag__sort_key')
+    for t in tagged:
+        # related?
+        item = data.setdefault(t.object_id, [])
+        if t.tag.name:
+            item.append({
+                "slug": t.tag.slug,
+                "url": t.tag.get_absolute_url(),
+                "name": t.tag.name,
+            })
+    for b in book_ids:
+        if b not in data:
+            data[b] = None
+    return data
+    
+    
+
+
+@never_cache
+def my_liked(request):
+    if not request.user.is_authenticated:
+        return JsonResponse({})
+    try:
+        ids = [int(x) for x in request.GET.get('ids', '').split(',')]
+    except:
+        return JsonResponse({})
+    return JsonResponse(get_sets_for_book_ids(ids, request.user))
+
+
+@never_cache
+@login_required
+def my_tags(request):
+    term = request.GET.get('term', '')
+    tags =             Tag.objects.filter(user=request.user).order_by('sort_key')
+    if term:
+        tags = tags.filter(name__icontains=term)
+    return JsonResponse(
+        [
+            t.name for t in tags
+        ], safe=False
+    )
+
+
 class ObjectSetsFormView(AjaxableFormView):
     form_class = forms.ObjectSetsForm
     placeholdize = True
 class ObjectSetsFormView(AjaxableFormView):
     form_class = forms.ObjectSetsForm
     placeholdize = True
index 9e07efb..81a935a 100644 (file)
@@ -25,6 +25,7 @@ PIPELINE = {
         '2022': {
             'source_filenames': [
                 'contrib/jquery-ui-1.13.1.custom/jquery-ui.css',
         '2022': {
             'source_filenames': [
                 'contrib/jquery-ui-1.13.1.custom/jquery-ui.css',
+                'css/jquery.countdown.css',
                 '2022/styles/main.scss',
                 '2022/more.scss',
                 'chunks/edit.scss',
                 '2022/styles/main.scss',
                 '2022/more.scss',
                 'chunks/edit.scss',
@@ -138,11 +139,14 @@ PIPELINE = {
         },
         '2022': {
             'source_filenames': [
         },
         '2022': {
             'source_filenames': [
+                '2022/scripts/vendor.js',
                 'contrib/jquery-ui-1.13.1.custom/jquery-ui.js',
                 'js/search.js',
                 'js/2022.js',
                 '2022/book/filter.js',
                 'chunks/edit.js',
                 'contrib/jquery-ui-1.13.1.custom/jquery-ui.js',
                 'js/search.js',
                 'js/2022.js',
                 '2022/book/filter.js',
                 'chunks/edit.js',
+                '2022/scripts/modernizr.js',
+                '2021/scripts/main.js',
 
                 'js/contrib/jquery.countdown.js', 'js/contrib/jquery.countdown-pl.js',
                 'js/contrib/jquery.countdown-de.js', 'js/contrib/jquery.countdown-uk.js',
 
                 'js/contrib/jquery.countdown.js', 'js/contrib/jquery.countdown-pl.js',
                 'js/contrib/jquery.countdown-de.js', 'js/contrib/jquery.countdown-uk.js',
index 3dd799a..a37d256 100644 (file)
     document.execCommand('copy');
   });
 })();
     document.execCommand('copy');
   });
 })();
+
+
+
+// Likes
+(function() {
+
+    ids = new Set(); 
+    $(".icon-like").each(
+        (i, e)=>{
+            ids.add($(e).attr('data-book'));
+        }
+    );
+    ids = [...ids].join(',');
+
+    state = {
+        liked: [],
+    };
+    
+    $(".icon-like").on('click', function(e) {
+        e.preventDefault();
+        let liked = $(this).hasClass('icon-liked');
+        $btn = $(this);
+        if (liked) {
+            $.post({
+                url: '/ludzie/lektura/' + $(this).attr('data-book-slug') + '/nie_lubie/',
+                data: {'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},
+                success: function() {
+                    delete state.liked[$btn.attr('data-book')];
+                    updateLiked($btn);
+                }
+            })
+        } else {
+            $.post({
+                url: '/ludzie/lektura/' + $(this).attr('data-book-slug') + '/lubie/',
+                data: {'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},
+                success: function() {
+                    state.liked[$btn.attr('data-book')] = [];
+                    updateLiked($btn);
+                },
+                error: function(e) {
+                    if (e.status == 403) {
+                        $('#login-link').click();
+                    }
+                },
+            });
+        }
+    })
+
+   $(".add-set-tag input[name=name]").autocomplete({
+       source: '/ludzie/moje-tagi/',
+   }).on('autocompleteopen', function() {
+       $(this).closest('article').addClass('ac-hover');
+   }).on('autocompleteclose', function() {
+       $(this).closest('article').removeClass('ac-hover');
+   });
+    $(".add-set-tag").on("submit", function(e) {
+        e.preventDefault();
+        let $form = $(this);
+        $.post({
+            url: $form.attr("action"),
+            data: $form.serialize(),
+            success: (data) => {
+                updateFromData(data);
+                updateLikedAll();
+                $('input[name=name]', $form).val('');
+            }
+        });
+    })
+
+    $(document).on("click", ".sets .close", function() {
+        let bookId = $(this).closest("[data-book]").attr('data-book');
+        $.post({
+            url: '/ludzie/usun-tag/',
+            data: {
+                csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
+                book: bookId,
+                slug: $(this).parent().attr('data-set'),
+            },
+            success: (data) => {
+                updateFromData(data);
+                updateLikedAll();
+            }
+        });
+    })
+
+    
+    function refreshAll(ids) {
+        $.ajax('/ludzie/ulubione/?ids=' + ids, {
+            success: function(result) {
+                updateFromData(result);
+                updateLikedAll();
+            },
+        });
+    }
+    refreshAll(ids);
+
+    function updateFromData(data) {
+        for (pk in data) {
+            if (data[pk] === null) {
+                delete state.liked[pk];
+            } else {
+                state.liked[pk] = data[pk];
+            }
+        }
+    }
+    
+    function updateLikedAll() {
+        $(".icon-like").each(
+            (i, e) => {
+                updateLiked(e);
+            }
+        )
+    }
+
+    function updateLiked(e) {
+        let bookId = $(e).attr('data-book');
+        let liked = bookId in state.liked;
+        $(e).toggleClass('icon-liked', liked);
+        let $bookContainer = $('.book-container-' + bookId);
+        $bookContainer.toggleClass('book-liked', liked);
+        let $sets = $(".sets", $bookContainer);
+        $sets.empty();
+        $.each(state.liked[bookId], (i,e) => {
+            let $set = $("<span>");
+            $set.attr("data-set", e.slug);
+            let $setA = $("<a>").appendTo($set);
+            $setA.attr("href", e.url);
+            $setA.text(e.name);
+            let $setX = $("<a class='close'></a>").appendTo($set);
+            $sets.append($set);
+        });
+    }
+    
+})();
+
+
+
+// Toggle a class on long press.
+(function() {
+    const TIME = 250;
+    let timer;
+
+    $("[data-longpress]").on("touchstart", (e) => {
+        $e = $(e.currentTarget);
+        timer = setTimeout(() => {
+            $e.toggleClass($e.attr('data-longpress'));
+        }, TIME);
+    });
+
+    $("[data-longpress]").on("touchend", () => {
+        clearTimeout(timer);
+    });
+})();
index 726b1b3..5f63275 100644 (file)
@@ -96,3 +96,86 @@ $teal: #007880;
         }
     }
 }
         }
     }
 }
+
+
+
+
+.book-container {
+    position: relative;
+
+    .set-tools {
+        display: none;
+        font-size: 12px;
+        position: absolute;
+        bottom: 0px;
+        right: 0;
+        left: 0;
+        background: black;
+        background: linear-gradient(0deg, rgba(0,0,0,1) 0%, rgba(255,255,255,0) 100%);
+        color: white;
+        padding: 30px 10px 10px;
+
+        .sets {
+            span {
+                padding: 3px 18px 3px 3px;
+                background: white;
+                color: black;
+                margin-right: 5px;
+                margin-bottom: 5px;
+                display: inline-block;
+                border-radius: 3px;
+                position: relative;
+
+                .close {
+                    margin-left: 5px;
+                    position: absolute;
+                    top: 0;
+                    right: 0;
+                    font-family: wl;
+                    font-size: 10px;
+                    color: #FF4C54;
+                    padding: 4px;
+                    
+                    &:hover {
+                        text-decoration: none;
+                        color: black;
+                        cursor: pointer;
+                    }
+                }
+            }
+        }
+        .add-set-tag {
+            input {
+                width: 100%;
+            }
+            button {
+                font-family: wl;
+                position: absolute;
+                right: 12px;
+                color: #FF4C54;
+                bottom: 10px;
+                font-size: 12px;
+                border: 0;
+                background: none;
+                padding: 3px;
+            }
+        }
+    }
+}
+
+
+.book-container-activator {
+    &:hover, &.hover, &.ac-hover {
+        .book-container {
+            &.book-liked {
+                .icon-liked {
+                    font-size: 2em;
+                }
+
+                .set-tools {
+                    display: block;
+                }
+            }
+        }
+    }
+}
index 36b1452..363d99f 100644 (file)
@@ -17,7 +17,6 @@
     <title>{% if title %}{{ title }} | {% endif %}WolneLektury.pl</title>
     <link rel="apple-touch-icon" href="apple-touch-icon.png">
     {% stylesheet '2022' %}
     <title>{% if title %}{{ title }} | {% endif %}WolneLektury.pl</title>
     <link rel="apple-touch-icon" href="apple-touch-icon.png">
     {% stylesheet '2022' %}
-      <script src="scripts/modernizr.js"></script>
 
       <link rel="preconnect" href="https://fonts.googleapis.com">
       <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 
       <link rel="preconnect" href="https://fonts.googleapis.com">
       <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@@ -67,9 +66,6 @@
 
     {% include '2022/footer.html' %}
 
 
     {% include '2022/footer.html' %}
 
-    <script src="{% static '2022/scripts/vendor.js' %}"></script>
-    <script src="{% static '2021/scripts/main.js' %}"></script>
-
     <script type="text/javascript">
       var LANGUAGE_CODE = "{{ LANGUAGE_CODE }}";
     </script>
     <script type="text/javascript">
       var LANGUAGE_CODE = "{{ LANGUAGE_CODE }}";
     </script>
@@ -77,5 +73,6 @@
     {% javascript '2022_player' %}
     {% block extrabody %}{% endblock %}
     {% include '2022/hotjar.html' %}
     {% javascript '2022_player' %}
     {% block extrabody %}{% endblock %}
     {% include '2022/hotjar.html' %}
+    {% csrf_token %}
   </body>
 </html>
   </body>
 </html>
index 6c7ff11..a99a8ab 100644 (file)
@@ -44,7 +44,7 @@
         </a>
       {% else %}
         <div class="l-navigation__login">
         </a>
       {% else %}
         <div class="l-navigation__login">
-          <a href='{% url 'login' %}?next={{ request.path }}'>Zaloguj się</a>
+          <a id="login-link" href='{% url 'login' %}?next={{ request.path }}'>Zaloguj się</a>
           /
           <a href='{% url 'register' %}?next={{ request.path }}'>Załóż konto</a>
         </div>
           /
           <a href='{% url 'register' %}?next={{ request.path }}'>Załóż konto</a>
         </div>
index a962aec..150988a 100644 (file)
@@ -24,6 +24,9 @@
 
     <a href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
 
 
     <a href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
 
+    <br><br>
+    <a href="{% url 'register' %}?next={{ request.GET.next }}">Nie masz jeszcze konta?</a>
+
     {% if USE_OPENID %}
       <h3>{% trans "Sign in using:" %}</h3>
 
     {% if USE_OPENID %}
       <h3>{% trans "Sign in using:" %}</h3>