Merge branch 'main' into list-not-loading

This commit is contained in:
Mouse Reeve
2022-01-05 16:33:05 -08:00
committed by GitHub
32 changed files with 5312 additions and 818 deletions

View File

@ -0,0 +1,34 @@
# Generated by Django 3.2.5 on 2022-01-04 22:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0122_alter_annualgoal_year"),
]
operations = [
migrations.AlterField(
model_name="user",
name="preferred_language",
field=models.CharField(
blank=True,
choices=[
("en-us", "English"),
("de-de", "Deutsch (German)"),
("es-es", "Español (Spanish)"),
("gl-es", "Galego (Galician)"),
("fr-fr", "Français (French)"),
("lt-lt", "Lietuvių (Lithuanian)"),
("pt-br", "Português do Brasil (Brazilian Portuguese)"),
("pt-pt", "Português Europeu (European Portuguese)"),
("zh-hans", "简体中文 (Simplified Chinese)"),
("zh-hant", "繁體中文 (Traditional Chinese)"),
],
max_length=255,
null=True,
),
),
]

View File

@ -168,7 +168,8 @@ LANGUAGES = [
("gl-es", _("Galego (Galician)")),
("fr-fr", _("Français (French)")),
("lt-lt", _("Lietuvių (Lithuanian)")),
("pt-br", _("Português - Brasil (Brazilian Portuguese)")),
("pt-br", _("Português do Brasil (Brazilian Portuguese)")),
("pt-pt", _("Português Europeu (European Portuguese)")),
("zh-hans", _("简体中文 (Simplified Chinese)")),
("zh-hant", _("繁體中文 (Traditional Chinese)")),
]

View File

@ -3,7 +3,7 @@ import math
import logging
from django.dispatch import receiver
from django.db import transaction
from django.db.models import signals, Count, Q
from django.db.models import signals, Count, Q, Case, When, IntegerField
from bookwyrm import models
from bookwyrm.redis_store import RedisStore, r
@ -85,24 +85,17 @@ class SuggestedUsers(RedisStore):
def get_suggestions(self, user, local=False):
"""get suggestions"""
values = self.get_store(self.store_id(user), withscores=True)
results = []
annotations = [
When(pk=int(pk), then=self.get_counts_from_rank(score)["mutuals"])
for (pk, score) in values
]
# annotate users with mutuals and shared book counts
for user_id, rank in values:
counts = self.get_counts_from_rank(rank)
try:
user = models.User.objects.get(
id=user_id, is_active=True, bookwyrm_user=True
)
except models.User.DoesNotExist as err:
# if this happens, the suggestions are janked way up
logger.exception(err)
continue
user.mutuals = counts["mutuals"]
if (local and user.local) or not local:
results.append(user)
if len(results) >= 5:
break
return results
users = models.User.objects.filter(
is_active=True, bookwyrm_user=True, id__in=[pk for (pk, _) in values]
).annotate(mutuals=Case(*annotations, output_field=IntegerField(), default=0))
if local:
users = users.filter(local=True)
return users[:5]
def get_annotated_users(viewer, *args, **kwargs):

View File

@ -2,8 +2,5 @@
{% load i18n %}
{% block searchresults %}
<h2 class="title is-5">
{% trans "Add new members!" %}
</h2>
{% include 'groups/suggested_users.html' with suggested_users=suggested_users %}
{% endblock %}

View File

@ -5,11 +5,11 @@
<div class="column is-two-thirds">
<input type="hidden" name="user" value="{{ request.user.id }}" />
<div class="field">
<label class="label" for="id_name">{% trans "Group Name:" %}</label>
<label class="label" for="group_form_id_name">{% trans "Group Name:" %}</label>
{{ group_form.name }}
</div>
<div class="field">
<label class="label" for="id_description">{% trans "Group Description:" %}</label>
<label class="label" for="group_form_id_description">{% trans "Group Description:" %}</label>
{{ group_form.description }}
</div>
</div>

View File

