diff --git a/.gitignore b/.gitignore index 624ce100c..e5582694a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.swp **/__pycache__ .local +/nginx/nginx.conf # VSCode /.vscode diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index c032986d1..bb2bfb6f9 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -111,7 +111,7 @@ class AbstractConnector(AbstractMinimalConnector): return existing.default_edition return existing - # load the json + # load the json data from the remote data source data = self.get_book_data(remote_id) if self.is_work_data(data): try: @@ -150,27 +150,37 @@ class AbstractConnector(AbstractMinimalConnector): """this allows connectors to override the default behavior""" return get_data(remote_id) - def create_edition_from_data(self, work, edition_data): + def create_edition_from_data(self, work, edition_data, instance=None): """if we already have the work, we're ready""" mapped_data = dict_from_mappings(edition_data, self.book_mappings) mapped_data["work"] = work.remote_id edition_activity = activitypub.Edition(**mapped_data) - edition = edition_activity.to_model(model=models.Edition, overwrite=False) - edition.connector = self.connector - edition.save() + edition = edition_activity.to_model( + model=models.Edition, overwrite=False, instance=instance + ) + + # if we're updating an existing instance, we don't need to load authors + if instance: + return edition + + if not edition.connector: + edition.connector = self.connector + edition.save(broadcast=False, update_fields=["connector"]) for author in self.get_authors_from_data(edition_data): edition.authors.add(author) + # use the authors from the work if none are found for the edition if not edition.authors.exists() and work.authors.exists(): edition.authors.set(work.authors.all()) return edition - def get_or_create_author(self, remote_id): + def get_or_create_author(self, remote_id, instance=None): """load that author""" - existing = models.Author.find_existing_by_remote_id(remote_id) - if existing: - return existing + if not instance: + existing = models.Author.find_existing_by_remote_id(remote_id) + if existing: + return existing data = self.get_book_data(remote_id) @@ -181,7 +191,24 @@ class AbstractConnector(AbstractMinimalConnector): return None # this will dedupe - return activity.to_model(model=models.Author, overwrite=False) + return activity.to_model( + model=models.Author, overwrite=False, instance=instance + ) + + def get_remote_id_from_model(self, obj): + """given the data stored, how can we look this up""" + return getattr(obj, getattr(self, "generated_remote_link_field")) + + def update_author_from_remote(self, obj): + """load the remote data from this connector and add it to an existing author""" + remote_id = self.get_remote_id_from_model(obj) + return self.get_or_create_author(remote_id, instance=obj) + + def update_book_from_remote(self, obj): + """load the remote data from this connector and add it to an existing book""" + remote_id = self.get_remote_id_from_model(obj) + data = self.get_book_data(remote_id) + return self.create_edition_from_data(obj.parent_work, data, instance=obj) @abstractmethod def is_work_data(self, data): diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index e9f538569..a9aeb94f9 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -11,6 +11,8 @@ from .connector_manager import ConnectorException class Connector(AbstractConnector): """instantiate a connector for inventaire""" + generated_remote_link_field = "inventaire_id" + def __init__(self, identifier): super().__init__(identifier) @@ -210,6 +212,11 @@ class Connector(AbstractConnector): return "" return data.get("extract") + def get_remote_id_from_model(self, obj): + """use get_remote_id to figure out the link from a model obj""" + remote_id_value = obj.inventaire_id + return self.get_remote_id(remote_id_value) + def get_language_code(options, code="en"): """when there are a bunch of translation but we need a single field""" diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index b8afc7ca6..c15277f84 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -12,6 +12,8 @@ from .openlibrary_languages import languages class Connector(AbstractConnector): """instantiate a connector for OL""" + generated_remote_link_field = "openlibrary_link" + def __init__(self, identifier): super().__init__(identifier) @@ -66,6 +68,7 @@ class Connector(AbstractConnector): Mapping("born", remote_field="birth_date"), Mapping("died", remote_field="death_date"), Mapping("bio", formatter=get_description), + Mapping("isni", remote_field="remote_ids", formatter=get_isni), ] def get_book_data(self, remote_id): @@ -224,6 +227,13 @@ def get_languages(language_blob): return langs +def get_isni(remote_ids_blob): + """extract the isni from the remote id data for the author""" + if not remote_ids_blob or not isinstance(remote_ids_blob, dict): + return None + return remote_ids_blob.get("isni") + + def pick_default_edition(options): """favor physical copies with covers in english""" if not options: diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 249b92113..7ba7bd97b 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -9,6 +9,7 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from bookwyrm import models +from bookwyrm.models.fields import ClearableFileInputWithWarning from bookwyrm.models.user import FeedFilterChoices @@ -148,6 +149,17 @@ class EditUserForm(CustomForm): "preferred_language", ] help_texts = {f: None for f in fields} + widgets = { + "avatar": ClearableFileInputWithWarning( + attrs={"aria-describedby": "desc_avatar"} + ), + "name": forms.TextInput(attrs={"aria-describedby": "desc_name"}), + "summary": forms.Textarea(attrs={"aria-describedby": "desc_summary"}), + "email": forms.EmailInput(attrs={"aria-describedby": "desc_email"}), + "discoverable": forms.CheckboxInput( + attrs={"aria-describedby": "desc_discoverable"} + ), + } class LimitedEditUserForm(CustomForm): @@ -161,6 +173,16 @@ class LimitedEditUserForm(CustomForm): "discoverable", ] help_texts = {f: None for f in fields} + widgets = { + "avatar": ClearableFileInputWithWarning( + attrs={"aria-describedby": "desc_avatar"} + ), + "name": forms.TextInput(attrs={"aria-describedby": "desc_name"}), + "summary": forms.Textarea(attrs={"aria-describedby": "desc_summary"}), + "discoverable": forms.CheckboxInput( + attrs={"aria-describedby": "desc_discoverable"} + ), + } class DeleteUserForm(CustomForm): @@ -209,6 +231,51 @@ class EditionForm(CustomForm): "connector", "search_vector", ] + widgets = { + "title": forms.TextInput(attrs={"aria-describedby": "desc_title"}), + "subtitle": forms.TextInput(attrs={"aria-describedby": "desc_subtitle"}), + "description": forms.Textarea( + attrs={"aria-describedby": "desc_description"} + ), + "series": forms.TextInput(attrs={"aria-describedby": "desc_series"}), + "series_number": forms.TextInput( + attrs={"aria-describedby": "desc_series_number"} + ), + "languages": forms.TextInput( + attrs={"aria-describedby": "desc_languages_help desc_languages"} + ), + "publishers": forms.TextInput( + attrs={"aria-describedby": "desc_publishers_help desc_publishers"} + ), + "first_published_date": forms.SelectDateWidget( + attrs={"aria-describedby": "desc_first_published_date"} + ), + "published_date": forms.SelectDateWidget( + attrs={"aria-describedby": "desc_published_date"} + ), + "cover": ClearableFileInputWithWarning( + attrs={"aria-describedby": "desc_cover"} + ), + "physical_format": forms.Select( + attrs={"aria-describedby": "desc_physical_format"} + ), + "physical_format_detail": forms.TextInput( + attrs={"aria-describedby": "desc_physical_format_detail"} + ), + "pages": forms.NumberInput(attrs={"aria-describedby": "desc_pages"}), + "isbn_13": forms.TextInput(attrs={"aria-describedby": "desc_isbn_13"}), + "isbn_10": forms.TextInput(attrs={"aria-describedby": "desc_isbn_10"}), + "openlibrary_key": forms.TextInput( + attrs={"aria-describedby": "desc_openlibrary_key"} + ), + "inventaire_id": forms.TextInput( + attrs={"aria-describedby": "desc_inventaire_id"} + ), + "oclc_number": forms.TextInput( + attrs={"aria-describedby": "desc_oclc_number"} + ), + "ASIN": forms.TextInput(attrs={"aria-describedby": "desc_ASIN"}), + } class AuthorForm(CustomForm): @@ -226,7 +293,30 @@ class AuthorForm(CustomForm): "inventaire_id", "librarything_key", "goodreads_key", + "isni", ] + widgets = { + "name": forms.TextInput(attrs={"aria-describedby": "desc_name"}), + "aliases": forms.TextInput(attrs={"aria-describedby": "desc_aliases"}), + "bio": forms.Textarea(attrs={"aria-describedby": "desc_bio"}), + "wikipedia_link": forms.TextInput( + attrs={"aria-describedby": "desc_wikipedia_link"} + ), + "born": forms.SelectDateWidget(attrs={"aria-describedby": "desc_born"}), + "died": forms.SelectDateWidget(attrs={"aria-describedby": "desc_died"}), + "oepnlibrary_key": forms.TextInput( + attrs={"aria-describedby": "desc_oepnlibrary_key"} + ), + "inventaire_id": forms.TextInput( + attrs={"aria-describedby": "desc_inventaire_id"} + ), + "librarything_key": forms.TextInput( + attrs={"aria-describedby": "desc_librarything_key"} + ), + "goodreads_key": forms.TextInput( + attrs={"aria-describedby": "desc_goodreads_key"} + ), + } class ImportForm(forms.Form): @@ -301,12 +391,37 @@ class SiteForm(CustomForm): class Meta: model = models.SiteSettings exclude = [] + widgets = { + "instance_short_description": forms.TextInput( + attrs={"aria-describedby": "desc_instance_short_description"} + ), + "require_confirm_email": forms.CheckboxInput( + attrs={"aria-describedby": "desc_require_confirm_email"} + ), + "invite_request_text": forms.Textarea( + attrs={"aria-describedby": "desc_invite_request_text"} + ), + } class AnnouncementForm(CustomForm): class Meta: model = models.Announcement exclude = ["remote_id"] + widgets = { + "preview": forms.TextInput(attrs={"aria-describedby": "desc_preview"}), + "content": forms.Textarea(attrs={"aria-describedby": "desc_content"}), + "event_date": forms.SelectDateWidget( + attrs={"aria-describedby": "desc_event_date"} + ), + "start_date": forms.SelectDateWidget( + attrs={"aria-describedby": "desc_start_date"} + ), + "end_date": forms.SelectDateWidget( + attrs={"aria-describedby": "desc_end_date"} + ), + "active": forms.CheckboxInput(attrs={"aria-describedby": "desc_active"}), + } class ListForm(CustomForm): @@ -331,6 +446,9 @@ class EmailBlocklistForm(CustomForm): class Meta: model = models.EmailBlocklist fields = ["domain"] + widgets = { + "avatar": forms.TextInput(attrs={"aria-describedby": "desc_domain"}), + } class IPBlocklistForm(CustomForm): diff --git a/bookwyrm/models/author.py b/bookwyrm/models/author.py index 6c29ac058..5cc11afd6 100644 --- a/bookwyrm/models/author.py +++ b/bookwyrm/models/author.py @@ -1,4 +1,5 @@ """ database schema for info about authors """ +import re from django.contrib.postgres.indexes import GinIndex from django.db import models @@ -33,6 +34,17 @@ class Author(BookDataModel): ) bio = fields.HtmlField(null=True, blank=True) + @property + def isni_link(self): + """generate the url from the isni id""" + clean_isni = re.sub(r"\s", "", self.isni) + return f"https://isni.org/isni/{clean_isni}" + + @property + def openlibrary_link(self): + """generate the url from the openlibrary id""" + return f"https://openlibrary.org/authors/{self.openlibrary_key}" + def get_remote_id(self): """editions and works both use "book" instead of model_name""" return f"https://{DOMAIN}/author/{self.id}" diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index d97a1b8a6..0a551bf28 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -52,6 +52,16 @@ class BookDataModel(ObjectMixin, BookWyrmModel): null=True, ) + @property + def openlibrary_link(self): + """generate the url from the openlibrary id""" + return f"https://openlibrary.org/books/{self.openlibrary_key}" + + @property + def inventaire_link(self): + """generate the url from the inventaire id""" + return f"https://inventaire.io/entity/{self.inventaire_id}" + class Meta: """can't initialize this model, that wouldn't make sense""" diff --git a/bookwyrm/preview_images.py b/bookwyrm/preview_images.py index 32465d6ed..a97ae2d5c 100644 --- a/bookwyrm/preview_images.py +++ b/bookwyrm/preview_images.py @@ -49,6 +49,28 @@ def get_font(font_name, size=28): return font +def get_wrapped_text(text, font, content_width): + """text wrap length depends on the max width of the content""" + + low = 0 + high = len(text) + + try: + # ideal length is determined via binary search + while low < high: + mid = math.floor(low + high) + wrapped_text = textwrap.fill(text, width=mid) + width = font.getsize_multiline(wrapped_text)[0] + if width < content_width: + low = mid + else: + high = mid - 1 + except AttributeError: + wrapped_text = text + + return wrapped_text + + def generate_texts_layer(texts, content_width): """Adds text for images""" font_text_zero = get_font("bold", size=20) @@ -63,7 +85,8 @@ def generate_texts_layer(texts, content_width): if "text_zero" in texts and texts["text_zero"]: # Text one (Book title) - text_zero = textwrap.fill(texts["text_zero"], width=72) + text_zero = get_wrapped_text(texts["text_zero"], font_text_zero, content_width) + text_layer_draw.multiline_text( (0, text_y), text_zero, font=font_text_zero, fill=TEXT_COLOR ) @@ -75,7 +98,8 @@ def generate_texts_layer(texts, content_width): if "text_one" in texts and texts["text_one"]: # Text one (Book title) - text_one = textwrap.fill(texts["text_one"], width=28) + text_one = get_wrapped_text(texts["text_one"], font_text_one, content_width) + text_layer_draw.multiline_text( (0, text_y), text_one, font=font_text_one, fill=TEXT_COLOR ) @@ -87,7 +111,8 @@ def generate_texts_layer(texts, content_width): if "text_two" in texts and texts["text_two"]: # Text one (Book subtitle) - text_two = textwrap.fill(texts["text_two"], width=36) + text_two = get_wrapped_text(texts["text_two"], font_text_two, content_width) + text_layer_draw.multiline_text( (0, text_y), text_two, font=font_text_two, fill=TEXT_COLOR ) @@ -99,7 +124,10 @@ def generate_texts_layer(texts, content_width): if "text_three" in texts and texts["text_three"]: # Text three (Book authors) - text_three = textwrap.fill(texts["text_three"], width=36) + text_three = get_wrapped_text( + texts["text_three"], font_text_three, content_width + ) + text_layer_draw.multiline_text( (0, text_y), text_three, font=font_text_three, fill=TEXT_COLOR ) diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index d6c0b5d5e..e95ff96e2 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -14,7 +14,7 @@ VERSION = "0.1.0" PAGE_LENGTH = env("PAGE_LENGTH", 15) DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English") -JS_CACHE = "3eb4edb1" +JS_CACHE = "3891b373" # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") diff --git a/bookwyrm/static/css/bookwyrm.css b/bookwyrm/static/css/bookwyrm.css index 2b6a122f6..f385e6295 100644 --- a/bookwyrm/static/css/bookwyrm.css +++ b/bookwyrm/static/css/bookwyrm.css @@ -119,6 +119,34 @@ input[type=file]::file-selector-button:hover { color: #363636; } +details .dropdown-menu { + display: block !important; +} + +details.dropdown[open] summary.dropdown-trigger::before { + content: ""; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +summary::marker { + content: none; +} + +.detail-pinned-button summary { + position: absolute; + right: 0; +} + +.detail-pinned-button form { + float: left; + width: -webkit-fill-available; + margin-top: 1em; +} + /** Shelving ******************************************************************************/ diff --git a/bookwyrm/static/css/fonts/icomoon.eot b/bookwyrm/static/css/fonts/icomoon.eot index 8eba8692f..7b1f2d9d9 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.eot and b/bookwyrm/static/css/fonts/icomoon.eot differ diff --git a/bookwyrm/static/css/fonts/icomoon.svg b/bookwyrm/static/css/fonts/icomoon.svg index 82e413294..7dbbe0dc5 100644 --- a/bookwyrm/static/css/fonts/icomoon.svg +++ b/bookwyrm/static/css/fonts/icomoon.svg @@ -46,4 +46,5 @@ + \ No newline at end of file diff --git a/bookwyrm/static/css/fonts/icomoon.ttf b/bookwyrm/static/css/fonts/icomoon.ttf index 5bf90a0a7..151f2b782 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.ttf and b/bookwyrm/static/css/fonts/icomoon.ttf differ diff --git a/bookwyrm/static/css/fonts/icomoon.woff b/bookwyrm/static/css/fonts/icomoon.woff index 6ce6834d5..bc0818413 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.woff and b/bookwyrm/static/css/fonts/icomoon.woff differ diff --git a/bookwyrm/static/css/vendor/icons.css b/bookwyrm/static/css/vendor/icons.css index b43224e34..9c35b1be7 100644 --- a/bookwyrm/static/css/vendor/icons.css +++ b/bookwyrm/static/css/vendor/icons.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('../fonts/icomoon.eot?36x4a3'); - src: url('../fonts/icomoon.eot?36x4a3#iefix') format('embedded-opentype'), - url('../fonts/icomoon.ttf?36x4a3') format('truetype'), - url('../fonts/icomoon.woff?36x4a3') format('woff'), - url('../fonts/icomoon.svg?36x4a3#icomoon') format('svg'); + src: url('../fonts/icomoon.eot?r7jc98'); + src: url('../fonts/icomoon.eot?r7jc98#iefix') format('embedded-opentype'), + url('../fonts/icomoon.ttf?r7jc98') format('truetype'), + url('../fonts/icomoon.woff?r7jc98') format('woff'), + url('../fonts/icomoon.svg?r7jc98#icomoon') format('svg'); font-weight: normal; font-style: normal; font-display: block; @@ -142,3 +142,6 @@ .icon-spinner:before { content: "\e97a"; } +.icon-download:before { + content: "\ea36"; +} diff --git a/bookwyrm/static/js/bookwyrm.js b/bookwyrm/static/js/bookwyrm.js index a78260db1..2b78bf518 100644 --- a/bookwyrm/static/js/bookwyrm.js +++ b/bookwyrm/static/js/bookwyrm.js @@ -414,6 +414,21 @@ let BookWyrm = new class { } } + /** + * Display pop up window. + * + * @param {string} url Url to open + * @param {string} windowName windowName + * @return {undefined} + */ + displayPopUp(url, windowName) { + window.open( + url, + windowName, + "left=100,top=100,width=430,height=600" + ); + } + duplicateInput (event ) { const trigger = event.currentTarget; const input_id = trigger.dataset['duplicate'] diff --git a/bookwyrm/static/js/status_cache.js b/bookwyrm/static/js/status_cache.js index 418b7dee2..dbc238c48 100644 --- a/bookwyrm/static/js/status_cache.js +++ b/bookwyrm/static/js/status_cache.js @@ -210,10 +210,10 @@ let StatusCache = new class { .forEach(item => BookWyrm.addRemoveClass(item, "is-hidden", true)); // Close menu - let menu = button.querySelector(".dropdown-trigger[aria-expanded=true]"); + let menu = button.querySelector("details[open]"); if (menu) { - menu.click(); + menu.removeAttribute("open"); } } diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index b066c6ca4..66ecb0625 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -14,7 +14,7 @@ {% if request.user.is_authenticated and perms.bookwyrm.edit_book %}
- + {% trans "Edit Author" %} @@ -23,102 +23,130 @@
-
+
+ {% if author.bio %} +
+ {% include "snippets/trimmed_text.html" with full=author.bio trim_length=200 %} +
+ {% endif %} - {% if author.aliases or author.born or author.died or author.wikipedia_link or author.openlibrary_key or author.inventaire_id or author.isni %} + {% firstof author.aliases author.born author.died as details %} + {% firstof author.wikipedia_link author.openlibrary_key author.inventaire_id author.isni as links %} + {% if details or links %}
-
-
+ {% if details %} +
+

