diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py
index 7c41323c..80b28310 100644
--- a/bookwyrm/forms.py
+++ b/bookwyrm/forms.py
@@ -3,7 +3,7 @@ import datetime
from collections import defaultdict
from django import forms
-from django.forms import ModelForm, PasswordInput, widgets
+from django.forms import ModelForm, PasswordInput, widgets, ChoiceField
from django.forms.widgets import Textarea
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
@@ -287,3 +287,20 @@ class ServerForm(CustomForm):
class Meta:
model = models.FederatedServer
exclude = ["remote_id"]
+
+
+class SortListForm(forms.Form):
+ sort_by = ChoiceField(
+ choices=(
+ ("order", _("List Order")),
+ ("title", _("Book Title")),
+ ("rating", _("Rating")),
+ ),
+ label=_("Sort By"),
+ )
+ direction = ChoiceField(
+ choices=(
+ ("ascending", _("Ascending")),
+ ("descending", _("Descending")),
+ ),
+ )
diff --git a/bookwyrm/migrations/0067_denullify_list_item_order.py b/bookwyrm/migrations/0067_denullify_list_item_order.py
new file mode 100644
index 00000000..51e28371
--- /dev/null
+++ b/bookwyrm/migrations/0067_denullify_list_item_order.py
@@ -0,0 +1,30 @@
+from django.db import migrations
+
+
+def forwards_func(apps, schema_editor):
+ # Set all values for ListItem.order
+ BookList = apps.get_model("bookwyrm", "List")
+ db_alias = schema_editor.connection.alias
+ for book_list in BookList.objects.using(db_alias).all():
+ for i, item in enumerate(book_list.listitem_set.order_by("id"), 1):
+ item.order = i
+ item.save()
+
+
+def reverse_func(apps, schema_editor):
+ # null all values for ListItem.order
+ BookList = apps.get_model("bookwyrm", "List")
+ db_alias = schema_editor.connection.alias
+ for book_list in BookList.objects.using(db_alias).all():
+ for item in book_list.listitem_set.order_by("id"):
+ item.order = None
+ item.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("bookwyrm", "0066_user_deactivation_reason"),
+ ]
+
+ operations = [migrations.RunPython(forwards_func, reverse_func)]
diff --git a/bookwyrm/migrations/0068_ordering_for_list_items.py b/bookwyrm/migrations/0068_ordering_for_list_items.py
new file mode 100644
index 00000000..fa64f13c
--- /dev/null
+++ b/bookwyrm/migrations/0068_ordering_for_list_items.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1.6 on 2021-04-08 16:15
+
+import bookwyrm.models.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("bookwyrm", "0067_denullify_list_item_order"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="listitem",
+ name="order",
+ field=bookwyrm.models.fields.IntegerField(),
+ ),
+ migrations.AlterUniqueTogether(
+ name="listitem",
+ unique_together={("order", "book_list"), ("book", "book_list")},
+ ),
+ ]
diff --git a/bookwyrm/models/list.py b/bookwyrm/models/list.py
index 4d6b53cd..7e6de106 100644
--- a/bookwyrm/models/list.py
+++ b/bookwyrm/models/list.py
@@ -67,7 +67,7 @@ class ListItem(CollectionItemMixin, BookWyrmModel):
)
notes = fields.TextField(blank=True, null=True)
approved = models.BooleanField(default=True)
- order = fields.IntegerField(blank=True, null=True)
+ order = fields.IntegerField()
endorsement = models.ManyToManyField("User", related_name="endorsers")
activity_serializer = activitypub.ListItem
@@ -93,7 +93,7 @@ class ListItem(CollectionItemMixin, BookWyrmModel):
)
class Meta:
- """ an opinionated constraint! you can't put a book on a list twice """
-
- unique_together = ("book", "book_list")
+ # A book may only be placed into a list once, and each order in the list may be used only
+ # once
+ unique_together = (("book", "book_list"), ("order", "book_list"))
ordering = ("-created_date",)
diff --git a/bookwyrm/templates/lists/list.html b/bookwyrm/templates/lists/list.html
index ace8aa63..3d338097 100644
--- a/bookwyrm/templates/lists/list.html
+++ b/bookwyrm/templates/lists/list.html
@@ -13,10 +13,11 @@
- {% if not items.exists %}
+ {% include "snippets/booklist-pagination.html" with page=items %}
+ {% if not items.object_list.exists %}
{% trans "This list is currently empty" %}
{% else %}
-
+
{% for item in items %}
-
@@ -40,6 +41,16 @@
+
+
@@ -49,8 +60,24 @@
{% endif %}
- {% if request.user.is_authenticated and not list.curation == 'closed' or request.user == list.user %}
+ {% trans "Sort List" %}
+
+ {% if request.user.is_authenticated and not list.curation == 'closed' or request.user == list.user %}
{% if list.curation == 'open' or request.user == list.user %}{% trans "Add Books" %}{% else %}{% trans "Suggest Books" %}{% endif %}
{% endif %}
+
{% endblock %}
diff --git a/bookwyrm/templates/snippets/booklist-pagination.html b/bookwyrm/templates/snippets/booklist-pagination.html
new file mode 100644
index 00000000..69fae52e
--- /dev/null
+++ b/bookwyrm/templates/snippets/booklist-pagination.html
@@ -0,0 +1,58 @@
+{% load i18n %}
+{% if page.has_other_pages %}
+
+{% endif %}
diff --git a/bookwyrm/tests/models/test_list.py b/bookwyrm/tests/models/test_list.py
index d99e5465..4e3460a9 100644
--- a/bookwyrm/tests/models/test_list.py
+++ b/bookwyrm/tests/models/test_list.py
@@ -51,6 +51,7 @@ class List(TestCase):
book_list=book_list,
book=self.book,
user=self.local_user,
+ order=1,
)
self.assertTrue(item.approved)
@@ -65,7 +66,11 @@ class List(TestCase):
)
item = models.ListItem.objects.create(
- book_list=book_list, book=self.book, user=self.local_user, approved=False
+ book_list=book_list,
+ book=self.book,
+ user=self.local_user,
+ approved=False,
+ order=1,
)
self.assertFalse(item.approved)
diff --git a/bookwyrm/tests/views/inbox/test_inbox_add.py b/bookwyrm/tests/views/inbox/test_inbox_add.py
index b2b65338..a5c629a8 100644
--- a/bookwyrm/tests/views/inbox/test_inbox_add.py
+++ b/bookwyrm/tests/views/inbox/test_inbox_add.py
@@ -94,6 +94,7 @@ class InboxAdd(TestCase):
"type": "ListItem",
"book": self.book.remote_id,
"id": "https://bookwyrm.social/listbook/6189",
+ "order": 1,
},
"target": "https://bookwyrm.social/user/mouse/list/to-read",
"@context": "https://www.w3.org/ns/activitystreams",
diff --git a/bookwyrm/tests/views/inbox/test_inbox_remove.py b/bookwyrm/tests/views/inbox/test_inbox_remove.py
index a17154d1..8ac8740a 100644
--- a/bookwyrm/tests/views/inbox/test_inbox_remove.py
+++ b/bookwyrm/tests/views/inbox/test_inbox_remove.py
@@ -80,6 +80,7 @@ class InboxRemove(TestCase):
user=self.local_user,
book=self.book,
book_list=booklist,
+ order=1,
)
self.assertEqual(booklist.books.count(), 1)
diff --git a/bookwyrm/tests/views/test_list.py b/bookwyrm/tests/views/test_list.py
index d669307c..0b4339fc 100644
--- a/bookwyrm/tests/views/test_list.py
+++ b/bookwyrm/tests/views/test_list.py
@@ -39,6 +39,18 @@ class ListViews(TestCase):
remote_id="https://example.com/book/1",
parent_work=work,
)
+ work_two = models.Work.objects.create(title="Labori")
+ self.book_two = models.Edition.objects.create(
+ title="Example Edition 2",
+ remote_id="https://example.com/book/2",
+ parent_work=work_two,
+ )
+ work_three = models.Work.objects.create(title="Trabajar")
+ self.book_three = models.Edition.objects.create(
+ title="Example Edition 3",
+ remote_id="https://example.com/book/3",
+ parent_work=work_three,
+ )
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
self.list = models.List.objects.create(
name="Test List", user=self.local_user
@@ -194,6 +206,7 @@ class ListViews(TestCase):
user=self.local_user,
book=self.book,
approved=False,
+ order=1,
)
request = self.factory.post(
@@ -228,6 +241,7 @@ class ListViews(TestCase):
user=self.local_user,
book=self.book,
approved=False,
+ order=1,
)
request = self.factory.post(
@@ -268,6 +282,145 @@ class ListViews(TestCase):
self.assertEqual(item.user, self.local_user)
self.assertTrue(item.approved)
+ def test_add_two_books(self):
+ """
+ Putting two books on the list. The first should have an order value of
+ 1 and the second should have an order value of 2.
+ """
+ request_one = self.factory.post(
+ "",
+ {
+ "book": self.book.id,
+ "list": self.list.id,
+ },
+ )
+ request_one.user = self.local_user
+
+ request_two = self.factory.post(
+ "",
+ {
+ "book": self.book_two.id,
+ "list": self.list.id,
+ },
+ )
+ request_two.user = self.local_user
+ views.list.add_book(request_one)
+ views.list.add_book(request_two)
+
+ items = self.list.listitem_set.order_by("order").all()
+ self.assertEqual(items[0].book, self.book)
+ self.assertEqual(items[1].book, self.book_two)
+ self.assertEqual(items[0].order, 1)
+ self.assertEqual(items[1].order, 2)
+
+ def test_add_three_books_and_remove_second(self):
+ """
+ Put three books on a list and then remove the one in the middle. The
+ ordering of the list should adjust to not have a gap.
+ """
+ request_one = self.factory.post(
+ "",
+ {
+ "book": self.book.id,
+ "list": self.list.id,
+ },
+ )
+ request_one.user = self.local_user
+
+ request_two = self.factory.post(
+ "",
+ {
+ "book": self.book_two.id,
+ "list": self.list.id,
+ },
+ )
+ request_two.user = self.local_user
+
+ request_three = self.factory.post(
+ "",
+ {
+ "book": self.book_three.id,
+ "list": self.list.id,
+ },
+ )
+ request_three.user = self.local_user
+
+ views.list.add_book(request_one)
+ views.list.add_book(request_two)
+ views.list.add_book(request_three)
+
+ items = self.list.listitem_set.order_by("order").all()
+ self.assertEqual(items[0].book, self.book)
+ self.assertEqual(items[1].book, self.book_two)
+ self.assertEqual(items[2].book, self.book_three)
+ self.assertEqual(items[0].order, 1)
+ self.assertEqual(items[1].order, 2)
+ self.assertEqual(items[2].order, 3)
+
+ remove_request = self.factory.post("", {"item": items[1].id})
+ remove_request.user = self.local_user
+ views.list.remove_book(remove_request, self.list.id)
+ items = self.list.listitem_set.order_by("order").all()
+ self.assertEqual(items[0].book, self.book)
+ self.assertEqual(items[1].book, self.book_three)
+ self.assertEqual(items[0].order, 1)
+ self.assertEqual(items[1].order, 2)
+
+ def test_add_three_books_and_move_last_to_first(self):
+ """
+ Put three books on the list and move the last book to the first
+ position.
+ """
+ request_one = self.factory.post(
+ "",
+ {
+ "book": self.book.id,
+ "list": self.list.id,
+ },
+ )
+ request_one.user = self.local_user
+
+ request_two = self.factory.post(
+ "",
+ {
+ "book": self.book_two.id,
+ "list": self.list.id,
+ },
+ )
+ request_two.user = self.local_user
+
+ request_three = self.factory.post(
+ "",
+ {
+ "book": self.book_three.id,
+ "list": self.list.id,
+ },
+ )
+ request_three.user = self.local_user
+
+ views.list.add_book(request_one)
+ views.list.add_book(request_two)
+ views.list.add_book(request_three)
+
+ items = self.list.listitem_set.order_by("order").all()
+ self.assertEqual(items[0].book, self.book)
+ self.assertEqual(items[1].book, self.book_two)
+ self.assertEqual(items[2].book, self.book_three)
+ self.assertEqual(items[0].order, 1)
+ self.assertEqual(items[1].order, 2)
+ self.assertEqual(items[2].order, 3)
+
+ set_position_request = self.factory.post("", {"position": 1})
+ set_position_request.user = self.local_user
+ views.list.set_book_position(set_position_request, items[2].id)
+ items = self.list.listitem_set.order_by("order").all()
+ self.assertEqual(items[0].book, self.book_three)
+ self.assertEqual(items[1].book, self.book)
+ self.assertEqual(items[2].book, self.book_two)
+ self.assertEqual(items[0].order, 1)
+ self.assertEqual(items[1].order, 2)
+ self.assertEqual(items[2].order, 3)
+
def test_add_book_outsider(self):
""" put a book on a list """
self.list.curation = "open"
@@ -358,6 +511,7 @@ class ListViews(TestCase):
book_list=self.list,
user=self.local_user,
book=self.book,
+ order=1,
)
self.assertTrue(self.list.listitem_set.exists())
@@ -377,9 +531,7 @@ class ListViews(TestCase):
""" take an item off a list """
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
item = models.ListItem.objects.create(
- book_list=self.list,
- user=self.local_user,
- book=self.book,
+ book_list=self.list, user=self.local_user, book=self.book, order=1
)
self.assertTrue(self.list.listitem_set.exists())
request = self.factory.post(
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index cf3f877b..9e280f3e 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -184,6 +184,11 @@ urlpatterns = [
views.list.remove_book,
name="list-remove-book",
),
+ re_path(
+ r"^list-item/(?P\d+)/set-position$",
+ views.list.set_book_position,
+ name="list-set-book-position",
+ ),
re_path(
r"^list/(?P\d+)/curate/?$", views.Curate.as_view(), name="list-curate"
),
diff --git a/bookwyrm/views/list.py b/bookwyrm/views/list.py
index 27e36dc5..c7311bf1 100644
--- a/bookwyrm/views/list.py
+++ b/bookwyrm/views/list.py
@@ -1,8 +1,9 @@
""" book list views"""
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
-from django.db import IntegrityError
-from django.db.models import Count, Q
+from django.db import IntegrityError, transaction
+from django.db.models import Avg, Count, Q, Max
+from django.db.models.functions import Coalesce
from django.http import HttpResponseNotFound, HttpResponseBadRequest
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
@@ -16,6 +17,7 @@ from bookwyrm.connectors import connector_manager
from .helpers import is_api_request, privacy_filter
from .helpers import get_user_from_username
+
# pylint: disable=no-self-use
class Lists(View):
""" book list page """
@@ -35,7 +37,6 @@ class Lists(View):
.filter(item_count__gt=0)
.order_by("-updated_date")
.distinct()
- .all()
)
lists = privacy_filter(
@@ -100,6 +101,43 @@ class List(View):
query = request.GET.get("q")
suggestions = None
+
+ # sort_by shall be "order" unless a valid alternative is given
+ sort_by = request.GET.get("sort_by", "order")
+ if sort_by not in ("order", "title", "rating"):
+ sort_by = "order"
+
+ # direction shall be "ascending" unless a valid alternative is given
+ direction = request.GET.get("direction", "ascending")
+ if direction not in ("ascending", "descending"):
+ direction = "ascending"
+
+ page = request.GET.get("page", 1)
+
+ if sort_by == "order":
+ directional_sort_by = "order"
+ if direction == "descending":
+ directional_sort_by = "-" + directional_sort_by
+ items = book_list.listitem_set.filter(approved=True).order_by(
+ directional_sort_by
+ )
+ elif sort_by == "title":
+ directional_sort_by = "book__title"
+ if direction == "descending":
+ directional_sort_by = "-" + directional_sort_by
+ items = book_list.listitem_set.filter(approved=True).order_by(
+ directional_sort_by
+ )
+ elif sort_by == "rating":
+ directional_sort_by = "average_rating"
+ if direction == "descending":
+ directional_sort_by = "-" + directional_sort_by
+ items = book_list.listitem_set.annotate(
+ average_rating=Avg(Coalesce("book__review__rating", 0))
+ ).order_by(directional_sort_by)
+
+ paginated = Paginator(items, 25)
+
if query and request.user.is_authenticated:
# search for books
suggestions = connector_manager.local_search(query, raw=True)
@@ -119,11 +157,14 @@ class List(View):
data = {
"list": book_list,
- "items": book_list.listitem_set.filter(approved=True),
+ "items": paginated.get_page(page),
"pending_count": book_list.listitem_set.filter(approved=False).count(),
"suggested_books": suggestions,
"list_form": forms.ListForm(instance=book_list),
"query": query or "",
+ "sort_form": forms.SortListForm(
+ {"direction": direction, "sort_by": sort_by}
+ ),
}
return TemplateResponse(request, "lists/list.html", data)
@@ -168,7 +209,9 @@ class Curate(View):
suggestion.approved = True
suggestion.save()
else:
+ deleted_order = suggestion.order
suggestion.delete(broadcast=False)
+ normalize_book_list_ordering(book_list.id, start=deleted_order)
return redirect("list-curate", book_list.id)
@@ -179,6 +222,8 @@ def add_book(request):
if not book_list.visible_to_user(request.user):
return HttpResponseNotFound()
+ order_max = book_list.listitem_set.aggregate(Max("order"))["order__max"] or 0
+
book = get_object_or_404(models.Edition, id=request.POST.get("book"))
# do you have permission to add to the list?
try:
@@ -188,6 +233,7 @@ def add_book(request):
book=book,
book_list=book_list,
user=request.user,
+ order=order_max + 1,
)
elif book_list.curation == "curated":
# make a pending entry
@@ -196,6 +242,7 @@ def add_book(request):
book=book,
book_list=book_list,
user=request.user,
+ order=order_max + 1,
)
else:
# you can't add to this list, what were you THINKING
@@ -209,12 +256,101 @@ def add_book(request):
@require_POST
def remove_book(request, list_id):
- """ put a book on a list """
- book_list = get_object_or_404(models.List, id=list_id)
- item = get_object_or_404(models.ListItem, id=request.POST.get("item"))
+ """ remove a book from a list """
+ with transaction.atomic():
+ book_list = get_object_or_404(models.List, id=list_id)
+ item = get_object_or_404(models.ListItem, id=request.POST.get("item"))
- if not book_list.user == request.user and not item.user == request.user:
- return HttpResponseNotFound()
+ if not book_list.user == request.user and not item.user == request.user:
+ return HttpResponseNotFound()
- item.delete()
+ deleted_order = item.order
+ item.delete()
+ normalize_book_list_ordering(book_list.id, start=deleted_order)
return redirect("list", list_id)
+
+
+@require_POST
+def set_book_position(request, list_item_id):
+ """
+ Action for when the list user manually specifies a list position, takes special care with the unique ordering per list
+ """
+ with transaction.atomic():
+ list_item = get_object_or_404(models.ListItem, id=list_item_id)
+ try:
+ int_position = int(request.POST.get("position"))
+ except ValueError:
+ return HttpResponseBadRequest(
+ "bad value for position. should be an integer"
+ )
+
+ if int_position < 1:
+ return HttpResponseBadRequest("position cannot be less than 1")
+
+ book_list = list_item.book_list
+ order_max = book_list.listitem_set.aggregate(Max("order"))["order__max"]
+
+ if int_position > order_max:
+ int_position = order_max
+
+ if request.user not in (book_list.user, list_item.user):
+ return HttpResponseNotFound()
+
+ original_order = list_item.order
+ if original_order == int_position:
+ return
+ elif original_order > int_position:
+ list_item.order = -1
+ list_item.save()
+ increment_order_in_reverse(book_list.id, int_position, original_order)
+ else:
+ list_item.order = -1
+ list_item.save()
+ decrement_order(book_list.id, original_order, int_position)
+
+ list_item.order = int_position
+ list_item.save()
+
+ return redirect("list", book_list.id)
+
+
+@transaction.atomic
+def increment_order_in_reverse(book_list_id, start, end):
+ try:
+ book_list = models.List.objects.get(id=book_list_id)
+ except models.List.DoesNotExist:
+ return
+ items = book_list.listitem_set.filter(order__gte=start, order__lt=end).order_by(
+ "-order"
+ )
+ for item in items:
+ item.order += 1
+ item.save()
+
+
+@transaction.atomic
+def decrement_order(book_list_id, start, end):
+ try:
+ book_list = models.List.objects.get(id=book_list_id)
+ except models.List.DoesNotExist:
+ return
+ items = book_list.listitem_set.filter(order__gt=start, order__lte=end).order_by(
+ "order"
+ )
+ for item in items:
+ item.order -= 1
+ item.save()
+
+
+@transaction.atomic
+def normalize_book_list_ordering(book_list_id, start=0, add_offset=0):
+ try:
+ book_list = models.List.objects.get(id=book_list_id)
+ except models.List.DoesNotExist:
+ return
+ items = book_list.listitem_set.filter(order__gt=start).order_by("order")
+ for i, item in enumerate(items, start):
+ effective_order = i + add_offset
+ if item.order != effective_order:
+ item.order = effective_order
+ item.save()
diff --git a/locale/es/LC_MESSAGES/django.mo b/locale/es/LC_MESSAGES/django.mo
index ea8eac7e..d42d8394 100644
Binary files a/locale/es/LC_MESSAGES/django.mo and b/locale/es/LC_MESSAGES/django.mo differ
diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po
index 64921d5e..159e806a 100644
--- a/locale/es/LC_MESSAGES/django.po
+++ b/locale/es/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-04-01 13:14-0700\n"
+"POT-Creation-Date: 2021-04-11 01:59+0000\n"
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -49,6 +49,34 @@ msgstr "%(count)d usos"
msgid "Unlimited"
msgstr "Sin límite"
+#: bookwyrm/forms.py:289
+msgid "List Order"
+msgstr "Orden de la lista"
+
+#: bookwyrm/forms.py:290
+#| msgid "Title"
+msgid "Book Title"
+msgstr "Título"
+
+#: bookwyrm/forms.py:291 bookwyrm/templates/snippets/create_status_form.html:29
+#: bookwyrm/templates/user/shelf.html:81
+msgid "Rating"
+msgstr "Calificación"
+
+#: bookwyrm/forms.py:293 bookwyrm/templates/lists/list.html:105
+msgid "Sort By"
+msgstr "Ordenar por"
+
+#: bookwyrm/forms.py:297
+#| msgid "Started reading"
+msgid "Ascending"
+msgstr "Ascendente"
+
+#: bookwyrm/forms.py:298
+#| msgid "Started reading"
+msgid "Descending"
+msgstr "Descendente"
+
#: bookwyrm/models/fields.py:24
#, python-format
msgid "%(value)s is not a valid remote_id"
@@ -59,7 +87,7 @@ msgstr "%(value)s no es un remote_id válido"
msgid "%(value)s is not a valid username"
msgstr "%(value)s no es un usuario válido"
-#: bookwyrm/models/fields.py:165 bookwyrm/templates/layout.html:157
+#: bookwyrm/models/fields.py:165 bookwyrm/templates/layout.html:152
msgid "username"
msgstr "nombre de usuario"
@@ -146,12 +174,12 @@ msgid "ISBN:"
msgstr "ISBN:"
#: bookwyrm/templates/book/book.html:69
-#: bookwyrm/templates/book/edit_book.html:211
+#: bookwyrm/templates/book/edit_book.html:223
msgid "OCLC Number:"
msgstr "Número OCLC:"
#: bookwyrm/templates/book/book.html:76
-#: bookwyrm/templates/book/edit_book.html:215
+#: bookwyrm/templates/book/edit_book.html:227
msgid "ASIN:"
msgstr "ASIN:"
@@ -171,17 +199,17 @@ msgid "Add Description"
msgstr "Agregar descripción"
#: bookwyrm/templates/book/book.html:107
-#: bookwyrm/templates/book/edit_book.html:101
+#: bookwyrm/templates/book/edit_book.html:107
#: bookwyrm/templates/lists/form.html:12
msgid "Description:"
msgstr "Descripción:"
#: bookwyrm/templates/book/book.html:111
-#: bookwyrm/templates/book/edit_book.html:225
+#: bookwyrm/templates/book/edit_book.html:237
#: bookwyrm/templates/edit_author.html:78 bookwyrm/templates/lists/form.html:42
#: bookwyrm/templates/preferences/edit_user.html:70
#: bookwyrm/templates/settings/site.html:93
-#: bookwyrm/templates/snippets/readthrough.html:65
+#: bookwyrm/templates/snippets/readthrough.html:75
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:34
@@ -190,12 +218,12 @@ msgstr "Guardar"
#: bookwyrm/templates/book/book.html:112 bookwyrm/templates/book/book.html:161
#: bookwyrm/templates/book/cover_modal.html:32
-#: bookwyrm/templates/book/edit_book.html:226
+#: bookwyrm/templates/book/edit_book.html:238
#: bookwyrm/templates/edit_author.html:79
#: bookwyrm/templates/moderation/report_modal.html:32
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
#: bookwyrm/templates/snippets/goal_form.html:32
-#: bookwyrm/templates/snippets/readthrough.html:66
+#: bookwyrm/templates/snippets/readthrough.html:76
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:43
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:43
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:35
@@ -257,7 +285,7 @@ msgstr "Irse a lista"
#: bookwyrm/templates/book/book.html:223
#: bookwyrm/templates/book/cover_modal.html:31
-#: bookwyrm/templates/lists/list.html:90
+#: bookwyrm/templates/lists/list.html:156
msgid "Add"
msgstr "Agregar"
@@ -266,14 +294,14 @@ msgid "rated it"
msgstr "lo calificó con"
#: bookwyrm/templates/book/cover_modal.html:17
-#: bookwyrm/templates/book/edit_book.html:163
+#: bookwyrm/templates/book/edit_book.html:175
#, fuzzy
#| msgid "Add cover"
msgid "Upload cover:"
msgstr "Agregar portada"
#: bookwyrm/templates/book/cover_modal.html:23
-#: bookwyrm/templates/book/edit_book.html:169
+#: bookwyrm/templates/book/edit_book.html:181
msgid "Load cover from url:"
msgstr ""
@@ -353,93 +381,93 @@ msgstr "Volver"
msgid "Metadata"
msgstr "Metadatos"
-#: bookwyrm/templates/book/edit_book.html:91
+#: bookwyrm/templates/book/edit_book.html:92
msgid "Title:"
msgstr "Título:"
-#: bookwyrm/templates/book/edit_book.html:96
+#: bookwyrm/templates/book/edit_book.html:100
msgid "Subtitle:"
msgstr "Subtítulo:"
-#: bookwyrm/templates/book/edit_book.html:106
+#: bookwyrm/templates/book/edit_book.html:112
msgid "Series:"
msgstr "Serie:"
-#: bookwyrm/templates/book/edit_book.html:111
+#: bookwyrm/templates/book/edit_book.html:117
msgid "Series number:"
msgstr "Número de serie:"
-#: bookwyrm/templates/book/edit_book.html:117
+#: bookwyrm/templates/book/edit_book.html:123
#, fuzzy
#| msgid "Published"
msgid "Publisher:"
msgstr "Publicado"
-#: bookwyrm/templates/book/edit_book.html:119
+#: bookwyrm/templates/book/edit_book.html:125
msgid "Separate multiple publishers with commas."
msgstr ""
-#: bookwyrm/templates/book/edit_book.html:125
+#: bookwyrm/templates/book/edit_book.html:132
msgid "First published date:"
msgstr "Fecha de primera publicación:"
-#: bookwyrm/templates/book/edit_book.html:130
+#: bookwyrm/templates/book/edit_book.html:140
msgid "Published date:"
msgstr "Fecha de publicación:"
-#: bookwyrm/templates/book/edit_book.html:137
+#: bookwyrm/templates/book/edit_book.html:149
#, fuzzy
#| msgid "Author"
msgid "Authors"
msgstr "Autor/Autora"
-#: bookwyrm/templates/book/edit_book.html:143
+#: bookwyrm/templates/book/edit_book.html:155
#, fuzzy, python-format
#| msgid "Added by %(username)s"
msgid "Remove %(name)s"
msgstr "Agregado por %(username)s"
-#: bookwyrm/templates/book/edit_book.html:148
+#: bookwyrm/templates/book/edit_book.html:160
#, fuzzy
#| msgid "Edit Author"
msgid "Add Authors:"
msgstr "Editar Autor/Autora"
-#: bookwyrm/templates/book/edit_book.html:149
+#: bookwyrm/templates/book/edit_book.html:161
msgid "John Doe, Jane Smith"
msgstr ""
-#: bookwyrm/templates/book/edit_book.html:155
+#: bookwyrm/templates/book/edit_book.html:167
#: bookwyrm/templates/user/shelf.html:75
msgid "Cover"
msgstr "Portada:"
-#: bookwyrm/templates/book/edit_book.html:182
+#: bookwyrm/templates/book/edit_book.html:194
msgid "Physical Properties"
msgstr "Propiedades físicas:"
-#: bookwyrm/templates/book/edit_book.html:183
+#: bookwyrm/templates/book/edit_book.html:195
#: bookwyrm/templates/book/format_filter.html:5
msgid "Format:"
msgstr "Formato:"
-#: bookwyrm/templates/book/edit_book.html:191
+#: bookwyrm/templates/book/edit_book.html:203
msgid "Pages:"
msgstr "Páginas:"
-#: bookwyrm/templates/book/edit_book.html:198
+#: bookwyrm/templates/book/edit_book.html:210
msgid "Book Identifiers"
msgstr "Identificadores de libro"
-#: bookwyrm/templates/book/edit_book.html:199
+#: bookwyrm/templates/book/edit_book.html:211
msgid "ISBN 13:"
msgstr "ISBN 13:"
-#: bookwyrm/templates/book/edit_book.html:203
+#: bookwyrm/templates/book/edit_book.html:215
msgid "ISBN 10:"
msgstr "ISBN 10:"
-#: bookwyrm/templates/book/edit_book.html:207
+#: bookwyrm/templates/book/edit_book.html:219
#: bookwyrm/templates/edit_author.html:59
msgid "Openlibrary key:"
msgstr "Clave OpenLibrary:"
@@ -497,12 +525,18 @@ msgstr ""
#: bookwyrm/templates/components/inline_form.html:8
#: bookwyrm/templates/components/modal.html:11
-#: bookwyrm/templates/feed/feed_layout.html:57
+#: bookwyrm/templates/feed/feed_layout.html:70
#: bookwyrm/templates/get_started/layout.html:19
#: bookwyrm/templates/get_started/layout.html:52
msgid "Close"
msgstr "Cerrar"
+#: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8
+#, fuzzy
+#| msgid "Boost status"
+msgid "Compose status"
+msgstr "Status de respaldo"
+
#: bookwyrm/templates/directory/community_filter.html:5
#, fuzzy
#| msgid "Comment"
@@ -523,7 +557,7 @@ msgstr "Federalizado"
#: bookwyrm/templates/directory/directory.html:6
#: bookwyrm/templates/directory/directory.html:11
-#: bookwyrm/templates/layout.html:97
+#: bookwyrm/templates/layout.html:92
msgid "Directory"
msgstr ""
@@ -844,23 +878,23 @@ msgstr "Tus libros"
msgid "There are no books here right now! Try searching for a book to get started"
msgstr "¡No hay ningún libro aqui ahorita! Busca a un libro para empezar"
-#: bookwyrm/templates/feed/feed_layout.html:23
+#: bookwyrm/templates/feed/feed_layout.html:24
#: bookwyrm/templates/user/shelf.html:28
msgid "To Read"
msgstr "Para leer"
-#: bookwyrm/templates/feed/feed_layout.html:24
+#: bookwyrm/templates/feed/feed_layout.html:25
#: bookwyrm/templates/user/shelf.html:28
msgid "Currently Reading"
msgstr "Leyendo actualmente"
-#: bookwyrm/templates/feed/feed_layout.html:25
+#: bookwyrm/templates/feed/feed_layout.html:26
#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:11
#: bookwyrm/templates/user/shelf.html:28
msgid "Read"
msgstr "Leer"
-#: bookwyrm/templates/feed/feed_layout.html:74 bookwyrm/templates/goal.html:26
+#: bookwyrm/templates/feed/feed_layout.html:88 bookwyrm/templates/goal.html:26
#: bookwyrm/templates/snippets/goal_card.html:6
#, python-format
msgid "%(year)s Reading Goal"
@@ -893,7 +927,7 @@ msgid "What are you reading?"
msgstr "Lectura se empezó"
#: bookwyrm/templates/get_started/books.html:9
-#: bookwyrm/templates/lists/list.html:58
+#: bookwyrm/templates/lists/list.html:124
msgid "Search for a book"
msgstr "Buscar libros"
@@ -914,7 +948,7 @@ msgstr ""
#: bookwyrm/templates/get_started/users.html:18
#: bookwyrm/templates/get_started/users.html:19
#: bookwyrm/templates/layout.html:37 bookwyrm/templates/layout.html:38
-#: bookwyrm/templates/lists/list.html:62
+#: bookwyrm/templates/lists/list.html:128
msgid "Search"
msgstr "Buscar"
@@ -931,7 +965,7 @@ msgid "Popular on %(site_name)s"
msgstr "Sobre %(site_name)s"
#: bookwyrm/templates/get_started/books.html:51
-#: bookwyrm/templates/lists/list.html:75
+#: bookwyrm/templates/lists/list.html:141
msgid "No books found"
msgstr "No se encontró ningún libro"
@@ -1055,7 +1089,7 @@ msgid "%(username)s's %(year)s Books"
msgstr "Los libros de %(username)s para %(year)s"
#: bookwyrm/templates/import.html:5 bookwyrm/templates/import.html:9
-#: bookwyrm/templates/layout.html:102
+#: bookwyrm/templates/layout.html:97
msgid "Import Books"
msgstr "Importar libros"
@@ -1196,16 +1230,11 @@ msgstr "Menú de navigación central"
msgid "Feed"
msgstr "Actividad"
-#: bookwyrm/templates/layout.html:92
-#: bookwyrm/templates/preferences/preferences_layout.html:14
-msgid "Profile"
-msgstr "Perfil"
-
-#: bookwyrm/templates/layout.html:107
+#: bookwyrm/templates/layout.html:102
msgid "Settings"
msgstr "Configuración"
-#: bookwyrm/templates/layout.html:116
+#: bookwyrm/templates/layout.html:111
#: bookwyrm/templates/settings/admin_layout.html:24
#: bookwyrm/templates/settings/manage_invite_requests.html:15
#: bookwyrm/templates/settings/manage_invites.html:3
@@ -1213,57 +1242,57 @@ msgstr "Configuración"
msgid "Invites"
msgstr "Invitaciones"
-#: bookwyrm/templates/layout.html:123
+#: bookwyrm/templates/layout.html:118
msgid "Admin"
msgstr ""
-#: bookwyrm/templates/layout.html:130
+#: bookwyrm/templates/layout.html:125
msgid "Log out"
msgstr "Cerrar sesión"
-#: bookwyrm/templates/layout.html:138 bookwyrm/templates/layout.html:139
+#: bookwyrm/templates/layout.html:133 bookwyrm/templates/layout.html:134
#: bookwyrm/templates/notifications.html:6
#: bookwyrm/templates/notifications.html:10
msgid "Notifications"
msgstr "Notificaciones"
-#: bookwyrm/templates/layout.html:156 bookwyrm/templates/layout.html:160
+#: bookwyrm/templates/layout.html:151 bookwyrm/templates/layout.html:155
#: bookwyrm/templates/login.html:17
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr "Nombre de usuario:"
-#: bookwyrm/templates/layout.html:161
+#: bookwyrm/templates/layout.html:156
msgid "password"
msgstr "contraseña"
-#: bookwyrm/templates/layout.html:162 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:157 bookwyrm/templates/login.html:36
msgid "Forgot your password?"
msgstr "¿Olvidaste tu contraseña?"
-#: bookwyrm/templates/layout.html:165 bookwyrm/templates/login.html:10
+#: bookwyrm/templates/layout.html:160 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33
msgid "Log in"
msgstr "Iniciar sesión"
-#: bookwyrm/templates/layout.html:173
+#: bookwyrm/templates/layout.html:168
msgid "Join"
msgstr ""
-#: bookwyrm/templates/layout.html:196
+#: bookwyrm/templates/layout.html:191
msgid "About this server"
msgstr "Sobre este servidor"
-#: bookwyrm/templates/layout.html:200
+#: bookwyrm/templates/layout.html:195
msgid "Contact site admin"
msgstr "Contactarse con administradores del sitio"
-#: bookwyrm/templates/layout.html:207
+#: bookwyrm/templates/layout.html:202
#, python-format
msgid "Support %(site_name)s on %(support_title)s"
msgstr ""
-#: bookwyrm/templates/layout.html:211
+#: bookwyrm/templates/layout.html:206
msgid "BookWyrm is open source software. You can contribute or report issues on GitHub."
msgstr "BookWyrm es software de código abierto. Puedes contribuir o reportar problemas en GitHub."
@@ -1342,45 +1371,74 @@ msgstr "Abierto"
msgid "Anyone can add books to this list"
msgstr "Cualquer usuario puede agregar libros a esta lista"
-#: bookwyrm/templates/lists/list.html:17
+#: bookwyrm/templates/lists/list.html:19
+#: bookwyrm/templates/snippets/pagination.html:12
+msgid "Previous"
+msgstr "Anterior"
+
+#: bookwyrm/templates/lists/list.html:22
+#: bookwyrm/templates/snippets/pagination.html:23
+msgid "Next"
+msgstr "Siguiente"
+
+#: bookwyrm/templates/lists/list.html:58
msgid "This list is currently empty"
msgstr "Esta lista está vacia"
-#: bookwyrm/templates/lists/list.html:35
+#: bookwyrm/templates/lists/list.html:76
#, python-format
msgid "Added by %(username)s"
msgstr "Agregado por %(username)s"
-#: bookwyrm/templates/lists/list.html:41
-#: bookwyrm/templates/snippets/shelf_selector.html:28
+#: bookwyrm/templates/lists/list.html:82
+#: bookwyrm/templates/snippets/shelf_selector.html:26
msgid "Remove"
msgstr "Quitar"
-#: bookwyrm/templates/lists/list.html:54
+#: bookwyrm/templates/lists/list.html:90
+msgid "Set list position"
+msgstr "Apunta indice"
+
+#: bookwyrm/templates/lists/list.html:103
+#: bookwyrm/templates/lists/list.html:115
+msgid "Sort List"
+msgstr "Ordena la lista"
+
+#: bookwyrm/templates/lists/list.html:109
+#, fuzzy
+#| msgid "List curation:"
+msgid "Direction"
+msgstr "Enumerar lista de comisariado:"
+
+#: bookwyrm/templates/lists/list.html:120
msgid "Add Books"
msgstr "Agregar libros"
-#: bookwyrm/templates/lists/list.html:54
+#: bookwyrm/templates/lists/list.html:120
msgid "Suggest Books"
msgstr "Sugerir libros"
-#: bookwyrm/templates/lists/list.html:63
+#: bookwyrm/templates/lists/list.html:129
msgid "search"
msgstr "buscar"
-#: bookwyrm/templates/lists/list.html:69
+#: bookwyrm/templates/lists/list.html:135
msgid "Clear search"
msgstr "Borrar búsqueda"
-#: bookwyrm/templates/lists/list.html:74
+#: bookwyrm/templates/lists/list.html:140
#, python-format
msgid "No books found matching the query \"%(query)s\""
msgstr "No se encontró ningún libro correspondiente a la búsqueda: \"%(query)s\""
-#: bookwyrm/templates/lists/list.html:90
+#: bookwyrm/templates/lists/list.html:156
msgid "Suggest"
msgstr "Sugerir"
+#: bookwyrm/templates/lists/lists.html:14 bookwyrm/templates/user/lists.html:9
+msgid "Your Lists"
+msgstr "Tus listas"
+
#: bookwyrm/templates/login.html:4
msgid "Login"
msgstr "Iniciar sesión"
@@ -1422,7 +1480,7 @@ msgid "View user profile"
msgstr "Perfil de usuario"
#: bookwyrm/templates/moderation/report.html:22
-#: bookwyrm/templates/snippets/status/status_options.html:25
+#: bookwyrm/templates/snippets/status/status_options.html:35
#: bookwyrm/templates/snippets/user_options.html:13
msgid "Send direct message"
msgstr "Enviar mensaje directo"
@@ -1440,8 +1498,8 @@ msgid "Moderator Comments"
msgstr ""
#: bookwyrm/templates/moderation/report.html:54
-#: bookwyrm/templates/snippets/create_status.html:12
-#: bookwyrm/templates/snippets/create_status_form.html:52
+#: bookwyrm/templates/snippets/create_status.html:28
+#: bookwyrm/templates/snippets/create_status_form.html:44
msgid "Comment"
msgstr "Comentario"
@@ -1698,6 +1756,10 @@ msgstr "Huso horario preferido"
msgid "Account"
msgstr "Cuenta"
+#: bookwyrm/templates/preferences/preferences_layout.html:14
+msgid "Profile"
+msgstr "Perfil"
+
#: bookwyrm/templates/preferences/preferences_layout.html:20
msgid "Relationships"
msgstr "Relaciones"
@@ -1854,7 +1916,8 @@ msgid "Software"
msgstr "Software"
#: bookwyrm/templates/settings/federation.html:24
-#: bookwyrm/templates/settings/manage_invite_requests.html:33
+#: bookwyrm/templates/settings/manage_invite_requests.html:44
+#: bookwyrm/templates/settings/status_filter.html:5
#: bookwyrm/templates/settings/user_admin.html:32
msgid "Status"
msgstr "Status"
@@ -1872,61 +1935,72 @@ msgstr "Invitaciones"
msgid "Ignored Invite Requests"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:31
-msgid "Date"
-msgstr ""
+#: bookwyrm/templates/settings/manage_invite_requests.html:35
+#, fuzzy
+#| msgid "Federated"
+msgid "Date requested"
+msgstr "Federalizado"
-#: bookwyrm/templates/settings/manage_invite_requests.html:32
+#: bookwyrm/templates/settings/manage_invite_requests.html:39
+#, fuzzy
+#| msgid "Accept"
+msgid "Date accepted"
+msgstr "Aceptar"
+
+#: bookwyrm/templates/settings/manage_invite_requests.html:42
msgid "Email"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:34
+#: bookwyrm/templates/settings/manage_invite_requests.html:47
#, fuzzy
#| msgid "Notifications"
msgid "Action"
msgstr "Notificaciones"
-#: bookwyrm/templates/settings/manage_invite_requests.html:37
+#: bookwyrm/templates/settings/manage_invite_requests.html:50
#, fuzzy
#| msgid "Follow Requests"
msgid "No requests"
msgstr "Solicitudes de seguidor"
-#: bookwyrm/templates/settings/manage_invite_requests.html:45
+#: bookwyrm/templates/settings/manage_invite_requests.html:59
+#: bookwyrm/templates/settings/status_filter.html:16
#, fuzzy
#| msgid "Accept"
msgid "Accepted"
msgstr "Aceptar"
-#: bookwyrm/templates/settings/manage_invite_requests.html:47
+#: bookwyrm/templates/settings/manage_invite_requests.html:61
+#: bookwyrm/templates/settings/status_filter.html:12
msgid "Sent"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:49
+#: bookwyrm/templates/settings/manage_invite_requests.html:63
+#: bookwyrm/templates/settings/status_filter.html:8
msgid "Requested"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:57
+#: bookwyrm/templates/settings/manage_invite_requests.html:73
msgid "Send invite"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:59
+#: bookwyrm/templates/settings/manage_invite_requests.html:75
msgid "Re-send invite"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:70
+#: bookwyrm/templates/settings/manage_invite_requests.html:95
msgid "Ignore"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:72
-msgid "Un-gnore"
+#: bookwyrm/templates/settings/manage_invite_requests.html:97
+msgid "Un-ignore"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:83
+#: bookwyrm/templates/settings/manage_invite_requests.html:108
msgid "Back to pending requests"
msgstr ""
-#: bookwyrm/templates/settings/manage_invite_requests.html:85
+#: bookwyrm/templates/settings/manage_invite_requests.html:110
msgid "View ignored requests"
msgstr ""
@@ -2080,8 +2154,8 @@ msgstr "%(title)s por "
#: bookwyrm/templates/snippets/boost_button.html:8
#: bookwyrm/templates/snippets/boost_button.html:9
-#: bookwyrm/templates/snippets/status/status_body.html:51
#: bookwyrm/templates/snippets/status/status_body.html:52
+#: bookwyrm/templates/snippets/status/status_body.html:53
msgid "Boost status"
msgstr "Status de respaldo"
@@ -2094,15 +2168,15 @@ msgstr "Status de des-respaldo"
msgid "Spoiler alert:"
msgstr "Alerta de spoiler:"
-#: bookwyrm/templates/snippets/content_warning_field.html:4
+#: bookwyrm/templates/snippets/content_warning_field.html:10
msgid "Spoilers ahead!"
msgstr "¡Advertencia, ya vienen spoilers!"
-#: bookwyrm/templates/snippets/create_status.html:9
+#: bookwyrm/templates/snippets/create_status.html:17
msgid "Review"
msgstr "Reseña"
-#: bookwyrm/templates/snippets/create_status.html:15
+#: bookwyrm/templates/snippets/create_status.html:39
msgid "Quote"
msgstr "Cita"
@@ -2124,52 +2198,41 @@ msgstr "Cita"
msgid "Review:"
msgstr "Reseña"
-#: bookwyrm/templates/snippets/create_status_form.html:29
-#: bookwyrm/templates/user/shelf.html:81
-msgid "Rating"
-msgstr "Calificación"
-
-#: bookwyrm/templates/snippets/create_status_form.html:31
-#: bookwyrm/templates/snippets/rate_action.html:14
-#: bookwyrm/templates/snippets/stars.html:3
-msgid "No rating"
-msgstr "No calificación"
-
-#: bookwyrm/templates/snippets/create_status_form.html:64
+#: bookwyrm/templates/snippets/create_status_form.html:56
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:16
msgid "Progress:"
msgstr "Progreso:"
-#: bookwyrm/templates/snippets/create_status_form.html:71
+#: bookwyrm/templates/snippets/create_status_form.html:63
#: bookwyrm/templates/snippets/readthrough_form.html:22
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:30
msgid "pages"
msgstr "páginas"
-#: bookwyrm/templates/snippets/create_status_form.html:72
+#: bookwyrm/templates/snippets/create_status_form.html:64
#: bookwyrm/templates/snippets/readthrough_form.html:23
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:31
msgid "percent"
msgstr "por ciento"
-#: bookwyrm/templates/snippets/create_status_form.html:77
+#: bookwyrm/templates/snippets/create_status_form.html:69
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:36
#, python-format
msgid "of %(pages)s pages"
msgstr "de %(pages)s páginas"
-#: bookwyrm/templates/snippets/create_status_form.html:89
+#: bookwyrm/templates/snippets/create_status_form.html:81
msgid "Include spoiler alert"
msgstr "Incluir alerta de spoiler"
-#: bookwyrm/templates/snippets/create_status_form.html:95
+#: bookwyrm/templates/snippets/create_status_form.html:88
#: bookwyrm/templates/snippets/privacy-icons.html:15
#: bookwyrm/templates/snippets/privacy-icons.html:16
#: bookwyrm/templates/snippets/privacy_select.html:19
msgid "Private"
msgstr "Privada"
-#: bookwyrm/templates/snippets/create_status_form.html:102
+#: bookwyrm/templates/snippets/create_status_form.html:99
msgid "Post"
msgstr "Compartir"
@@ -2184,13 +2247,14 @@ msgstr "Estás eliminando esta lectura y sus %(count)s actualizaciones de progre
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15
#: bookwyrm/templates/snippets/follow_request_buttons.html:13
+#: venv/lib/python3.8/site-packages/django/forms/formsets.py:391
msgid "Delete"
msgstr "Eliminar"
#: bookwyrm/templates/snippets/fav_button.html:7
#: bookwyrm/templates/snippets/fav_button.html:8
-#: bookwyrm/templates/snippets/status/status_body.html:55
#: bookwyrm/templates/snippets/status/status_body.html:56
+#: bookwyrm/templates/snippets/status/status_body.html:57
msgid "Like status"
msgstr "Me gusta status"
@@ -2209,11 +2273,11 @@ msgstr "Mostrar menos"
msgid "Hide filters"
msgstr ""
-#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:19
+#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:22
msgid "Apply filters"
msgstr ""
-#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:23
+#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:26
#, fuzzy
#| msgid "Clear search"
msgid "Clear filters"
@@ -2237,6 +2301,19 @@ msgstr "Dejar de seguir"
msgid "Accept"
msgstr "Aceptar"
+#: bookwyrm/templates/snippets/form_rate_stars.html:20
+#: bookwyrm/templates/snippets/stars.html:13
+msgid "No rating"
+msgstr "No calificación"
+
+#: bookwyrm/templates/snippets/form_rate_stars.html:45
+#: bookwyrm/templates/snippets/stars.html:7
+#, python-format
+msgid "%(rating)s star"
+msgid_plural "%(rating)s stars"
+msgstr[0] ""
+msgstr[1] ""
+
#: bookwyrm/templates/snippets/generated_status/goal.html:1
#, python-format
msgid "set a goal to read %(counter)s book in %(year)s"
@@ -2311,13 +2388,17 @@ msgstr "Has leído %(read_count)s de %(goal_count)s libros<
msgid "%(username)s has read %(read_count)s of %(goal_count)s books."
msgstr "%(username)s ha leído %(read_count)s de %(goal_count)s libros."
-#: bookwyrm/templates/snippets/pagination.html:7
-msgid "Previous"
-msgstr "Anterior"
+#: bookwyrm/templates/snippets/page_text.html:4
+#, fuzzy, python-format
+#| msgid "of %(pages)s pages"
+msgid "page %(page)s of %(total_pages)s"
+msgstr "de %(pages)s páginas"
-#: bookwyrm/templates/snippets/pagination.html:15
-msgid "Next"
-msgstr "Siguiente"
+#: bookwyrm/templates/snippets/page_text.html:6
+#, fuzzy, python-format
+#| msgid "%(pages)s pages"
+msgid "page %(page)s"
+msgstr "%(pages)s páginas"
#: bookwyrm/templates/snippets/privacy-icons.html:3
#: bookwyrm/templates/snippets/privacy-icons.html:4
@@ -2348,7 +2429,7 @@ msgstr "Seguidores"
msgid "Leave a rating"
msgstr "Da una calificación"
-#: bookwyrm/templates/snippets/rate_action.html:29
+#: bookwyrm/templates/snippets/rate_action.html:19
msgid "Rate"
msgstr "Calificar"
@@ -2356,28 +2437,28 @@ msgstr "Calificar"
msgid "Progress Updates:"
msgstr "Actualizaciones de progreso:"
-#: bookwyrm/templates/snippets/readthrough.html:12
+#: bookwyrm/templates/snippets/readthrough.html:14
msgid "finished"
msgstr "terminado"
-#: bookwyrm/templates/snippets/readthrough.html:15
+#: bookwyrm/templates/snippets/readthrough.html:25
msgid "Show all updates"
msgstr "Mostrar todas las actualizaciones"
-#: bookwyrm/templates/snippets/readthrough.html:31
+#: bookwyrm/templates/snippets/readthrough.html:41
msgid "Delete this progress update"
msgstr "Eliminar esta actualización de progreso"
-#: bookwyrm/templates/snippets/readthrough.html:41
+#: bookwyrm/templates/snippets/readthrough.html:51
msgid "started"
msgstr "empezado"
-#: bookwyrm/templates/snippets/readthrough.html:47
-#: bookwyrm/templates/snippets/readthrough.html:61
+#: bookwyrm/templates/snippets/readthrough.html:57
+#: bookwyrm/templates/snippets/readthrough.html:71
msgid "Edit read dates"
msgstr "Editar fechas de lectura"
-#: bookwyrm/templates/snippets/readthrough.html:51
+#: bookwyrm/templates/snippets/readthrough.html:61
msgid "Delete these read dates"
msgstr "Eliminar estas fechas de lectura"
@@ -2501,9 +2582,9 @@ msgstr "respaldó"
msgid "Delete status"
msgstr "Eliminar status"
-#: bookwyrm/templates/snippets/status/status_body.html:34
-#: bookwyrm/templates/snippets/status/status_body.html:47
+#: bookwyrm/templates/snippets/status/status_body.html:35
#: bookwyrm/templates/snippets/status/status_body.html:48
+#: bookwyrm/templates/snippets/status/status_body.html:49
msgid "Reply"
msgstr "Respuesta"
@@ -2550,6 +2631,12 @@ msgstr "respondió a tu tag or including the “Referrer-Policy: no-referrer” header, please remove them. The CSRF protection requires the “Referer” header to do strict referer checking. If you’re concerned about privacy, use alternatives like for links to third-party sites."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/csrf.py:132
+msgid "You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/csrf.py:137
+msgid "If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/csrf.py:142
+msgid "More information is available with DEBUG=True."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:41
+msgid "No year specified"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:61
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:111
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:208
+msgid "Date out of range"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:90
+msgid "No month specified"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:142
+msgid "No day specified"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:188
+msgid "No week specified"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:338
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:367
+#, python-format
+msgid "No %(verbose_name_plural)s available"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:589
+#, python-format
+msgid "Future %(verbose_name_plural)s not available because %(class_name)s.allow_future is False."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/dates.py:623
+#, python-format
+msgid "Invalid date string “%(datestr)s” given format “%(format)s”"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/detail.py:54
+#, fuzzy, python-format
+#| msgid "No books found matching the query \"%(query)s\""
+msgid "No %(verbose_name)s found matching the query"
+msgstr "No se encontró ningún libro correspondiente a la búsqueda: \"%(query)s\""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/list.py:67
+msgid "Page is not “last”, nor can it be converted to an int."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/list.py:72
+#, python-format
+msgid "Invalid page (%(page_number)s): %(message)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/generic/list.py:154
+#, python-format
+msgid "Empty list and “%(class_name)s.allow_empty” is False."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/static.py:40
+msgid "Directory indexes are not allowed here."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/static.py:42
+#, fuzzy, python-format
+#| msgid "%(value)s is not a valid username"
+msgid "“%(path)s” does not exist"
+msgstr "%(value)s no es un usuario válido"
+
+#: venv/lib/python3.8/site-packages/django/views/static.py:80
+#, python-format
+msgid "Index of %(directory)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:7
+msgid "Django: the Web framework for perfectionists with deadlines."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:346
+#, python-format
+msgid "View release notes for Django %(version)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:368
+msgid "The install worked successfully! Congratulations!"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:369
+#, python-format
+msgid "You are seeing this page because DEBUG=True is in your settings file and you have not configured any URLs."
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:384
+msgid "Django Documentation"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:385
+msgid "Topics, references, & how-to’s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:396
+msgid "Tutorial: A Polling App"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:397
+msgid "Get started with Django"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:408
+#, fuzzy
+#| msgid "Comment"
+msgid "Django Community"
+msgstr "Comentario"
+
+#: venv/lib/python3.8/site-packages/django/views/templates/default_urlconf.html:409
+msgid "Connect, get help, or contribute"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/kombu/transport/qpid.py:1301
+#, python-format
+msgid "Attempting to connect to qpid with SASL mechanism %s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/kombu/transport/qpid.py:1306
+#, python-format
+msgid "Connected to qpid with SASL mechanism %s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/kombu/transport/qpid.py:1324
+#, python-format
+msgid "Unable to connect to qpid with SASL mechanism %s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:371
+msgid "1 second ago"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:377
+msgid "1 minute ago"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:382
+msgid "1 hour ago"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:385
+#, python-format
+msgid "%(time)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:387
+msgid "yesterday"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:387
+#, python-format
+msgid "yesterday at %(time)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:389
+#, python-format
+msgid "%(weekday)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:389
+#, python-format
+msgid "%(weekday)s at %(time)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:392
+#: venv/lib/python3.8/site-packages/tornado/locale.py:445
+#, python-format
+msgid "%(month_name)s %(day)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:394
+#, python-format
+msgid "%(month_name)s %(day)s at %(time)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:399
+#, python-format
+msgid "%(month_name)s %(day)s, %(year)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:401
+#, python-format
+msgid "%(month_name)s %(day)s, %(year)s at %(time)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:439
+#, python-format
+msgid "%(weekday)s, %(month_name)s %(day)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/locale.py:462
+#, python-format
+msgid "%(commas)s and %(last)s"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:68
+msgctxt "law"
+msgid "right"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:69
+msgctxt "good"
+msgid "right"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:71
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:74
+msgctxt "organization"
+msgid "club"
+msgstr ""
+
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:76
+#: venv/lib/python3.8/site-packages/tornado/test/locale_test.py:77
+msgctxt "stick"
+msgid "club"
+msgstr ""
+
#, fuzzy
#~| msgid "Started"
#~ msgid "Getting Started"
#~ msgstr "Empezado"
-#, fuzzy, python-format
+#, fuzzy
#~| msgid "No users found for \"%(query)s\""
#~ msgid "No users were found for \"%(query)s\""
#~ msgstr "No se encontró ningún usuario correspondiente a \"%(query)s\""
@@ -2757,7 +4188,6 @@ msgstr ""
#~ msgid "Your lists"
#~ msgstr "Tus listas"
-#, python-format
#~ msgid "See all %(size)s lists"
#~ msgstr "Ver las %(size)s listas"
@@ -2782,148 +4212,18 @@ msgstr ""
#~ msgid "Your Shelves"
#~ msgstr "Tus estantes"
-#, python-format
#~ msgid "%(username)s: Shelves"
#~ msgstr "%(username)s: Estantes"
#~ msgid "Shelves"
#~ msgstr "Estantes"
-#, python-format
#~ msgid "See all %(shelf_count)s shelves"
#~ msgstr "Ver los %(shelf_count)s estantes"
#~ msgid "Send follow request"
#~ msgstr "Envia solicitud de seguidor"
-#, fuzzy
-#~| msgid "All messages"
-#~ msgid "Messages"
-#~ msgstr "Todos los mensajes"
-
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "Enter a valid email address."
-#~ msgstr "Dirección de correo electrónico:"
-
-#, fuzzy
-#~| msgid "Series number:"
-#~ msgid "Enter a number."
-#~ msgstr "Número de serie:"
-
-#, fuzzy
-#~| msgid "%(value)s is not a valid remote_id"
-#~ msgid "Value %(value)r is not a valid choice."
-#~ msgstr "%(value)s no es un remote_id válido"
-
-#, fuzzy
-#~| msgid "Series number:"
-#~ msgid "Decimal number"
-#~ msgstr "Número de serie:"
-
-#, fuzzy
-#~| msgid "List curation:"
-#~ msgid "Duration"
-#~ msgstr "Enumerar lista de comisariado:"
-
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "Email address"
-#~ msgstr "Dirección de correo electrónico:"
-
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "IPv4 address"
-#~ msgstr "Dirección de correo electrónico:"
-
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "IP address"
-#~ msgstr "Dirección de correo electrónico:"
-
-#, fuzzy
-#~| msgid "No active invites"
-#~ msgid "Positive integer"
-#~ msgstr "No invitaciónes activas"
-
-#, fuzzy
-#~| msgid "%(value)s is not a valid username"
-#~ msgid "“%(value)s” is not a valid UUID."
-#~ msgstr "%(value)s no es un usuario válido"
-
-#, fuzzy
-#~| msgid "Images"
-#~ msgid "Image"
-#~ msgstr "Imagenes"
-
-#, fuzzy
-#~| msgid "Relationships"
-#~ msgid "One-to-one relationship"
-#~ msgstr "Relaciones"
-
-#, fuzzy
-#~| msgid "This shelf is empty."
-#~ msgid "This field is required."
-#~ msgstr "Este estante está vacio."
-
-#, fuzzy
-#~| msgid "This shelf is empty."
-#~ msgid "The submitted file is empty."
-#~ msgstr "Este estante está vacio."
-
-#, fuzzy
-#~| msgid "%(value)s is not a valid username"
-#~ msgid "“%(pk)s” is not a valid value."
-#~ msgstr "%(value)s no es un usuario válido"
-
-#, fuzzy
-#~| msgid "Currently Reading"
-#~ msgid "Currently"
-#~ msgstr "Leyendo actualmente"
-
-#, fuzzy
-#~| msgid "Change shelf"
-#~ msgid "Change"
-#~ msgstr "Cambiar estante"
-
-#, fuzzy
-#~| msgid "Status"
-#~ msgid "Sat"
-#~ msgstr "Status"
-
-#, fuzzy
-#~| msgid "Search"
-#~ msgid "March"
-#~ msgstr "Buscar"
-
-#, fuzzy
-#~| msgid "Series number:"
-#~ msgid "September"
-#~ msgstr "Número de serie:"
-
-#, fuzzy
-#~| msgid "Search"
-#~ msgctxt "abbrev. month"
-#~ msgid "March"
-#~ msgstr "Buscar"
-
-#, fuzzy
-#~| msgid "Search"
-#~ msgctxt "alt. month"
-#~ msgid "March"
-#~ msgstr "Buscar"
-
-#, fuzzy
-#~| msgid "Series number:"
-#~ msgctxt "alt. month"
-#~ msgid "September"
-#~ msgstr "Número de serie:"
-
-#, fuzzy
-#~| msgid "No books found matching the query \"%(query)s\""
-#~ msgid "No %(verbose_name)s found matching the query"
-#~ msgstr "No se encontró ningún libro correspondiente a la búsqueda: \"%(query)s\""
-
#~ msgid "Announcements"
#~ msgstr "Anuncios"