pull/3/head
Andrew Godwin 2022-11-17 20:04:01 -07:00
rodzic adf2449d37
commit b3072c81ba
8 zmienionych plików z 125 dodań i 16 usunięć

Wyświetl plik

@ -335,6 +335,18 @@ nav a i {
font-size: 200%;
}
.icon-menu .option .handle {
margin-right: 20px;
}
.icon-menu .option .pill {
display: inline-block;
padding: 5px 8px;
background: var(--color-highlight);
border-radius: 5px;
margin: 0 5px 0 5px;
}
.handle {
vertical-align: middle;
display: inline-block;
@ -375,6 +387,20 @@ form.follow {
float: right;
margin: 20px 0 0 0;
font-size: 16px;
text-align: center;
}
form.follow.has-reverse {
margin-top: 0;
}
form.follow .reverse-follow {
display: block;
margin: 0 0 5px 0;
}
form.follow button {
margin: 0;
}
form h1 {

Wyświetl plik

@ -6,7 +6,7 @@ from django.views.static import serve
from activities.views import posts, search, timelines
from core import views as core
from stator import views as stator
from users.views import activitypub, admin, auth, identity, settings
from users.views import activitypub, admin, auth, follows, identity, settings
urlpatterns = [
path("", core.homepage),
@ -31,6 +31,11 @@ urlpatterns = [
settings.ProfilePage.as_view(),
name="settings_profile",
),
path(
"settings/follows/",
follows.FollowsPage.as_view(),
name="settings_follows",
),
path(
"settings/interface/",
settings.InterfacePage.as_view(),

Wyświetl plik

@ -13,16 +13,25 @@
<img src="{{ identity.local_icon_url }}" class="icon">
{% if request.identity %}
<form action="{{ identity.urls.action }}" method="POST" class="inline follow">
{% csrf_token %}
{% if follow %}
<input type="hidden" name="action" value="unfollow">
<button>Unfollow</button>
{% else %}
<input type="hidden" name="action" value="follow">
<button>Follow</button>
{% endif %}
</form>
{% if identity == request.identity %}
<form class="inline follow">
<a class="button" href="{% url "settings_profile" %}">Edit Profile</a>
</form>
{% else %}
<form action="{{ identity.urls.action }}" method="POST" class="inline follow {% if reverse_follow %}has-reverse{% endif %}">
{% csrf_token %}
{% if reverse_follow %}
<span class="reverse-follow">Follows You</span>
{% endif %}
{% if follow %}
<input type="hidden" name="action" value="unfollow">
<button>Unfollow</button>
{% else %}
<input type="hidden" name="action" value="follow">
<button>Follow</button>
{% endif %}
</form>
{% endif %}
{% endif %}
{{ identity.name_or_handle }} <small>@{{ identity.handle }}</small>

Wyświetl plik

@ -6,6 +6,9 @@
<a href="{% url "settings_interface" %}" {% if section == "interface" %}class="selected"{% endif %}>
<i class="fa-solid fa-display"></i> Interface
</a>
<a href="{% url "settings_follows" %}" {% if section == "follows" %}class="selected"{% endif %}>
<i class="fa-solid fa-arrow-right-arrow-left"></i> Follows
</a>
{% if request.user.admin %}
<h3>Account</h3>
<a href="{% url "settings_security" %}" {% if section == "security" %}class="selected"{% endif %}>

Wyświetl plik

@ -0,0 +1,25 @@
{% extends "settings/base.html" %}
{% block subtitle %}Follows{% endblock %}
{% block content %}
<section class="icon-menu">
{% for identity, details in identities %}
<a class="option" href="{{ identity.urls.view }}">
<img src="{{ identity.local_icon_url }}">
<span class="handle">
{{ identity.name_or_handle }}
<small>@{{ identity.handle }}</small>
</span>
{% if details.outbound %}
<span class="pill">Following</span>
{% endif %}
{% if details.inbound %}
<span class="pill">Follows You</span>
{% endif %}
</a>
{% empty %}
<p class="option empty">You have no follows.</p>
{% endfor %}
</section>
{% endblock %}

Wyświetl plik

@ -23,6 +23,10 @@ class FollowStates(StateGraph):
accepted.transitions_to(undone)
undone.transitions_to(undone_remotely)
@classmethod
def group_active(cls):
return [cls.unrequested, cls.local_requested, cls.accepted]
@classmethod
async def handle_unrequested(cls, instance: "Follow"):
"""

Wyświetl plik

@ -0,0 +1,33 @@
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
from users.decorators import identity_required
from users.models import FollowStates
@method_decorator(identity_required, name="dispatch")
class FollowsPage(TemplateView):
"""
Shows followers/follows.
"""
template_name = "settings/follows.html"
def get_context_data(self):
# Gather all identities with a following relationship with us
identities = {}
for outbound_follow in self.request.identity.outbound_follows.filter(
state__in=FollowStates.group_active()
):
identities.setdefault(outbound_follow.target, {})[
"outbound"
] = outbound_follow
for inbound_follow in self.request.identity.inbound_follows.filter(
state__in=FollowStates.group_active()
):
identities.setdefault(inbound_follow.source, {})["inbound"] = inbound_follow
return {
"section": "follows",
"identities": sorted(identities.items(), key=lambda i: i[0].username),
}

Wyświetl plik

@ -28,18 +28,22 @@ class ViewIdentity(TemplateView):
if identity.data_age > Config.system.identity_max_age:
identity.transition_perform(IdentityStates.outdated)
follow = None
reverse_follow = None
if self.request.identity:
follow = Follow.maybe_get(self.request.identity, identity)
if follow and follow.state not in [
FollowStates.unrequested,
FollowStates.local_requested,
FollowStates.accepted,
]:
if follow and follow.state not in FollowStates.group_active():
follow = None
reverse_follow = Follow.maybe_get(identity, self.request.identity)
if (
reverse_follow
and reverse_follow.state not in FollowStates.group_active()
):
reverse_follow = None
return {
"identity": identity,
"posts": posts,
"follow": follow,
"reverse_follow": reverse_follow,
}