Implement replies profile tab and boosts option

This commit is contained in:
Andrew Godwin 2023-05-13 11:07:57 -06:00
parent 31c4f89124
commit f5a3971ef8
10 changed files with 37 additions and 11 deletions

View file

@ -81,7 +81,12 @@ class TimelineService:
.order_by("-created")
)
def identity_public(self, identity: Identity, include_boosts: bool = True):
def identity_public(
self,
identity: Identity,
include_boosts: bool = True,
include_replies: bool = True,
):
"""
Returns timeline events with all of an identity's publicly visible posts
and their boosts
@ -99,6 +104,8 @@ class TimelineService:
filter = filter | models.Q(
type=TimelineEvent.Types.boost, subject_identity=identity
)
if not include_replies:
filter = filter & models.Q(subject_post__in_reply_to__isnull=True)
return (
self.event_queryset()
.filter(

View file

@ -430,6 +430,6 @@ class Preferences(Schema):
"posting:default:sensitive": False,
"posting:default:language": None,
"reading:expand:media": "default",
"reading:expand:spoilers": identity.config_identity.expand_linked_cws,
"reading:expand:spoilers": identity.config_identity.expand_content_warnings,
}
)

View file

@ -229,7 +229,6 @@ class Config(models.Model):
)
class SystemOptions(pydantic.BaseModel):
version: str = __version__
system_actor_public_key: str = ""
@ -280,18 +279,15 @@ class Config(models.Model):
light_theme: bool = False
class IdentityOptions(pydantic.BaseModel):
toot_mode: bool = False
default_post_visibility: int = 0 # Post.Visibilities.public
visible_follows: bool = True
search_enabled: bool = True
# Wellness Options
visible_reaction_counts: bool = True
expand_linked_cws: bool = True
expand_content_warnings: bool = False
boosts_on_profile: bool = True
class DomainOptions(pydantic.BaseModel):
site_name: str = ""
site_icon: UploadedImage | None = None
hide_login: bool = False

View file

@ -238,6 +238,7 @@ urlpatterns = [
),
# Identity views
path("@<handle>/", identity.ViewIdentity.as_view()),
path("@<handle>/replies/", identity.ViewIdentity.as_view(with_replies=True)),
path("@<handle>/inbox/", activitypub.Inbox.as_view()),
path("@<handle>/outbox/", activitypub.Outbox.as_view()),
path("@<handle>/collections/featured/", activitypub.FeaturedCollection.as_view()),

View file

@ -1,5 +1,6 @@
<section class="view-options">
<a href="{{ identity.urls.view }}" {% if not section %}class="selected"{% endif %}><strong>{{ post_count }}</strong> Posts</a>
<a href="{{ identity.urls.replies }}" {% if section == "replies" %}class="selected"{% endif %}>Posts & Replies</a>
{% if identity.local and identity.config_identity.visible_follows %}
<a href="{{ identity.urls.following }}" {% if not inbound and section == "follows" %}class="selected"{% endif %}><strong>{{ following_count }}</strong> Following</a>
<a href="{{ identity.urls.followers }}" {% if inbound and section == "follows" %}class="selected"{% endif %}><strong>{{ followers_count }}</strong> Follower{{ followers_count|pluralize }}</a>

View file

@ -18,7 +18,7 @@
<legend>Appearance</legend>
{% include "forms/_field.html" with field=form.icon %}
{% include "forms/_field.html" with field=form.image %}
{% include "forms/_field.html" with field=form.theme %}
{% include "forms/_field.html" with field=form.boosts_on_profile %}
</fieldset>
<fieldset>

View file

@ -231,6 +231,7 @@ class Identity(StatorModel):
class urls(urlman.Urls):
view = "/@{self.username}@{self.domain_id}/"
replies = "{view}replies/"
settings = "{view}settings/"
action = "{view}action/"
followers = "{view}followers/"

View file

@ -32,6 +32,7 @@ class ViewIdentity(ListView):
template_name = "identity/view.html"
paginate_by = 25
with_replies = False
def get(self, request, handle):
# Make sure we understand this handle
@ -64,7 +65,11 @@ class ViewIdentity(ListView):
)
def get_queryset(self):
return TimelineService(None).identity_public(self.identity)
return TimelineService(None).identity_public(
self.identity,
include_boosts=self.identity.config_identity.boosts_on_profile,
include_replies=self.with_replies,
)
def get_context_data(self):
context = super().get_context_data()
@ -72,6 +77,8 @@ class ViewIdentity(ListView):
context["public_styling"] = True
context["post_count"] = self.identity.posts.count()
context["pinned_posts"] = TimelineService(self.identity).identity_pinned()
if self.with_replies:
context["section"] = "replies"
if self.identity.config_identity.visible_follows:
context["followers_count"] = self.identity.inbound_follows.filter(
state__in=FollowStates.group_active()

View file

@ -11,8 +11,12 @@ class PostingPage(SettingsPage):
"help_text": "Visibility to use as default for new posts.",
"choices": Post.Visibilities.choices,
},
"expand_content_warnings": {
"title": "Expand content warnings",
"help_text": "If content warnings should be expanded by default (not honoured by all clients)",
},
}
layout = {
"Posting": ["default_post_visibility"],
"Posting": ["default_post_visibility", "expand_content_warnings"],
}

View file

@ -53,6 +53,11 @@ class ProfilePage(FormView):
widget=forms.Select(choices=[(True, "Enabled"), (False, "Disabled")]),
required=False,
)
boosts_on_profile = forms.BooleanField(
help_text="Include your boosts with your posts on your profile page",
widget=forms.Select(choices=[(True, "Enabled"), (False, "Disabled")]),
required=False,
)
metadata = forms.JSONField(
label="Profile Metadata Fields",
help_text="These values will appear on your profile below your bio",
@ -91,6 +96,7 @@ class ProfilePage(FormView):
"visible_follows": self.identity.config_identity.visible_follows,
"metadata": self.identity.metadata or [],
"search_enabled": self.identity.config_identity.search_enabled,
"boosts_on_profile": self.identity.config_identity.boosts_on_profile,
}
def form_valid(self, form):
@ -125,6 +131,9 @@ class ProfilePage(FormView):
Config.set_identity(
self.identity, "search_enabled", form.cleaned_data["search_enabled"]
)
Config.set_identity(
self.identity, "boosts_on_profile", form.cleaned_data["boosts_on_profile"]
)
messages.success(self.request, "Your profile has been updated.")
return redirect(".")