From 20e63023bb0d3c7e4cb36b91b73e79f51889cc90 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Tue, 15 Nov 2022 18:30:30 -0700 Subject: Get outbound likes/boosts and their undos working --- activities/views/posts.py | 102 ++++++++++++++++++++++++++++++++++++++++++ activities/views/timelines.py | 8 ++-- 2 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 activities/views/posts.py (limited to 'activities/views') diff --git a/activities/views/posts.py b/activities/views/posts.py new file mode 100644 index 0000000..ece7cf3 --- /dev/null +++ b/activities/views/posts.py @@ -0,0 +1,102 @@ +from django.shortcuts import get_object_or_404, redirect, render +from django.utils.decorators import method_decorator +from django.views.generic import TemplateView, View + +from activities.models import PostInteraction, PostInteractionStates +from users.decorators import identity_required +from users.shortcuts import by_handle_or_404 + + +class Post(TemplateView): + + template_name = "activities/post.html" + + def get_context_data(self, handle, post_id): + identity = by_handle_or_404(self.request, handle, local=False) + post = get_object_or_404(identity.posts, pk=post_id) + return { + "identity": identity, + "post": post, + "interactions": PostInteraction.get_post_interactions( + [post], + self.request.identity, + ), + } + + +@method_decorator(identity_required, name="dispatch") +class Like(View): + """ + Adds/removes a like from the current identity to the post + """ + + undo = False + + def post(self, request, handle, post_id): + identity = by_handle_or_404(self.request, handle, local=False) + post = get_object_or_404(identity.posts, pk=post_id) + if self.undo: + # Undo any likes on the post + for interaction in PostInteraction.objects.filter( + type=PostInteraction.Types.like, + identity=request.identity, + post=post, + ): + interaction.transition_perform(PostInteractionStates.undone) + else: + # Make a like on this post if we didn't already + PostInteraction.objects.get_or_create( + type=PostInteraction.Types.like, + identity=request.identity, + post=post, + ) + # Return either a redirect or a HTMX snippet + if request.htmx: + return render( + request, + "activities/_like.html", + { + "post": post, + "interactions": {"like": set() if self.undo else {post.pk}}, + }, + ) + return redirect(post.urls.view) + + +@method_decorator(identity_required, name="dispatch") +class Boost(View): + """ + Adds/removes a boost from the current identity to the post + """ + + undo = False + + def post(self, request, handle, post_id): + identity = by_handle_or_404(self.request, handle, local=False) + post = get_object_or_404(identity.posts, pk=post_id) + if self.undo: + # Undo any boosts on the post + for interaction in PostInteraction.objects.filter( + type=PostInteraction.Types.boost, + identity=request.identity, + post=post, + ): + interaction.transition_perform(PostInteractionStates.undone) + else: + # Make a boost on this post if we didn't already + PostInteraction.objects.get_or_create( + type=PostInteraction.Types.boost, + identity=request.identity, + post=post, + ) + # Return either a redirect or a HTMX snippet + if request.htmx: + return render( + request, + "activities/_boost.html", + { + "post": post, + "interactions": {"boost": set() if self.undo else {post.pk}}, + }, + ) + return redirect(post.urls.view) diff --git a/activities/views/timelines.py b/activities/views/timelines.py index 9be988d..c59c3b6 100644 --- a/activities/views/timelines.py +++ b/activities/views/timelines.py @@ -4,7 +4,7 @@ from django.template.defaultfilters import linebreaks_filter from django.utils.decorators import method_decorator from django.views.generic import FormView, TemplateView -from activities.models import Post, TimelineEvent +from activities.models import Post, PostInteraction, TimelineEvent from users.decorators import identity_required @@ -33,7 +33,7 @@ class Home(FormView): def get_context_data(self): context = super().get_context_data() - context["events"] = ( + context["events"] = list( TimelineEvent.objects.filter( identity=self.request.identity, type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost], @@ -41,7 +41,9 @@ class Home(FormView): .select_related("subject_post", "subject_post__author") .order_by("-created")[:100] ) - + context["interactions"] = PostInteraction.get_event_interactions( + context["events"], self.request.identity + ) context["current_page"] = "home" return context -- cgit v1.2.3