Several pagination improvements (#170)

Home/Notification gets pagination, Follows becomes ListView
This commit is contained in:
Gabriel Rodríguez Alberich 2022-12-17 01:06:29 +01:00 committed by GitHub
parent 45c6978bc3
commit fb2eea956e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 95 additions and 41 deletions

View file

@ -1,33 +1,39 @@
from django.db.models import Q
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.generic import TemplateView from django.views.generic import ListView
from users.decorators import identity_required from users.decorators import identity_required
from users.models import FollowStates from users.models import Follow, FollowStates
@method_decorator(identity_required, name="dispatch") @method_decorator(identity_required, name="dispatch")
class FollowsPage(TemplateView): class Follows(ListView):
""" """
Shows followers/follows. Shows followers/follows.
""" """
template_name = "activities/follows.html" template_name = "activities/follows.html"
extra_context = {
"section": "follows",
}
paginate_by = 50
def get_queryset(self):
return Follow.objects.filter(
Q(source=self.request.identity) | Q(target=self.request.identity),
state__in=FollowStates.group_active(),
).order_by("-created")
def get_context_data(self): def get_context_data(self):
# Gather all identities with a following relationship with us context = super().get_context_data()
identities = {} identities = []
for outbound_follow in self.request.identity.outbound_follows.filter( for follow in context["page_obj"].object_list:
state__in=FollowStates.group_active() if follow.source == self.request.identity:
): identity = follow.target
identities.setdefault(outbound_follow.target, {})[ follow_type = "outbound"
"outbound" else:
] = outbound_follow identity = follow.source
for inbound_follow in self.request.identity.inbound_follows.filter( follow_type = "inbound"
state__in=FollowStates.group_active() identities.append((identity, follow_type))
): context["page_obj"].object_list = identities
identities.setdefault(inbound_follow.source, {})["inbound"] = inbound_follow return context
return {
"section": "follows",
"identities": sorted(identities.items(), key=lambda i: i[0].username),
}

View file

@ -1,3 +1,4 @@
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.template.defaultfilters import linebreaks_filter from django.template.defaultfilters import linebreaks_filter
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@ -22,20 +23,23 @@ class Home(FormView):
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
context["events"] = list( events = (
TimelineEvent.objects.filter( TimelineEvent.objects.filter(
identity=self.request.identity, identity=self.request.identity,
type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost], type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost],
) )
.select_related("subject_post", "subject_post__author") .select_related("subject_post", "subject_post__author")
.prefetch_related("subject_post__attachments", "subject_post__mentions") .prefetch_related("subject_post__attachments", "subject_post__mentions")
.order_by("-created")[:50] .order_by("-created")
) )
context["interactions"] = PostInteraction.get_event_interactions( context["interactions"] = PostInteraction.get_event_interactions(
context["events"], self.request.identity events, self.request.identity
) )
context["current_page"] = "home" context["current_page"] = "home"
context["allows_refresh"] = True context["allows_refresh"] = True
paginator = Paginator(events, 50)
page_number = self.request.GET.get("page")
context["page_obj"] = paginator.get_page(page_number)
return context return context
def form_valid(self, form): def form_valid(self, form):
@ -74,7 +78,7 @@ class Tag(ListView):
.tagged_with(self.hashtag) .tagged_with(self.hashtag)
.select_related("author") .select_related("author")
.prefetch_related("attachments", "mentions") .prefetch_related("attachments", "mentions")
.order_by("-created")[:50] .order_by("-created")
) )
def get_context_data(self): def get_context_data(self):
@ -103,7 +107,7 @@ class Local(ListView):
Post.objects.local_public() Post.objects.local_public()
.select_related("author", "author__domain") .select_related("author", "author__domain")
.prefetch_related("attachments", "mentions", "emojis") .prefetch_related("attachments", "mentions", "emojis")
.order_by("-created")[:50] .order_by("-created")
) )
def get_context_data(self): def get_context_data(self):
@ -131,7 +135,7 @@ class Federated(ListView):
) )
.select_related("author", "author__domain") .select_related("author", "author__domain")
.prefetch_related("attachments", "mentions", "emojis") .prefetch_related("attachments", "mentions", "emojis")
.order_by("-created")[:50] .order_by("-created")
) )
def get_context_data(self): def get_context_data(self):
@ -175,7 +179,7 @@ class Notifications(ListView):
types.append(type) types.append(type)
return ( return (
TimelineEvent.objects.filter(identity=self.request.identity, type__in=types) TimelineEvent.objects.filter(identity=self.request.identity, type__in=types)
.order_by("-created")[:50] .order_by("-created")
.select_related( .select_related(
"subject_post", "subject_post",
"subject_post__author", "subject_post__author",

View file

@ -1089,6 +1089,12 @@ table.metadata td .emoji {
margin-right: 4px; margin-right: 4px;
} }
.pagination {
display: flex;
justify-content: center;
gap: 1em;
}
.load-more { .load-more {
margin: 10px 0; margin: 10px 0;
text-align: center; text-align: center;

View file

@ -22,7 +22,7 @@ urlpatterns = [
path("explore/tags/", explore.ExploreTag.as_view(), name="explore-tag"), path("explore/tags/", explore.ExploreTag.as_view(), name="explore-tag"),
path( path(
"follows/", "follows/",
follows.FollowsPage.as_view(), follows.Follows.as_view(),
name="follows", name="follows",
), ),
# Settings views # Settings views

View file

@ -4,17 +4,17 @@
{% block content %} {% block content %}
<section class="icon-menu"> <section class="icon-menu">
{% for identity, details in identities %} {% for identity, follow_type in page_obj %}
<a class="option" href="{{ identity.urls.view }}"> <a class="option" href="{{ identity.urls.view }}">
<img src="{{ identity.local_icon_url.relative }}"> <img src="{{ identity.local_icon_url.relative }}">
<span class="handle"> <span class="handle">
{{ identity.html_name_or_handle }} {{ identity.html_name_or_handle }}
<small>@{{ identity.handle }}</small> <small>@{{ identity.handle }}</small>
</span> </span>
{% if details.outbound %} {% if follow_type == "outbound" %}
<span class="pill">Following</span> <span class="pill">Following</span>
{% endif %} {% endif %}
{% if details.inbound %} {% if follow_type == "inbound" %}
<span class="pill">Follows You</span> <span class="pill">Follows You</span>
{% endif %} {% endif %}
</a> </a>
@ -22,4 +22,14 @@
<p class="option empty">You have no follows.</p> <p class="option empty">You have no follows.</p>
{% endfor %} {% endfor %}
</section> </section>
<div class="pagination">
{% if page_obj.has_previous %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a></div>
{% endif %}
{% if page_obj.has_next %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
{% endif %}
</div>
{% endblock %} {% endblock %}

View file

@ -4,7 +4,7 @@
{% block title %}Home{% endblock %} {% block title %}Home{% endblock %}
{% block content %} {% block content %}
{% for event in events %} {% for event in page_obj %}
{% if event.type == "post" %} {% if event.type == "post" %}
{% include "activities/_post.html" with post=event.subject_post %} {% include "activities/_post.html" with post=event.subject_post %}
{% elif event.type == "boost" %} {% elif event.type == "boost" %}
@ -21,4 +21,14 @@
{% empty %} {% empty %}
Nothing to show yet. Nothing to show yet.
{% endfor %} {% endfor %}
<div class="pagination">
{% if page_obj.has_previous %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a></div>
{% endif %}
{% if page_obj.has_next %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
{% endif %}
</div>
{% endblock %} {% endblock %}

View file

@ -9,7 +9,13 @@
No posts yet. No posts yet.
{% endfor %} {% endfor %}
{% if page_obj.has_next %} <div class="pagination">
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div> {% if page_obj.has_previous %}
{% endif %} <div class="load-more"><a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a></div>
{% endif %}
{% if page_obj.has_next %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
{% endif %}
</div>
{% endblock %} {% endblock %}

View file

@ -32,7 +32,13 @@
No notifications yet. No notifications yet.
{% endfor %} {% endfor %}
{% if page_obj.has_next %} <div class="pagination">
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div> {% if page_obj.has_previous %}
{% endif %} <div class="load-more"><a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a></div>
{% endif %}
{% if page_obj.has_next %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
{% endif %}
</div>
{% endblock %} {% endblock %}

View file

@ -10,7 +10,13 @@
No posts yet. No posts yet.
{% endfor %} {% endfor %}
{% if page_obj.has_next %} <div class="pagination">
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div> {% if page_obj.has_previous %}
{% endif %} <div class="load-more"><a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a></div>
{% endif %}
{% if page_obj.has_next %}
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
{% endif %}
</div>
{% endblock %} {% endblock %}