summaryrefslogtreecommitdiffstats
path: root/activities
diff options
context:
space:
mode:
authorAndrew Godwin2022-11-17 18:52:00 -0700
committerAndrew Godwin2022-11-17 15:10:09 -0700
commit0851fbd1ec09b142608667bf90ee806e59cafb28 (patch)
treeeb4bfa7e52ef0a66460840747ea83b7685e1a5e8 /activities
parent2154e6f02252576d8652e66f26fa4ae635d0f8ee (diff)
downloadtakahe-0851fbd1ec09b142608667bf90ee806e59cafb28.tar.gz
takahe-0851fbd1ec09b142608667bf90ee806e59cafb28.tar.bz2
takahe-0851fbd1ec09b142608667bf90ee806e59cafb28.zip
Add search and better notifications
Diffstat (limited to 'activities')
-rw-r--r--activities/admin.py1
-rw-r--r--activities/models/fan_out.py2
-rw-r--r--activities/models/timeline_event.py3
-rw-r--r--activities/views/posts.py18
-rw-r--r--activities/views/search.py32
-rw-r--r--activities/views/timelines.py17
6 files changed, 67 insertions, 6 deletions
diff --git a/activities/admin.py b/activities/admin.py
index 371aa7b..e24304d 100644
--- a/activities/admin.py
+++ b/activities/admin.py
@@ -36,6 +36,7 @@ class PostAdmin(admin.ModelAdmin):
@admin.register(TimelineEvent)
class TimelineEventAdmin(admin.ModelAdmin):
list_display = ["id", "identity", "created", "type"]
+ readonly_fields = ["created"]
raw_id_fields = [
"identity",
"subject_post",
diff --git a/activities/models/fan_out.py b/activities/models/fan_out.py
index 771be19..6ebbe0a 100644
--- a/activities/models/fan_out.py
+++ b/activities/models/fan_out.py
@@ -37,7 +37,6 @@ class FanOutStates(StateGraph):
private_key=post.author.private_key,
key_id=post.author.public_key_id,
)
- return cls.sent
# Handle boosts/likes
elif fan_out.type == FanOut.Types.interaction:
interaction = await fan_out.subject_post_interaction.afetch_full()
@@ -74,6 +73,7 @@ class FanOutStates(StateGraph):
)
else:
raise ValueError(f"Cannot fan out with type {fan_out.type}")
+ return cls.sent
class FanOut(StatorModel):
diff --git a/activities/models/timeline_event.py b/activities/models/timeline_event.py
index 368fdad..cf93661 100644
--- a/activities/models/timeline_event.py
+++ b/activities/models/timeline_event.py
@@ -66,7 +66,7 @@ class TimelineEvent(models.Model):
"""
return cls.objects.get_or_create(
identity=identity,
- type=cls.Types.follow,
+ type=cls.Types.followed,
subject_identity=source_identity,
)[0]
@@ -90,6 +90,7 @@ class TimelineEvent(models.Model):
identity=identity,
type=cls.Types.mentioned,
subject_post=post,
+ subject_identity=post.author,
)[0]
@classmethod
diff --git a/activities/views/posts.py b/activities/views/posts.py
index 7b93e42..14da9ca 100644
--- a/activities/views/posts.py
+++ b/activities/views/posts.py
@@ -5,6 +5,7 @@ from django.utils.decorators import method_decorator
from django.views.generic import FormView, TemplateView, View
from activities.models import Post, PostInteraction, PostInteractionStates
+from core.models import Config
from users.decorators import identity_required
from users.shortcuts import by_handle_or_404
@@ -112,6 +113,7 @@ class Compose(FormView):
template_name = "activities/compose.html"
class form_class(forms.Form):
+
text = forms.CharField(
widget=forms.Textarea(
attrs={
@@ -137,6 +139,22 @@ class Compose(FormView):
help_text="Optional - Post will be hidden behind this text until clicked",
)
+ def clean_text(self):
+ text = self.cleaned_data.get("text")
+ if not text:
+ return text
+ length = len(text)
+ if length > Config.system.post_length:
+ raise forms.ValidationError(
+ f"Maximum post length is {Config.system.post_length} characters (you have {length})"
+ )
+ return text
+
+ def get_form_class(self):
+ form = super().get_form_class()
+ form.declared_fields["text"]
+ return form
+
def form_valid(self, form):
Post.create_local(
author=self.request.identity,
diff --git a/activities/views/search.py b/activities/views/search.py
new file mode 100644
index 0000000..b748348
--- /dev/null
+++ b/activities/views/search.py
@@ -0,0 +1,32 @@
+from django import forms
+from django.views.generic import FormView
+
+from users.models import Identity
+
+
+class Search(FormView):
+
+ template_name = "activities/search.html"
+
+ class form_class(forms.Form):
+ query = forms.CharField()
+
+ def form_valid(self, form):
+ query = form.cleaned_data["query"].lstrip("@").lower()
+ results = {"identities": set()}
+ # Search identities
+ if "@" in query:
+ username, domain = query.split("@", 1)
+ for identity in Identity.objects.filter(
+ domain_id=domain, username=username
+ )[:20]:
+ results["identities"].add(identity)
+ else:
+ for identity in Identity.objects.filter(username=query)[:20]:
+ results["identities"].add(identity)
+ for identity in Identity.objects.filter(username__startswith=query)[:20]:
+ results["identities"].add(identity)
+ # Render results
+ context = self.get_context_data(form=form)
+ context["results"] = results
+ return self.render_to_response(context)
diff --git a/activities/views/timelines.py b/activities/views/timelines.py
index 02afc2c..38f9331 100644
--- a/activities/views/timelines.py
+++ b/activities/views/timelines.py
@@ -98,9 +98,18 @@ class Notifications(TemplateView):
def get_context_data(self):
context = super().get_context_data()
- context["events"] = TimelineEvent.objects.filter(
- identity=self.request.identity,
- type__in=[TimelineEvent.Types.mentioned, TimelineEvent.Types.boosted],
- ).select_related("subject_post", "subject_post__author", "subject_identity")
+ context["events"] = (
+ TimelineEvent.objects.filter(
+ identity=self.request.identity,
+ type__in=[
+ TimelineEvent.Types.mentioned,
+ TimelineEvent.Types.boosted,
+ TimelineEvent.Types.liked,
+ TimelineEvent.Types.followed,
+ ],
+ )
+ .order_by("-created")[:50]
+ .select_related("subject_post", "subject_post__author", "subject_identity")
+ )
context["current_page"] = "notifications"
return context