@ -1,37 +1,41 @@
{% extends 'groups/layout.html' %}
{% load i18n %}
{% load bookwyrm_tags %}
{% load bookwyrm_group_tags %}
{% load markdown %}
{% block panel %}
<div class="columns mt-3">
<section class="column is-three-quarters">
{% if group.user == request.user %}
<div class="block">
<form class="field has-addons" method="get" action="{% url 'group-find-users' group.id %}">
<div class="control">
<input type="text" name="user_query" value="{{ request.GET.user_query }}" class="input" placeholder="{% trans 'Search to add a user' %}" aria-label="{% trans 'Search to add a user' %}">
</div>
<div class="control">
<button class="button" type="submit">
<span class="icon icon-search" title="{% trans 'Search' %}">
<span class="is-sr-only">{% trans "Search" %}</span>
</span>
</button>
</div>
</form>
</div>
{% endif %}
{% block searchresults %}
{% endblock %}
<div class="mb-2">
{% include "groups/members.html" with group=group %}
</div>
<h2 class="title is-5">Lists</h2>
</section>
</div>
<header class="columns content is-mobile">
<div class="column">
<h2 class="title is-5">{% trans "Lists" %}</h2>
<p class="subtitle is-6">
{% trans "Members of this group can create group-curated lists." %}
</p>
</div>
{% if request.user.is_authenticated and group|is_member:request.user %}
<div class="column is-narrow is-flex">
{% trans "Create List" as button_text %}
{% include 'snippets/toggle/open_button.html' with controls_text="create_list" icon_with_text="plus" text=button_text focus="create_list_header" %}
</div>
{% endif %}
</header>
{% if request.user.is_authenticated and group|is_member:request.user %}
<div class="block">
{% include 'lists/create_form.html' with controls_text="create_list" curation_group=group %}
</div>
{% endif %}
<div class="columns mt-3">
<section class="column is-three-quarters">
{% if not lists %}
<p>{% trans "This group has no lists" %}</p>
{% else %}
@ -45,19 +49,17 @@
<a href="{{ list.local_path }}">{{ list.name }}</a> <span class="subtitle">{% include 'snippets/privacy-icons.html' with item=list %}</span>
</h4>
</header>
{% with list_books=list.listitem_set.all|slice:5 %}
{% if list_books %}
<div class="card-image columns is-mobile is-gapless is-clipped">
{% for book in list_books %}
<a class="column is-cover" href="{{ book.book.local_path }}">
{% include 'snippets/book_cover.html' with book=book.book cover_class='is-h-s' size='small' aria='show' %}
</a>
{% endfor %}
</div>
{% endif %}
{% if list_books %}
<div class="card-image columns is-mobile is-gapless is-clipped">
{% for book in list_books %}
<a class="column is-cover" href="{{ book.book.local_path }}">
{% include 'snippets/book_cover.html' with book=book.book cover_class='is-h-s' size='small' aria='show' %}
</a>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<div class="card-content is-flex-grow-0">
<div class="is-clipped" {% if list.description %}title="{{ list.description }}"{% endif %}>
{% if list.description %}
@ -74,9 +76,8 @@
</div>
{% endfor %}
</div>
{% endif %}
{% include "snippets/pagination.html" with page=items %}
</section>
</div>
{% endblock %}

View File

