Merge pull request #341 from mouse-reeve/pagination

Pagination
This commit is contained in:
Mouse Reeve 2020-11-11 10:58:29 -08:00 committed by GitHub
commit 041b94605c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 12 deletions

View file

@ -6,6 +6,8 @@ from environs import Env
env = Env() env = Env()
DOMAIN = env('DOMAIN') DOMAIN = env('DOMAIN')
PAGE_LENGTH = env('PAGE_LENGTH', 15)
# celery # celery
CELERY_BROKER = env('CELERY_BROKER') CELERY_BROKER = env('CELERY_BROKER')
CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND') CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND')

View file

@ -54,6 +54,26 @@
<p>No activities yet!</a> <p>No activities yet!</a>
</div> </div>
{% endif %} {% endif %}
<nav class="pagination" role="navigation" aria-label="pagination">
{% if prev %}
<p class="pagination-previous">
<a href="{{ prev }}">
<span class="icon icon-arrow-left"></span>
Previous
</a>
</p>
{% endif %}
{% if next %}
<p class="pagination-next">
<a href="{{ next }}">
Next
<span class="icon icon-arrow-right"></span>
</a>
</p>
{% endif %}
</nav>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -3,6 +3,7 @@ import re
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.postgres.search import TrigramSimilarity from django.contrib.postgres.search import TrigramSimilarity
from django.core.paginator import Paginator
from django.db.models import Avg, Q from django.db.models import Avg, Q
from django.http import HttpResponseBadRequest, HttpResponseNotFound,\ from django.http import HttpResponseBadRequest, HttpResponseNotFound,\
JsonResponse JsonResponse
@ -15,6 +16,7 @@ from bookwyrm import outgoing
from bookwyrm.activitypub import ActivityEncoder from bookwyrm.activitypub import ActivityEncoder
from bookwyrm import forms, models, books_manager from bookwyrm import forms, models, books_manager
from bookwyrm import goodreads_import from bookwyrm import goodreads_import
from bookwyrm.settings import PAGE_LENGTH
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.utils import regex from bookwyrm.utils import regex
@ -53,8 +55,6 @@ def home(request):
@login_required @login_required
def home_tab(request, tab): def home_tab(request, tab):
''' user's homepage with activity feed ''' ''' user's homepage with activity feed '''
# TODO: why on earth would this be where the pagination is set
page_size = 15
try: try:
page = int(request.GET.get('page', 1)) page = int(request.GET.get('page', 1))
except ValueError: except ValueError:
@ -63,20 +63,24 @@ def home_tab(request, tab):
suggested_books = get_suggested_books(request.user) suggested_books = get_suggested_books(request.user)
activities = get_activity_feed(request.user, tab) activities = get_activity_feed(request.user, tab)
paginated = Paginator(activities, PAGE_LENGTH)
activity_page = paginated.page(page)
activity_count = activities.count() prev_page = next_page = None
activities = activities[(page - 1) * page_size:page * page_size] if activity_page.has_next():
next_page = '/%s/?page=%d#feed' % \
next_page = '/?page=%d#feed' % (page + 1) (tab, activity_page.next_page_number())
prev_page = '/?page=%d#feed' % (page - 1) if activity_page.has_previous():
prev_page = '/%s/?page=%d#feed' % \
(tab, activity_page.previous_page_number())
data = { data = {
'title': 'Updates Feed', 'title': 'Updates Feed',
'user': request.user, 'user': request.user,
'suggested_books': suggested_books, 'suggested_books': suggested_books,
'activities': activities, 'activities': activity_page.object_list,
'tab': tab, 'tab': tab,
'next': next_page if activity_count > (page_size * page) else None, 'next': next_page,
'prev': prev_page if page > 1 else None, 'prev': prev_page,
} }
return TemplateResponse(request, 'feed.html', data) return TemplateResponse(request, 'feed.html', data)
@ -323,6 +327,11 @@ def user_page(request, username):
return JsonResponse(user.to_activity(), encoder=ActivityEncoder) return JsonResponse(user.to_activity(), encoder=ActivityEncoder)
# otherwise we're at a UI view # otherwise we're at a UI view
try:
page = int(request.GET.get('page', 1))
except ValueError:
page = 1
shelf_preview = [] shelf_preview = []
# only show other shelves that should be visible # only show other shelves that should be visible
@ -347,13 +356,27 @@ def user_page(request, username):
if len(shelf_preview) > 2: if len(shelf_preview) > 2:
break break
# user's posts
activities = get_activity_feed(user, 'self')
paginated = Paginator(activities, PAGE_LENGTH)
activity_page = paginated.page(page)
prev_page = next_page = None
if activity_page.has_next():
next_page = '/user/%s/?page=%d' % \
(username, activity_page.next_page_number())
if activity_page.has_previous():
prev_page = '/user/%s/?page=%d' % \
(username, activity_page.previous_page_number())
data = { data = {
'title': user.name, 'title': user.name,
'user': user, 'user': user,
'is_self': is_self, 'is_self': is_self,
'shelves': shelf_preview, 'shelves': shelf_preview,
'shelf_count': shelves.count(), 'shelf_count': shelves.count(),
'activities': get_activity_feed(user, 'self')[:15], 'activities': activity_page.object_list,
'next': next_page,
'prev': prev_page,
} }
return TemplateResponse(request, 'user.html', data) return TemplateResponse(request, 'user.html', data)
@ -483,6 +506,11 @@ def edit_profile_page(request):
def book_page(request, book_id): def book_page(request, book_id):
''' info about a book ''' ''' info about a book '''
try:
page = int(request.GET.get('page', 1))
except ValueError:
page = 1
book = models.Book.objects.select_subclasses().get(id=book_id) book = models.Book.objects.select_subclasses().get(id=book_id)
if is_api_request(request): if is_api_request(request):
return JsonResponse(book.to_activity(), encoder=ActivityEncoder) return JsonResponse(book.to_activity(), encoder=ActivityEncoder)
@ -499,8 +527,21 @@ def book_page(request, book_id):
reviews = models.Review.objects.filter( reviews = models.Review.objects.filter(
book__in=work.edition_set.all(), book__in=work.edition_set.all(),
) )
# all reviews for the book
reviews = get_activity_feed(request.user, 'federated', model=reviews) reviews = get_activity_feed(request.user, 'federated', model=reviews)
# the reviews to show
paginated = Paginator(reviews.filter(content__isnull=False), PAGE_LENGTH)
reviews_page = paginated.page(page)
prev_page = next_page = None
if reviews_page.has_next():
next_page = '/book/%d/?page=%d' % \
(book_id, reviews_page.next_page_number())
if reviews_page.has_previous():
prev_page = '/book/%s/?page=%d' % \
(book_id, reviews_page.previous_page_number())
user_tags = [] user_tags = []
readthroughs = [] readthroughs = []
if request.user.is_authenticated: if request.user.is_authenticated:
@ -523,7 +564,7 @@ def book_page(request, book_id):
data = { data = {
'title': book.title, 'title': book.title,
'book': book, 'book': book,
'reviews': reviews.filter(content__isnull=False), 'reviews': reviews_page,
'ratings': reviews.filter(content__isnull=True), 'ratings': reviews.filter(content__isnull=True),
'rating': rating['rating__avg'], 'rating': rating['rating__avg'],
'tags': tags, 'tags': tags,
@ -538,6 +579,8 @@ def book_page(request, book_id):
{'name': 'Format', 'value': book.physical_format}, {'name': 'Format', 'value': book.physical_format},
{'name': 'Pages', 'value': book.pages}, {'name': 'Pages', 'value': book.pages},
], ],
'next': next_page,
'prev': prev_page,
} }
return TemplateResponse(request, 'book.html', data) return TemplateResponse(request, 'book.html', data)