Implement replies profile tab and boosts option
This commit is contained in:
parent
31c4f89124
commit
f5a3971ef8
|
@ -81,7 +81,12 @@ class TimelineService:
|
||||||
.order_by("-created")
|
.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
|
Returns timeline events with all of an identity's publicly visible posts
|
||||||
and their boosts
|
and their boosts
|
||||||
|
@ -99,6 +104,8 @@ class TimelineService:
|
||||||
filter = filter | models.Q(
|
filter = filter | models.Q(
|
||||||
type=TimelineEvent.Types.boost, subject_identity=identity
|
type=TimelineEvent.Types.boost, subject_identity=identity
|
||||||
)
|
)
|
||||||
|
if not include_replies:
|
||||||
|
filter = filter & models.Q(subject_post__in_reply_to__isnull=True)
|
||||||
return (
|
return (
|
||||||
self.event_queryset()
|
self.event_queryset()
|
||||||
.filter(
|
.filter(
|
||||||
|
|
|
@ -430,6 +430,6 @@ class Preferences(Schema):
|
||||||
"posting:default:sensitive": False,
|
"posting:default:sensitive": False,
|
||||||
"posting:default:language": None,
|
"posting:default:language": None,
|
||||||
"reading:expand:media": "default",
|
"reading:expand:media": "default",
|
||||||
"reading:expand:spoilers": identity.config_identity.expand_linked_cws,
|
"reading:expand:spoilers": identity.config_identity.expand_content_warnings,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -229,7 +229,6 @@ class Config(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
class SystemOptions(pydantic.BaseModel):
|
class SystemOptions(pydantic.BaseModel):
|
||||||
|
|
||||||
version: str = __version__
|
version: str = __version__
|
||||||
|
|
||||||
system_actor_public_key: str = ""
|
system_actor_public_key: str = ""
|
||||||
|
@ -280,18 +279,15 @@ class Config(models.Model):
|
||||||
light_theme: bool = False
|
light_theme: bool = False
|
||||||
|
|
||||||
class IdentityOptions(pydantic.BaseModel):
|
class IdentityOptions(pydantic.BaseModel):
|
||||||
|
|
||||||
toot_mode: bool = False
|
toot_mode: bool = False
|
||||||
default_post_visibility: int = 0 # Post.Visibilities.public
|
default_post_visibility: int = 0 # Post.Visibilities.public
|
||||||
visible_follows: bool = True
|
visible_follows: bool = True
|
||||||
search_enabled: bool = True
|
search_enabled: bool = True
|
||||||
|
|
||||||
# Wellness Options
|
|
||||||
visible_reaction_counts: bool = True
|
visible_reaction_counts: bool = True
|
||||||
expand_linked_cws: bool = True
|
expand_content_warnings: bool = False
|
||||||
|
boosts_on_profile: bool = True
|
||||||
|
|
||||||
class DomainOptions(pydantic.BaseModel):
|
class DomainOptions(pydantic.BaseModel):
|
||||||
|
|
||||||
site_name: str = ""
|
site_name: str = ""
|
||||||
site_icon: UploadedImage | None = None
|
site_icon: UploadedImage | None = None
|
||||||
hide_login: bool = False
|
hide_login: bool = False
|
||||||
|
|
|
@ -238,6 +238,7 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
# Identity views
|
# Identity views
|
||||||
path("@<handle>/", identity.ViewIdentity.as_view()),
|
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>/inbox/", activitypub.Inbox.as_view()),
|
||||||
path("@<handle>/outbox/", activitypub.Outbox.as_view()),
|
path("@<handle>/outbox/", activitypub.Outbox.as_view()),
|
||||||
path("@<handle>/collections/featured/", activitypub.FeaturedCollection.as_view()),
|
path("@<handle>/collections/featured/", activitypub.FeaturedCollection.as_view()),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<section class="view-options">
|
<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.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 %}
|
{% 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.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>
|
<a href="{{ identity.urls.followers }}" {% if inbound and section == "follows" %}class="selected"{% endif %}><strong>{{ followers_count }}</strong> Follower{{ followers_count|pluralize }}</a>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<legend>Appearance</legend>
|
<legend>Appearance</legend>
|
||||||
{% include "forms/_field.html" with field=form.icon %}
|
{% include "forms/_field.html" with field=form.icon %}
|
||||||
{% include "forms/_field.html" with field=form.image %}
|
{% 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>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
|
@ -231,6 +231,7 @@ class Identity(StatorModel):
|
||||||
|
|
||||||
class urls(urlman.Urls):
|
class urls(urlman.Urls):
|
||||||
view = "/@{self.username}@{self.domain_id}/"
|
view = "/@{self.username}@{self.domain_id}/"
|
||||||
|
replies = "{view}replies/"
|
||||||
settings = "{view}settings/"
|
settings = "{view}settings/"
|
||||||
action = "{view}action/"
|
action = "{view}action/"
|
||||||
followers = "{view}followers/"
|
followers = "{view}followers/"
|
||||||
|
|
|
@ -32,6 +32,7 @@ class ViewIdentity(ListView):
|
||||||
|
|
||||||
template_name = "identity/view.html"
|
template_name = "identity/view.html"
|
||||||
paginate_by = 25
|
paginate_by = 25
|
||||||
|
with_replies = False
|
||||||
|
|
||||||
def get(self, request, handle):
|
def get(self, request, handle):
|
||||||
# Make sure we understand this handle
|
# Make sure we understand this handle
|
||||||
|
@ -64,7 +65,11 @@ class ViewIdentity(ListView):
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_queryset(self):
|
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):
|
def get_context_data(self):
|
||||||
context = super().get_context_data()
|
context = super().get_context_data()
|
||||||
|
@ -72,6 +77,8 @@ class ViewIdentity(ListView):
|
||||||
context["public_styling"] = True
|
context["public_styling"] = True
|
||||||
context["post_count"] = self.identity.posts.count()
|
context["post_count"] = self.identity.posts.count()
|
||||||
context["pinned_posts"] = TimelineService(self.identity).identity_pinned()
|
context["pinned_posts"] = TimelineService(self.identity).identity_pinned()
|
||||||
|
if self.with_replies:
|
||||||
|
context["section"] = "replies"
|
||||||
if self.identity.config_identity.visible_follows:
|
if self.identity.config_identity.visible_follows:
|
||||||
context["followers_count"] = self.identity.inbound_follows.filter(
|
context["followers_count"] = self.identity.inbound_follows.filter(
|
||||||
state__in=FollowStates.group_active()
|
state__in=FollowStates.group_active()
|
||||||
|
|
|
@ -11,8 +11,12 @@ class PostingPage(SettingsPage):
|
||||||
"help_text": "Visibility to use as default for new posts.",
|
"help_text": "Visibility to use as default for new posts.",
|
||||||
"choices": Post.Visibilities.choices,
|
"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 = {
|
layout = {
|
||||||
"Posting": ["default_post_visibility"],
|
"Posting": ["default_post_visibility", "expand_content_warnings"],
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,11 @@ class ProfilePage(FormView):
|
||||||
widget=forms.Select(choices=[(True, "Enabled"), (False, "Disabled")]),
|
widget=forms.Select(choices=[(True, "Enabled"), (False, "Disabled")]),
|
||||||
required=False,
|
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(
|
metadata = forms.JSONField(
|
||||||
label="Profile Metadata Fields",
|
label="Profile Metadata Fields",
|
||||||
help_text="These values will appear on your profile below your bio",
|
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,
|
"visible_follows": self.identity.config_identity.visible_follows,
|
||||||
"metadata": self.identity.metadata or [],
|
"metadata": self.identity.metadata or [],
|
||||||
"search_enabled": self.identity.config_identity.search_enabled,
|
"search_enabled": self.identity.config_identity.search_enabled,
|
||||||
|
"boosts_on_profile": self.identity.config_identity.boosts_on_profile,
|
||||||
}
|
}
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
@ -125,6 +131,9 @@ class ProfilePage(FormView):
|
||||||
Config.set_identity(
|
Config.set_identity(
|
||||||
self.identity, "search_enabled", form.cleaned_data["search_enabled"]
|
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.")
|
messages.success(self.request, "Your profile has been updated.")
|
||||||
return redirect(".")
|
return redirect(".")
|
||||||
|
|
Loading…
Reference in New Issue