@ -1,5 +1,6 @@
{% extends 'layout.html' %}
{% load i18n %}
{% load bookwyrm_group_tags %}
{% block title %}{{ group.name }}{% endblock %}
@ -11,12 +12,12 @@
{% include 'groups/created_text.html' with group=group %}
</p>
</div>
{% if request.user == group.user %}
<div class="column is-narrow is-flex">
{% if request.user == group.user %}
{% trans "Edit group" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_group" focus="edit_group_header" %}
{% endif %}
{% trans "Edit group" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_group" focus="edit_group_header" %}
</div>
{% endif %}
</header>
<div class="block content">

View File

@ -5,8 +5,22 @@
{% load bookwyrm_group_tags %}
<h2 class="title is-5">Group Members</h2>
<p class="subtitle is-6">{% trans "Members can add and remove books on a group's book lists" %}</p>
{% if group.user == request.user %}
<div class="block">
<form class="field has-addons" method="get" action="{% url 'group-find-users' group.id %}">
<div class="control">
<input type="text" name="user_query" value="{{ request.GET.user_query }}" class="input" placeholder="{% trans 'Search to add a user' %}" aria-label="{% trans 'Search to add a user' %}">
</div>
<div class="control">
<button class="button" type="submit">
<span class="icon icon-search" title="{% trans 'Search' %}">
<span class="is-sr-only">{% trans "Search" %}</span>
</span>
</button>
</div>
</form>
</div>
{% endif %}
{% if group.user != request.user and group|is_member:request.user %}
<form action="{% url 'remove-group-member' %}" method="POST" class="my-4">
{% csrf_token %}

View File

@ -3,6 +3,9 @@
{% load humanize %}
{% if suggested_users %}
<h2 class="title is-5">
{% trans "Add new members!" %}
</h2>
<div class="column is-flex is-flex-grow-0">
{% for user in suggested_users %}
<div class="box has-text-centered is-shadowless has-background-white-bis m-2">

View File

@ -7,6 +7,6 @@
{% block form %}
<form name="create-list" method="post" action="{% url 'lists' %}">
{% include 'lists/form.html' %}
{% include 'lists/form.html' with curation_group=group %}
</form>
{% endblock %}

View File

@ -25,7 +25,7 @@
value="closed"
aria-described-by="id_curation_closed_help"
id="id_curation_closed"
{% if not list or list.curation == 'closed' %} checked{% endif %}
{% if not curation_group.exists or not list or list.curation == 'closed' %}checked{% endif %}
>
<label for="id_curation_closed">
{% trans "Closed" %}
@ -76,7 +76,7 @@
value="group"
aria-described-by="id_curation_group_help"
id="id_curation_group"
{% if list.curation == 'group' %}checked{% endif %}
{% if curation_group.id or list.curation == 'group' %}checked{% endif %}
>
<label for="id_curation_group">
{% trans "Group" %}
@ -85,15 +85,15 @@
{% trans "Group members can add to and remove from this list" %}
</p>
<fieldset class="{% if list.curation != 'group' %}is-hidden{% endif %}" id="list_group_selector">
<fieldset class="{% if list.curation != 'group' and not curation_group %}is-hidden{% endif %}" id="list_group_selector">
{% if user.memberships.exists %}
<label class="label" for="id_group" id="group">{% trans "Select Group" %}</label>
<div class="field has-addons">
<div class="select control">
<select name="group" id="id_group">
<option value="" disabled {% if not list.group %} selected{% endif %}>{% trans "Select a group" %}</option>
<option value="" disabled {% if not list.group and not curation_group %} selected{% endif %}>{% trans "Select a group" %}</option>
{% for membership in user.memberships.all %}
<option value="{{ membership.group.id }}" {% if list.group.id == membership.group.id %} selected{% endif %}>{{ membership.group.name }}</option>
<option value="{{ membership.group.id }}" {% if list.group.id == membership.group.id or curation_group.id == membership.group.id %} selected{% endif %}>{{ membership.group.name }}</option>
{% endfor %}
</select>
</div>

View File

@ -34,7 +34,8 @@ class Group(View):
data = {
"group": group,
"lists": lists,
"group_form": forms.GroupForm(instance=group),
"group_form": forms.GroupForm(instance=group, auto_id="group_form_id_%s"),
"list_form": forms.ListForm(),
"path": "/group",
}
return TemplateResponse(request, "groups/group.html", data)
@ -121,6 +122,11 @@ class FindUsers(View):
"""basic profile info"""
user_query = request.GET.get("user_query")
group = get_object_or_404(models.Group, id=group_id)
lists = (
models.List.privacy_filter(request.user)
.filter(group=group)
.order_by("-updated_date")
)
if not group:
return HttpResponseBadRequest()
@ -142,7 +148,7 @@ class FindUsers(View):
.filter(similarity__gt=0.5, local=True)
.order_by("-similarity")[:5]
)
data = {"no_results": not user_results}
no_results = not user_results
if user_results.count() < 5:
user_results = list(user_results) + suggested_users.get_suggestions(
@ -151,8 +157,11 @@ class FindUsers(View):
data = {
"suggested_users": user_results,
"no_results": no_results,
"group": group,
"group_form": forms.GroupForm(instance=group),
"lists": lists,
"group_form": forms.GroupForm(instance=group, auto_id="group_form_id_%s"),
"list_form": forms.ListForm(),
"user_query": user_query,
"requestor_is_manager": request.user == group.user,
}