{% trans "Author details" %}

+
{% if author.aliases %} -
+
{% trans "Aliases:" %}
- {% for alias in author.aliases %} -
- {{alias}}{% if not forloop.last %}, {% endif %} -
- {% endfor %} +
+ {% include "snippets/trimmed_list.html" with items=author.aliases itemprop="alternateName" %} +
{% endif %} {% if author.born %} -
+
{% trans "Born:" %}
{{ author.born|naturalday }}
{% endif %} {% if author.died %} -
+
{% trans "Died:" %}
{{ author.died|naturalday }}
{% endif %}
+
+ {% endif %} - {% if author.wikipedia_link %} -

- - {% trans "Wikipedia" %} - -

- {% endif %} + {% if links %} +
+

{% trans "External links" %}

+
+ {% if author.wikipedia_link %} + + {% endif %} - {% if author.isni %} -

- - {% trans "View ISNI record" %} - -

- {% endif %} + {% if author.isni %} + + {% endif %} - {% if author.openlibrary_key %} -

- - {% trans "View on OpenLibrary" %} - -

- {% endif %} + {% trans "Load data" as button_text %} + {% if author.openlibrary_key %} +
+ + {% trans "View on OpenLibrary" %} + + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + {% with controls_text="ol_sync" controls_uid=author.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_ol_sync" class="is-small" icon_with_text="download" %} + {% include "author/sync_modal.html" with source="openlibrary.org" source_name="OpenLibrary" %} + {% endwith %} + {% endif %} +
+ {% endif %} - {% if author.inventaire_id %} -

- - {% trans "View on Inventaire" %} - -

- {% endif %} + {% if author.inventaire_id %} +
+ + {% trans "View on Inventaire" %} + - {% if author.librarything_key %} -

- - {% trans "View on LibraryThing" %} - -

- {% endif %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + {% with controls_text="iv_sync" controls_uid=author.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_iv_sync" class="is-small" icon_with_text="download" %} + {% include "author/sync_modal.html" with source="inventaire.io" source_name="Inventaire" %} + {% endwith %} + {% endif %} +
+ {% endif %} - {% if author.goodreads_key %} -

- - {% trans "View on Goodreads" %} - -

- {% endif %} -
-
- {% endif %} -
- {% if author.bio %} - {{ author.bio|to_markdown|safe }} + {% if author.librarything_key %} + + {% endif %} + + {% if author.goodreads_key %} + + {% endif %} +
+ {% endif %}
+ {% endif %}
+ +
-

{% blocktrans with name=author.name %}Books by {{ name }}{% endblocktrans %}

+

{% blocktrans with name=author.name %}Books by {{ name }}{% endblocktrans %}

{% for book in books %} -
- {% include 'landing/small-book.html' with book=book %} +
+
+ {% include 'landing/small-book.html' with book=book %} +
{% include 'snippets/shelve_button/shelve_button.html' with book=book %}
{% endfor %} diff --git a/bookwyrm/templates/author/edit_author.html b/bookwyrm/templates/author/edit_author.html index 54d7f4f1c..6f72b8700 100644 --- a/bookwyrm/templates/author/edit_author.html +++ b/bookwyrm/templates/author/edit_author.html @@ -34,47 +34,41 @@
{{ form.name }} - {% for error in form.name.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.name.errors id="desc_name" %}
{{ form.aliases }} {% trans "Separate multiple values with commas." %} - {% for error in form.aliases.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.aliases.errors id="desc_aliases" %}
{{ form.bio }} - {% for error in form.bio.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.bio.errors id="desc_bio" %}

{{ form.wikipedia_link }}

- {% for error in form.wikipedia_link.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.wikipedia_link.errors id="desc_wikipedia_link" %}
- {% for error in form.born.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.born.errors id="desc_born" %}
- {% for error in form.died.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.died.errors id="desc_died" %}
@@ -82,33 +76,36 @@
{{ form.openlibrary_key }} - {% for error in form.openlibrary_key.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.oepnlibrary_key.errors id="desc_oepnlibrary_key" %}
{{ form.inventaire_id }} - {% for error in form.inventaire_id.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.inventaire_id.errors id="desc_inventaire_id" %}
{{ form.librarything_key }} - {% for error in form.librarything_key.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.librarything_key.errors id="desc_librarything_key" %}
{{ form.goodreads_key }} - {% for error in form.goodreads_key.errors %} -

{{ error | escape }}

- {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.goodreads_key.errors id="desc_goodreads_key" %} +
+ +
+ + {{ form.isni }} + + {% include 'snippets/form_errors.html' with errors_list=form.isni.errors id="desc_isni" %}
diff --git a/bookwyrm/templates/author/sync_modal.html b/bookwyrm/templates/author/sync_modal.html new file mode 100644 index 000000000..a061ada80 --- /dev/null +++ b/bookwyrm/templates/author/sync_modal.html @@ -0,0 +1,30 @@ +{% extends 'components/modal.html' %} +{% load i18n %} + +{% block modal-title %} +{% trans "Load data" %} +{% endblock %} + +{% block modal-form-open %} +
+ {% csrf_token %} +{% endblock %} + +{% block modal-body %} +

+ {% blocktrans trimmed %} + Loading data will connect to {{ source_name }} and check for any metadata about this author which aren't present here. Existing metadata will not be overwritten. + {% endblocktrans %} +

+{% endblock %} + +{% block modal-footer %} + + +{% trans "Cancel" as button_text %} +{% include 'snippets/toggle/toggle_button.html' with text=button_text %} +{% endblock %} + +{% block modal-form-close %}
{% endblock %} diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index 713e7abee..27d061a28 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -90,11 +90,28 @@
{% endwith %} + {% trans "Load data" as button_text %} {% if book.openlibrary_key %} -

{% trans "View on OpenLibrary" %}

+

+ {% trans "View on OpenLibrary" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + {% with controls_text="ol_sync" controls_uid=book.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_ol_sync" class="is-small" icon_with_text="download" %} + {% include "book/sync_modal.html" with source="openlibrary.org" source_name="OpenLibrary" %} + {% endwith %} + {% endif %} +

{% endif %} {% if book.inventaire_id %} -

{% trans "View on Inventaire" %}

+

+ {% trans "View on Inventaire" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + {% with controls_text="iv_sync" controls_uid=book.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_iv_sync" class="is-small" icon_with_text="download" %} + {% include "book/sync_modal.html" with source="inventaire.io" source_name="Inventaire" %} + {% endwith %} + {% endif %} +

{% endif %}
@@ -160,7 +177,7 @@
    {% for shelf in user_shelfbooks %}
  • - {% blocktrans with path=shelf.shelf.local_path shelf_name=shelf.shelf.name %}{{ shelf_name }}{% endblocktrans %} + {{ shelf.shelf.name }}
    {% include 'snippets/shelf_selector.html' with shelf=shelf.shelf class="is-small" readthrough=readthrough %}
    diff --git a/bookwyrm/templates/book/edit/edit_book_form.html b/bookwyrm/templates/book/edit/edit_book_form.html index 25d24e43d..fd2516a66 100644 --- a/bookwyrm/templates/book/edit/edit_book_form.html +++ b/bookwyrm/templates/book/edit/edit_book_form.html @@ -12,106 +12,125 @@
    -

    {% trans "Metadata" %}

    +

    + {% trans "Metadata" %} +

    - - - {% for error in form.title.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.title.errors id="desc_title" %}
    - - - {% for error in form.subtitle.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.subtitle.errors id="desc_subtitle" %}
    - + {{ form.description }} - {% for error in form.description.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.description.errors id="desc_description" %}
    - - - {% for error in form.series.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.series.errors id="desc_series" %}
    - + {{ form.series_number }} - {% for error in form.series_number.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.series_number.errors id="desc_series_number" %}
    - + {{ form.languages }} - {% trans "Separate multiple values with commas." %} - {% for error in form.languages.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% trans "Separate multiple values with commas." %} + + + {% include 'snippets/form_errors.html' with errors_list=form.languages.errors id="desc_languages" %}
    -

    {% trans "Publication" %}

    +

    + {% trans "Publication" %} +

    - + {{ form.publishers }} - {% trans "Separate multiple values with commas." %} - {% for error in form.publishers.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% trans "Separate multiple values with commas." %} + + + {% include 'snippets/form_errors.html' with errors_list=form.publishers.errors id="desc_publishers" %}
    - - - {% for error in form.first_published_date.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.first_published_date.errors id="desc_first_published_date" %}
    - - - {% for error in form.published_date.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.published_date.errors id="desc_published_date" %}
    -

    {% trans "Authors" %}

    +

    + {% trans "Authors" %} +

    {% if book.authors.exists %}
    {% for author in book.authors.all %}
    -

    +

    {% blocktrans with name=author.name %}Author page for {{ name }}{% endblocktrans %}

    @@ -119,7 +138,9 @@
    {% endif %}
    - + {% for author in add_author %} @@ -135,7 +156,9 @@
    -

    {% trans "Cover" %}

    +

    + {% trans "Cover" %} +

    {% if book.cover %} @@ -146,108 +169,122 @@
    - + {{ form.cover }}
    - +
    - {% for error in form.cover.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.cover.errors id="desc_cover" %}
    -

    {% trans "Physical Properties" %}

    +

    + {% trans "Physical Properties" %} +

    - +
    {{ form.physical_format }}
    - {% for error in form.physical_format.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.physical_format.errors id="desc_physical_format" %}
    - + {{ form.physical_format_detail }} - {% for error in form.physical_format_detail.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.physical_format_detail.errors id="desc_physical_format_detail" %}
    - + {{ form.pages }} - {% for error in form.pages.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.pages.errors id="desc_pages" %}
    -

    {% trans "Book Identifiers" %}

    +

    + {% trans "Book Identifiers" %} +

    - + {{ form.isbn_13 }} - {% for error in form.isbn_13.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.isbn_13.errors id="desc_isbn_13" %}
    - + {{ form.isbn_10 }} - {% for error in form.isbn_10.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.isbn_10.errors id="desc_isbn_10" %}
    - + {{ form.openlibrary_key }} - {% for error in form.openlibrary_key.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.openlibrary_key.errors id="desc_openlibrary_key" %}
    - + {{ form.inventaire_id }} - {% for error in form.inventaire_id.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.inventaire_id.errors id="desc_inventaire_id" %}
    - + {{ form.oclc_number }} - {% for error in form.oclc_number.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.oclc_number.errors id="desc_oclc_number" %}
    - + {{ form.asin }} - {% for error in form.ASIN.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.ASIN.errors id="desc_ASIN" %}
    diff --git a/bookwyrm/templates/book/sync_modal.html b/bookwyrm/templates/book/sync_modal.html new file mode 100644 index 000000000..d80bf25fd --- /dev/null +++ b/bookwyrm/templates/book/sync_modal.html @@ -0,0 +1,30 @@ +{% extends 'components/modal.html' %} +{% load i18n %} + +{% block modal-title %} +{% trans "Load data" %} +{% endblock %} + +{% block modal-form-open %} +
    + {% csrf_token %} +{% endblock %} + +{% block modal-body %} +

    + {% blocktrans trimmed %} + Loading data will connect to {{ source_name }} and check for any metadata about this book which aren't present here. Existing metadata will not be overwritten. + {% endblocktrans %} +

    +{% endblock %} + +{% block modal-footer %} + + +{% trans "Cancel" as button_text %} +{% include 'snippets/toggle/toggle_button.html' with text=button_text %} +{% endblock %} + +{% block modal-form-close %}
    {% endblock %} diff --git a/bookwyrm/templates/components/dropdown.html b/bookwyrm/templates/components/dropdown.html index 98291bc96..b3710271a 100644 --- a/bookwyrm/templates/components/dropdown.html +++ b/bookwyrm/templates/components/dropdown.html @@ -2,25 +2,20 @@ {% load utilities %} {% with 0|uuid as uuid %} - @@ -31,9 +29,8 @@
    {{ form.avatar }} - {% for error in form.avatar.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.avatar.errors id="desc_avatar" %}
    diff --git a/bookwyrm/templates/landing/layout.html b/bookwyrm/templates/landing/layout.html index 0d6f231c1..56985768f 100644 --- a/bookwyrm/templates/landing/layout.html +++ b/bookwyrm/templates/landing/layout.html @@ -65,10 +65,9 @@ {% csrf_token %}
    - - {% for error in request_form.email.errors %} -

    {{ error|escape }}

    - {% endfor %} + + + {% include 'snippets/form_errors.html' with errors_list=request_form.email.errors id="desc_request_email" %}
    diff --git a/bookwyrm/templates/landing/login.html b/bookwyrm/templates/landing/login.html index 95baa06de..c9ac25261 100644 --- a/bookwyrm/templates/landing/login.html +++ b/bookwyrm/templates/landing/login.html @@ -26,11 +26,10 @@
    - +
    - {% for error in login_form.password.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=login_form.password.errors id="desc_password" %}
    diff --git a/bookwyrm/templates/landing/password_reset.html b/bookwyrm/templates/landing/password_reset.html index be1dccf81..8348efd4f 100644 --- a/bookwyrm/templates/landing/password_reset.html +++ b/bookwyrm/templates/landing/password_reset.html @@ -8,21 +8,33 @@

    {% trans "Reset Password" %}

    - {% for error in errors %} -

    {{ error }}

    - {% endfor %} + + {% if errors %} +
    + {% for error in errors %} +

    + {{ error }} +

    + {% endfor %} +
    + + {% endif %}
    {% csrf_token %}
    - +
    - +
    - +
    - +
    diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html index 901c417fd..25aaf1b6b 100644 --- a/bookwyrm/templates/layout.html +++ b/bookwyrm/templates/layout.html @@ -267,5 +267,6 @@ {% block scripts %}{% endblock %} + diff --git a/bookwyrm/templates/lists/list_items.html b/bookwyrm/templates/lists/list_items.html index 9c7e1710c..1191a6264 100644 --- a/bookwyrm/templates/lists/list_items.html +++ b/bookwyrm/templates/lists/list_items.html @@ -7,8 +7,8 @@
    -

    - {{ list.name }} {% include 'snippets/privacy-icons.html' with item=list %} +

    + {{ list.name }} {% include 'snippets/privacy-icons.html' with item=list %}

    {% if request.user.is_authenticated and request.user|saved:list %}
    diff --git a/bookwyrm/templates/ostatus/error.html b/bookwyrm/templates/ostatus/error.html new file mode 100644 index 000000000..fc1dd18d5 --- /dev/null +++ b/bookwyrm/templates/ostatus/error.html @@ -0,0 +1,70 @@ +{% load i18n %} + +{% block content %} +
    + {% if error == 'invalid_username' %} +
    +

    {% blocktrans %}{{ account }} is not a valid username{% endblocktrans %}.

    +

    {% trans 'Check you have the correct username before trying again' %}.

    +
    + {% elif error == 'user_not_found' %} +
    +

    {% blocktrans %}{{ account }} could not be found or {{ remote_domain }} does not support identity discovery{% endblocktrans %}.

    +

    {% trans 'Check you have the correct username before trying again' %}.

    +
    + {% elif error == 'not_supported' %} +
    +

    {% blocktrans %}{{ account }} was found but {{ remote_domain }} does not support 'remote follow'{% endblocktrans %}.

    +

    {% blocktrans %}Try searching for {{ user }} on {{ remote_domain }} instead{% endblocktrans %}.

    +
    + {% elif not request.user.is_authenticated %} + + {% elif error == 'ostatus_subscribe' %} +
    +

    {% blocktrans %}Something went wrong trying to follow {{ account }}{% endblocktrans %}

    +

    {% trans 'Check you have the correct username before trying again.' %}

    +
    + {% elif error == 'is_blocked' %} +
    +

    {% blocktrans %}You have blocked {{ account }}{% endblocktrans %}

    +
    + {% elif error == 'has_blocked' %} +
    +

    {% blocktrans %}{{ account }} has blocked you{% endblocktrans %}

    +
    + {% elif error == 'already_following' %} +
    +

    {% blocktrans %}You are already following {{ account }}{% endblocktrans %}

    +
    + {% elif error == 'already_requested' %} +
    +

    {% blocktrans %}You have already requested to follow {{ account }}{% endblocktrans %}

    +
    + {% endif %} +
    +
    + +
    +{% endblock %} diff --git a/bookwyrm/templates/ostatus/remote_follow.html b/bookwyrm/templates/ostatus/remote_follow.html new file mode 100644 index 000000000..ca47c529b --- /dev/null +++ b/bookwyrm/templates/ostatus/remote_follow.html @@ -0,0 +1,46 @@ +{% extends 'ostatus/template.html' %} +{% load i18n %} +{% load utilities %} + +{% block heading %} +{% blocktrans with username=user.localname sitename=site.name %}Follow {{ username }} on the fediverse{% endblocktrans %} +{% endblock %} + +{% block content %} + +
    +

    {% blocktrans with username=user.display_name %}Follow {{ username }} from another Fediverse account like BookWyrm, Mastodon, or Pleroma.{% endblocktrans %}

    +
    +
    +
    +
    + {% csrf_token %} + + + + +
    +
    +
    +{% endblock %} diff --git a/bookwyrm/templates/ostatus/remote_follow_button.html b/bookwyrm/templates/ostatus/remote_follow_button.html new file mode 100644 index 000000000..fc869229a --- /dev/null +++ b/bookwyrm/templates/ostatus/remote_follow_button.html @@ -0,0 +1,15 @@ +{% load i18n %} +{% if request.user == user %} +{% else %} + +
    + +

    + {% trans 'This link opens in a pop-up window' %} +

    +
    +{% endif %} diff --git a/bookwyrm/templates/ostatus/subscribe.html b/bookwyrm/templates/ostatus/subscribe.html new file mode 100644 index 000000000..1020279b7 --- /dev/null +++ b/bookwyrm/templates/ostatus/subscribe.html @@ -0,0 +1,63 @@ +{% extends 'ostatus/template.html' %} +{% load i18n %} +{% load utilities %} +{% load markdown %} + +{% block title %} +{% if not request.user.is_authenticated %} +{% blocktrans with sitename=site.name %}Log in to {{ sitename }}{% endblocktrans %} +{% elif error %} +{% blocktrans with sitename=site.name %}Error following from {{ sitename }}{% endblocktrans %} +{% else %} +{% blocktrans with sitename=site.name %}Follow from {{ sitename }}{% endblocktrans %} +{% endif %} +{% endblock %} + +{% block heading %} +{% if error %} +{% trans 'Uh oh...' %} +{% elif not request.user.is_authenticated %} +{% trans "Let's log in first..." %} +{% else %} +{% blocktrans with sitename=site.name %}Follow from {{ sitename }}{% endblocktrans %} +{% endif %} +{% endblock %} + +{% block content %} +{% if error or not request.user.is_authenticated %} + {% include 'ostatus/error.html' with error=error user=user account=account %} +{% else %} +
    +
    + +
    + {% if user.summary %} + {{ user.summary|to_markdown|safe|truncatechars_html:120 }} + {% else %} {% endif %} +
    +
    +
    +{% endif %} +{% endblock %} diff --git a/bookwyrm/templates/ostatus/success.html b/bookwyrm/templates/ostatus/success.html new file mode 100644 index 000000000..66577e83f --- /dev/null +++ b/bookwyrm/templates/ostatus/success.html @@ -0,0 +1,35 @@ +{% extends 'ostatus/template.html' %} +{% load i18n %} +{% load utilities %} + +{% block content %} + +
    + +
    +{% endblock %} diff --git a/bookwyrm/templates/ostatus/template.html b/bookwyrm/templates/ostatus/template.html new file mode 100644 index 000000000..9776f28dd --- /dev/null +++ b/bookwyrm/templates/ostatus/template.html @@ -0,0 +1,41 @@ +{% load layout %} +{% load i18n %} +{% load static %} +{% load utilities %} +{% load markdown %} + + + + + {% block title %}{% endblock %} + + + + + + + + +
    +
    + {% block content%}{% endblock %} +
    +
    + + + + + diff --git a/bookwyrm/templates/preferences/delete_user.html b/bookwyrm/templates/preferences/delete_user.html index 63bd2f860..b009230c5 100644 --- a/bookwyrm/templates/preferences/delete_user.html +++ b/bookwyrm/templates/preferences/delete_user.html @@ -18,10 +18,9 @@ {% csrf_token %}
    - - {% for error in form.password.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + {% include 'snippets/form_errors.html' with errors_list=form.password.errors id="desc_password" %}
    diff --git a/bookwyrm/templates/preferences/edit_user.html b/bookwyrm/templates/preferences/edit_user.html index 72c49dbe5..b18eb4e98 100644 --- a/bookwyrm/templates/preferences/edit_user.html +++ b/bookwyrm/templates/preferences/edit_user.html @@ -33,31 +33,27 @@ {% endif %}
    {{ form.avatar }} - {% for error in form.avatar.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.avatar.errors id="desc_avatar" %}
    {{ form.name }} - {% for error in form.name.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.name.errors id="desc_name" %}
    {{ form.summary }} - {% for error in form.summary.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.summary.errors id="desc_summary" %}
    {{ form.email }} - {% for error in form.email.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.email.errors id="desc_email" %}
    @@ -69,19 +65,23 @@
    +
    +
    +
    +
    {% url 'directory' as path %} -

    +

    {% blocktrans %}Your account will show up in the directory, and may be recommended to other BookWyrm users.{% endblocktrans %}

    @@ -107,8 +107,8 @@
    diff --git a/bookwyrm/templates/settings/announcements/announcement_form.html b/bookwyrm/templates/settings/announcements/announcement_form.html index ffdbfc2fd..8f68e2555 100644 --- a/bookwyrm/templates/settings/announcements/announcement_form.html +++ b/bookwyrm/templates/settings/announcements/announcement_form.html @@ -13,60 +13,68 @@ {% csrf_token %}

    - + {{ form.preview }} - {% for error in form.preview.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.preview.errors id="desc_preview" %}

    - + {{ form.content }} - {% for error in form.content.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.content.errors id="desc_content" %}

    - + - {% for error in form.event_date.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.event_date.errors id="desc_event_date" %}

    - + - {% for error in form.start_date.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.start_date.errors id="desc_start_date" %}

    - + - {% for error in form.end_date.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.end_date.errors id="desc_end_date" %}

    - + {{ form.active }} - {% for error in form.active.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=form.active.errors id="desc_active" %}

    - +
    {% endblock %} diff --git a/bookwyrm/templates/settings/email_blocklist/domain_form.html b/bookwyrm/templates/settings/email_blocklist/domain_form.html index e93337495..cebc97c85 100644 --- a/bookwyrm/templates/settings/email_blocklist/domain_form.html +++ b/bookwyrm/templates/settings/email_blocklist/domain_form.html @@ -17,10 +17,8 @@ {{ form.domain }}
    - {% for error in form.domain.errors %} -

    {{ error | escape }}

    - {% endfor %} + {% include 'snippets/form_errors.html' with errors_list=form.domain.errors id="desc_domain" %}
    diff --git a/bookwyrm/templates/settings/federation/edit_instance.html b/bookwyrm/templates/settings/federation/edit_instance.html index 7c2e6be66..0a67895cc 100644 --- a/bookwyrm/templates/settings/federation/edit_instance.html +++ b/bookwyrm/templates/settings/federation/edit_instance.html @@ -27,11 +27,12 @@
    - - - {% for error in form.server_name.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.server_name.errors id="desc_server_name" %}
    @@ -49,29 +50,37 @@
    - - - {% for error in form.application_type.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.application_type.errors id="desc_application_type" %}
    - - - {% for error in form.application_version.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + + {% include 'snippets/form_errors.html' with errors_list=form.application_version.errors id="desc_application_version" %}
    - - + +
    - + {% endblock %} diff --git a/bookwyrm/templates/settings/ip_blocklist/ip_address_form.html b/bookwyrm/templates/settings/ip_blocklist/ip_address_form.html index c8a4c3e74..4a776987f 100644 --- a/bookwyrm/templates/settings/ip_blocklist/ip_address_form.html +++ b/bookwyrm/templates/settings/ip_blocklist/ip_address_form.html @@ -20,16 +20,16 @@
    - +
    - {% for error in form.address.errors %} -

    {{ error | escape }}

    - {% endfor %} + {% include 'snippets/form_errors.html' with errors_list=form.address.errors id="desc_address" %}
    - +
    diff --git a/bookwyrm/templates/settings/site.html b/bookwyrm/templates/settings/site.html index 94a4dd454..8efad308d 100644 --- a/bookwyrm/templates/settings/site.html +++ b/bookwyrm/templates/settings/site.html @@ -33,8 +33,8 @@ {{ site_form.instance_description }}
    - -

    {% trans "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." %}

    + +

    {% trans "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." %}

    {{ site_form.instance_short_description }}
    @@ -114,7 +114,7 @@ {{ site_form.require_confirm_email }} {% trans "Require users to confirm email address" %} -

    {% trans "(Recommended if registration is open)" %}

    +

    {% trans "(Recommended if registration is open)" %}

    @@ -123,9 +123,8 @@
    {{ site_form.invite_request_text }} - {% for error in site_form.invite_request_text.errors %} -

    {{ error|escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=site_form.invite_request_text.errors id="desc_invite_request_text" %}
    diff --git a/bookwyrm/templates/settings/users/delete_user_form.html b/bookwyrm/templates/settings/users/delete_user_form.html index 158745d05..1ea63269d 100644 --- a/bookwyrm/templates/settings/users/delete_user_form.html +++ b/bookwyrm/templates/settings/users/delete_user_form.html @@ -15,10 +15,9 @@

    - - {% for error in form.password.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + {% include 'snippets/form_errors.html' with errors_list=form.password.errors id="desc_password" %}
    diff --git a/bookwyrm/templates/settings/users/user_moderation_actions.html b/bookwyrm/templates/settings/users/user_moderation_actions.html index a976359f4..b5f69529f 100644 --- a/bookwyrm/templates/settings/users/user_moderation_actions.html +++ b/bookwyrm/templates/settings/users/user_moderation_actions.html @@ -50,18 +50,23 @@ {% endif %} {% with group=user.groups.first %}
    - {% for value, name in group_form.fields.groups.choices %} - + {% endfor %} - +
    - {% for error in group_form.groups.errors %} -

    {{ error | escape }}

    - {% endfor %} + + {% include 'snippets/form_errors.html' with errors_list=group_form.groups.errors id="desc_user_group" %} {% endwith %} - +
    {% endif %} diff --git a/bookwyrm/templates/snippets/form_errors.html b/bookwyrm/templates/snippets/form_errors.html new file mode 100644 index 000000000..ecbf7ff8d --- /dev/null +++ b/bookwyrm/templates/snippets/form_errors.html @@ -0,0 +1,9 @@ +{% if errors_list %} +
    + {% for error in errors_list %} +

    + {{ error | escape }} +

    + {% endfor %} +
    +{% endif %} diff --git a/bookwyrm/templates/snippets/register_form.html b/bookwyrm/templates/snippets/register_form.html index 9e610bd13..a1af78eff 100644 --- a/bookwyrm/templates/snippets/register_form.html +++ b/bookwyrm/templates/snippets/register_form.html @@ -3,32 +3,31 @@
    - + + + {% include 'snippets/form_errors.html' with errors_list=register_form.localname.errors id="desc_localname_register" %}
    - {% for error in register_form.localname.errors %} -

    {{ error | escape }}

    - {% endfor %}
    - - {% for error in register_form.email.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + {% include 'snippets/form_errors.html' with errors_list=register_form.email.errors id="desc_email_register" %}
    - - {% for error in register_form.password.errors %} -

    {{ error | escape }}

    - {% endfor %} + + + {% include 'snippets/form_errors.html' with errors_list=register_form.password.errors id="desc_password_register" %}
    - +
    diff --git a/bookwyrm/templates/snippets/shelf_selector.html b/bookwyrm/templates/snippets/shelf_selector.html index 3ee6fa92c..f96f48a89 100644 --- a/bookwyrm/templates/snippets/shelf_selector.html +++ b/bookwyrm/templates/snippets/shelf_selector.html @@ -86,11 +86,11 @@
  • {% endif %} -{% include 'snippets/reading_modals/want_to_read_modal.html' with book=active_shelf.book controls_text="want_to_read" controls_uid=uuid move_from=current.id refresh=True %} +{% include 'snippets/reading_modals/want_to_read_modal.html' with book=active_shelf.book controls_text="want_to_read" controls_uid=uuid move_from=current.id refresh=True class="" %} -{% include 'snippets/reading_modals/start_reading_modal.html' with book=active_shelf.book controls_text="start_reading" controls_uid=uuid move_from=current.id refresh=True %} +{% include 'snippets/reading_modals/start_reading_modal.html' with book=active_shelf.book controls_text="start_reading" controls_uid=uuid move_from=current.id refresh=True class="" %} -{% include 'snippets/reading_modals/finish_reading_modal.html' with book=active_shelf.book controls_text="finish_reading" controls_uid=uuid move_from=current.id readthrough=readthrough refresh=True %} +{% include 'snippets/reading_modals/finish_reading_modal.html' with book=active_shelf.book controls_text="finish_reading" controls_uid=uuid move_from=current.id readthrough=readthrough refresh=True class="" %} {% endwith %} {% endblock %} diff --git a/bookwyrm/templates/snippets/trimmed_list.html b/bookwyrm/templates/snippets/trimmed_list.html new file mode 100644 index 000000000..2e5f4595b --- /dev/null +++ b/bookwyrm/templates/snippets/trimmed_list.html @@ -0,0 +1,34 @@ +{% spaceless %} +{% load i18n %} +{% load humanize %} +{% firstof limit 3 as limit %} +{% with subtraction_value='-'|add:limit %} +{% with remainder_count=items|length|add:subtraction_value %} +{% with remainder_count_display=remainder_count|intcomma %} + +
    + + {% for item in items|slice:limit %} + {{ item }}{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %} + and {{ remainder_count_display }} other + {% plural %} + and {{ remainder_count_display }} others + {% endblocktrans %} + {% endif %} + {% endfor %} + + + {% for item in items|slice:"3:" %} + {{ item }}{% if not forloop.last %}, {% endif %} + {% endfor %} +
    + + +{% endwith %} +{% endwith %} +{% endwith %} +{% endspaceless %} diff --git a/bookwyrm/templates/user/layout.html b/bookwyrm/templates/user/layout.html index d7557ae7b..03e3dfce8 100755 --- a/bookwyrm/templates/user/layout.html +++ b/bookwyrm/templates/user/layout.html @@ -39,6 +39,9 @@ {% if not is_self and request.user.is_authenticated %} {% include 'snippets/follow_button.html' with user=user %} {% endif %} + {% if not is_self %} + {% include 'ostatus/remote_follow_button.html' with user=user %} + {% endif %} {% if is_self and user.follower_requests.all %}