Adds "suggested follows" panel

This commit is contained in:
Mouse Reeve 2021-03-26 10:32:42 -07:00
parent c00558bda6
commit b0e1095fe6
4 changed files with 53 additions and 7 deletions

View file

@ -15,6 +15,11 @@ html {
overflow: visible; overflow: visible;
} }
.scroll-x {
overflow: hidden;
overflow-x: auto;
}
/* --- SHELVING --- */ /* --- SHELVING --- */
.shelf-option:disabled > *::after { .shelf-option:disabled > *::after {
font-family: "icomoon"; font-family: "icomoon";

View file

@ -1,6 +1,7 @@
{% extends 'feed/feed_layout.html' %} {% extends 'feed/feed_layout.html' %}
{% load i18n %} {% load i18n %}
{% load bookwyrm_tags %} {% load bookwyrm_tags %}
{% load humanize %}
{% block panel %} {% block panel %}
<h1 class="title"> <h1 class="title">
@ -48,6 +49,32 @@
{% endif %} {% endif %}
{% for activity in activities %} {% for activity in activities %}
{% if not activities.number > 1 and forloop.counter0 == 2 and suggested_users %}
{# suggested users on the first page, two statuses down #}
<section class="block">
<h2 class="title is-5">{% trans "Who to follow" %}</h2>
<div class="columns is-mobile is-gapless scroll-x">
{% for user in suggested_users %}
<div class="column is-flex">
<div class="box has-text-centered is-shadowless has-background-white-bis">
<a href="{{ user.local_path }}" class="has-text-black">
{% include 'snippets/avatar.html' with user=user large=True %}
<span title="{{ user.display_name }}" class="is-block is-6 has-text-weight-bold">{{ user.display_name|truncatechars:10 }}</span>
<span title="@{{ user|username }}" class="is-block pb-3">@{{ user|username|truncatechars:8 }}</span>
</a>
{% include 'snippets/follow_button.html' with user=user minimal=True %}
{% if user.mutuals %}
<p class="help">
{% blocktrans with mutuals=user.mutuals|intcomma count counter=user.mutuals %}{{ mutuals }} follower you follow{% plural %}{{ mutuals }} followers you follow{% endblocktrans %}
</p>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</section>
{% endif %}
<div class="block"> <div class="block">
{% include 'snippets/status/status.html' with status=activity %} {% include 'snippets/status/status.html' with status=activity %}
</div> </div>

View file

@ -4,16 +4,12 @@
{% include 'snippets/block_button.html' %} {% include 'snippets/block_button.html' %}
{% else %} {% else %}
<div class="field has-addons"> <div class="field{% if not minimal %} has-addons{% else %} mb-0{% endif %}">
<div class="control"> <div class="control">
<form action="{% url 'follow' %}" method="POST" class="interaction follow-{{ user.id }} {% if request.user in user.followers.all or request.user in user.follower_requests.all %}hidden{%endif %}" data-id="follow-{{ user.id }}"> <form action="{% url 'follow' %}" method="POST" class="interaction follow-{{ user.id }} {% if request.user in user.followers.all or request.user in user.follower_requests.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ user.username }}"> <input type="hidden" name="user" value="{{ user.username }}">
{% if user.manually_approves_followers %} <button class="button is-small{% if not minimal %} is-link{% endif %}" type="submit">{% trans "Follow" %}</button>
<button class="button is-small is-link" type="submit">{% trans "Send follow request" %}</button>
{% else %}
<button class="button is-small is-link" type="submit">{% trans "Follow" %}</button>
{% endif %}
</form> </form>
<form action="{% url 'unfollow' %}" method="POST" class="interaction follow-{{ user.id }} {% if not request.user in user.followers.all and not request.user in user.follower_requests.all %}hidden{%endif %}" data-id="follow-{{ user.id }}"> <form action="{% url 'unfollow' %}" method="POST" class="interaction follow-{{ user.id }} {% if not request.user in user.followers.all and not request.user in user.follower_requests.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
{% csrf_token %} {% csrf_token %}
@ -25,8 +21,10 @@
{% endif %} {% endif %}
</form> </form>
</div> </div>
{% if not minimal %}
<div class="control"> <div class="control">
{% include 'snippets/user_options.html' with user=user class="is-small" %} {% include 'snippets/user_options.html' with user=user class="is-small" %}
</div> </div>
{% endif %}
</div> </div>
{% endif %} {% endif %}

View file

@ -1,7 +1,7 @@
""" non-interactive pages """ """ non-interactive pages """
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models import Q from django.db.models import Count, Q
from django.http import HttpResponseNotFound from django.http import HttpResponseNotFound
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils import timezone from django.utils import timezone
@ -34,11 +34,27 @@ class Feed(View):
paginated = Paginator(activities, PAGE_LENGTH) paginated = Paginator(activities, PAGE_LENGTH)
suggested_users = models.User.objects.filter(
~Q(id__in=request.user.following.all()),
~Q(id=request.user.id),
discoverable=True,
is_active=True,
bookwyrm_user=True,
).annotate(
mutuals=Count(
"following",
filter=Q(
following__in=request.user.following.all()
),
)
).order_by("-mutuals", "-last_active_date").all()[:5]
data = { data = {
**feed_page_data(request.user), **feed_page_data(request.user),
**{ **{
"user": request.user, "user": request.user,
"activities": paginated.page(page), "activities": paginated.page(page),
"suggested_users": suggested_users,
"tab": tab, "tab": tab,
"goal_form": forms.GoalForm(), "goal_form": forms.GoalForm(),
"path": "/%s" % tab, "path": "/%s" % tab,