diff --git a/djaif/book/models.py b/djaif/book/models.py
index 15d505b..39521e3 100644
--- a/djaif/book/models.py
+++ b/djaif/book/models.py
@@ -103,6 +103,32 @@ def load_from(self, save_id):
book_progress=self,
).save()
+ def notes(self):
+ """Return a prepared set of notes.
+
+ These notes will be annotated with relation to the
+ current page and will appear in order:
+
+ 1. pinned notes (key=0, pinned=True)
+ 2. current page notes (key=1)
+ 3. other notes (key=0, pinned=False)
+
+ Within each group the notes will be ordered
+ by decreasing of 'updated_at'.
+ """
+ return Note.objects.filter(
+ progress=self,
+ ).annotate(
+ key=models.Count(
+ 'page',
+ filter=models.Q(page=self.book_page),
+ ),
+ ).order_by(
+ '-pinned',
+ '-key',
+ '-updated_at',
+ )
+
class ProgressSave(models.Model):
progress = models.ForeignKey(BookProgress, on_delete=models.CASCADE)
diff --git a/djaif/book/templates/page.html b/djaif/book/templates/page.html
index 65bc705..4ab35c6 100644
--- a/djaif/book/templates/page.html
+++ b/djaif/book/templates/page.html
@@ -3,6 +3,8 @@
@@ -78,28 +80,19 @@
Заметки
{% for name, noteset in notesets %}
-
- {% for note in noteset %}
+
+ {% for note_id, note_text, note_page_title in noteset %}
-
-
- [X]
-
-
- [📎]
-
-
- [🖉]
-
-
{{ note.text }}
- {% if note.page and name == 'other' %}
- ({{ note.page.title }})
+ 🚮
+ 📌
+ 🖉
+ {{ note_text }}
+ {% if note_page_title and name == 'other' %}
+ ({{ note_page_title }})
{% endif %}
{% endfor %}
- {% if noteset %}
-
- {% endif %}
{% endfor %}
diff --git a/djaif/book/views.py b/djaif/book/views.py
index e6831b2..0090e7a 100644
--- a/djaif/book/views.py
+++ b/djaif/book/views.py
@@ -1,4 +1,5 @@
from functools import wraps
+from itertools import groupby
from django.db import transaction
from django.db.models import F, Func # noqa: WPS347
@@ -39,6 +40,7 @@ def view_books(request):
def view_book(request, book_id):
book = get_object_or_404(models.Book, id=book_id)
+
if not book.first_page:
raise ValueError("Book {0.id} hasn't a first page!")
try:
@@ -50,21 +52,41 @@ def view_book(request, book_id):
book=book, user=request.user,
)
- page = progress.book_page
-
links = [
(link, link.has_all_needed(list(progress.items.all())))
- for link in page.pagelink_set.all()
+ for link in progress.book_page.pagelink_set.all()
+ ]
+
+ notesets = [
+ (name, [
+ (
+ note.id,
+ note.text,
+ note.page.title if note.page else '',
+ )
+ for note in group
+ ])
+ for name, group in groupby(
+ progress.notes().select_related(
+ 'page',
+ ).all(),
+ key=lambda note: (
+ 'page' if note.key else
+ 'pinned' if note.pinned else
+ 'other'
+ ),
+ )
]
return render(
request,
'page.html',
context={
- 'page': page,
+ 'page': progress.book_page,
'progress': progress,
'links': links,
- 'page_items': page.items.exclude(
+ 'notesets': notesets,
+ 'page_items': progress.book_page.items.exclude(
id__in=progress.items.only('id'),
).exclude(
id__in=progress.droppeditem_set.values_list(
@@ -72,30 +94,8 @@ def view_book(request, book_id):
),
).all(),
'dropped_items': progress.droppeditem_set.filter(
- book_page=page,
+ book_page=progress.book_page,
).all(),
- 'notesets': [
- (
- 'pinned',
- progress.note_set.filter(
- pinned=True,
- ).order_by('-updated_at').all(),
- ),
- (
- 'page',
- progress.note_set.filter(
- page=page, pinned=False,
- ).order_by('-updated_at').all(),
- ),
- (
- 'other',
- progress.note_set.exclude(
- page=page,
- ).filter(
- pinned=False,
- ).order_by('-updated_at').all(),
- ),
- ],
},
)
diff --git a/djaif/settings.py b/djaif/settings.py
index 56445a1..3e6621a 100644
--- a/djaif/settings.py
+++ b/djaif/settings.py
@@ -116,9 +116,12 @@
USE_TZ = True
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+
+SHELL_PLUS_PRINT_SQL = True
# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/3.0/howto/static-files/
+# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
@@ -130,7 +133,3 @@
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
-
-DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
-
-SHELL_PLUS_PRINT_SQL = True
diff --git a/setup.cfg b/setup.cfg
index 5f09f09..bf06b40 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -29,13 +29,16 @@ exclude =
ignore =
# documentation isn't so important for now
D100, D101, D102, D103, D104, D105, D106,
+ DAR201,
# yes, we have bad names here and there
WPS110, WPS111,
# annoying stuff
WPS326, WPS306, WPS317, WPS202, WPS226, WPS411, WPS323,
+ WPS509,
# I like multiline conditions!
WPS337, W503, W504,
per-file-ignores =
settings.py: WPS407, E501, C812, WPS221, WPS226, S105
models.py: WPS226
+ views.py: WPS210
diff --git a/static/favicon.png b/static/favicon.png
new file mode 100644
index 0000000..adce88a
Binary files /dev/null and b/static/favicon.png differ
diff --git a/static/page.css b/static/page.css
new file mode 100644
index 0000000..23c9075
--- /dev/null
+++ b/static/page.css
@@ -0,0 +1,9 @@
+.noteset {}
+
+.noteset-page {
+ background-color: greenyellow;
+}
+
+.noteset-pinned {
+ background-color: yellow;
+}