Several pagination improvements (#170)
Home/Notification gets pagination, Follows becomes ListView
This commit is contained in:
parent
45c6978bc3
commit
fb2eea956e
@ -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),
|
|
||||||
}
|
|
||||||
|
@ -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",
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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 %}
|
||||||
|
@ -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 %}
|
||||||
|
@ -9,7 +9,13 @@
|
|||||||
No posts yet.
|
No posts 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 %}
|
{% if page_obj.has_next %}
|
||||||
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -32,7 +32,13 @@
|
|||||||
No notifications yet.
|
No notifications 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 %}
|
{% if page_obj.has_next %}
|
||||||
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -10,7 +10,13 @@
|
|||||||
No posts yet.
|
No posts 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 %}
|
{% if page_obj.has_next %}
|
||||||
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
<div class="load-more"><a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Reference in New Issue
Block a user