Merge branch 'main' into activitystreams-celery

This commit is contained in:
Mouse Reeve 2021-08-17 10:42:09 -06:00 committed by GitHub
commit ddaf949c94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
146 changed files with 3921 additions and 1805 deletions

View file

@ -36,6 +36,7 @@ jobs:
env: env:
SECRET_KEY: beepbeep SECRET_KEY: beepbeep
DEBUG: false DEBUG: false
USE_HTTPS: true
DOMAIN: your.domain.here DOMAIN: your.domain.here
BOOKWYRM_DATABASE_BACKEND: postgres BOOKWYRM_DATABASE_BACKEND: postgres
MEDIA_ROOT: images/ MEDIA_ROOT: images/

View file

@ -48,7 +48,7 @@ class Signature:
def naive_parse(activity_objects, activity_json, serializer=None): def naive_parse(activity_objects, activity_json, serializer=None):
"""this navigates circular import issues""" """this navigates circular import issues by looking up models' serializers"""
if not serializer: if not serializer:
if activity_json.get("publicKeyPem"): if activity_json.get("publicKeyPem"):
# ugh # ugh

View file

@ -6,7 +6,6 @@ from django.db.models import signals, Q
from bookwyrm import models from bookwyrm import models
from bookwyrm.redis_store import RedisStore, r from bookwyrm.redis_store import RedisStore, r
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.settings import STREAMS
from bookwyrm.views.helpers import privacy_filter from bookwyrm.views.helpers import privacy_filter
@ -58,7 +57,13 @@ class ActivityStream(RedisStore):
return ( return (
models.Status.objects.select_subclasses() models.Status.objects.select_subclasses()
.filter(id__in=statuses) .filter(id__in=statuses)
.select_related("user", "reply_parent") .select_related(
"user",
"reply_parent",
"comment__book",
"review__book",
"quotation__book",
)
.prefetch_related("mention_books", "mention_users") .prefetch_related("mention_books", "mention_users")
.order_by("-published_date") .order_by("-published_date")
) )
@ -237,15 +242,10 @@ class BooksStream(ActivityStream):
# determine which streams are enabled in settings.py # determine which streams are enabled in settings.py
available_streams = [s["key"] for s in STREAMS]
streams = { streams = {
k: v
for (k, v) in {
"home": HomeStream(), "home": HomeStream(),
"local": LocalStream(), "local": LocalStream(),
"books": BooksStream(), "books": BooksStream(),
}.items()
if k in available_streams
} }
@ -261,8 +261,6 @@ def add_status_on_create(sender, instance, created, *args, **kwargs):
remove_status_task.delay(instance.id) remove_status_task.delay(instance.id)
return return
if not created:
return
# when creating new things, gotta wait on the transaction # when creating new things, gotta wait on the transaction
transaction.on_commit(lambda: add_status_on_create_command(sender, instance)) transaction.on_commit(lambda: add_status_on_create_command(sender, instance))
@ -395,8 +393,53 @@ def remove_statuses_on_shelve(sender, instance, *args, **kwargs):
BooksStream().remove_book_statuses(instance.user, instance.book) BooksStream().remove_book_statuses(instance.user, instance.book)
@receiver(signals.pre_save, sender=models.ShelfBook)
# pylint: disable=unused-argument
def add_statuses_on_shelve(sender, instance, *args, **kwargs):
"""update books stream when user shelves a book"""
if not instance.user.local:
return
book = None
if hasattr(instance, "book"):
book = instance.book
elif instance.mention_books.exists():
book = instance.mention_books.first()
if not book:
return
# check if the book is already on the user's shelves
editions = book.parent_work.editions.all()
if models.ShelfBook.objects.filter(user=instance.user, book__in=editions).exists():
return
BooksStream().add_book_statuses(instance.user, book)
@receiver(signals.post_delete, sender=models.ShelfBook)
# pylint: disable=unused-argument
def remove_statuses_on_unshelve(sender, instance, *args, **kwargs):
"""update books stream when user unshelves a book"""
if not instance.user.local:
return
book = None
if hasattr(instance, "book"):
book = instance.book
elif instance.mention_books.exists():
book = instance.mention_books.first()
if not book:
return
# check if the book is actually unshelved, not just moved
editions = book.parent_work.editions.all()
if models.ShelfBook.objects.filter(user=instance.user, book__in=editions).exists():
return
BooksStream().remove_book_statuses(instance.user, instance.book)
# ---- TASKS # ---- TASKS
# TODO: merge conflict: reconcile these tasks
@app.task @app.task
def populate_streams_task(user_id): def populate_streams_task(user_id):
@ -406,6 +449,14 @@ def populate_streams_task(user_id):
stream.populate_streams(user) stream.populate_streams(user)
@app.task
def populate_stream_task(stream, user_id):
"""background task for populating an empty activitystream"""
user = models.User.objects.get(id=user_id)
stream = streams[stream]
stream.populate_streams(user)
@app.task @app.task
def remove_status_task(status_ids): def remove_status_task(status_ids):
"""remove a status from any stream it might be in""" """remove a status from any stream it might be in"""

View file

@ -71,7 +71,7 @@ class Connector(AbstractConnector):
# flatten the data so that images, uri, and claims are on the same level # flatten the data so that images, uri, and claims are on the same level
return { return {
**data.get("claims", {}), **data.get("claims", {}),
**{k: data.get(k) for k in ["uri", "image", "labels", "sitelinks"]}, **{k: data.get(k) for k in ["uri", "image", "labels", "sitelinks", "type"]},
} }
def search(self, query, min_confidence=None): # pylint: disable=arguments-differ def search(self, query, min_confidence=None): # pylint: disable=arguments-differ

View file

@ -23,6 +23,14 @@ def email_data():
} }
def email_confirmation_email(user):
"""newly registered users confirm email address"""
data = email_data()
data["confirmation_code"] = user.confirmation_code
data["confirmation_link"] = user.confirmation_link
send_email.delay(user.email, *format_email("confirm", data))
def invite_email(invite_request): def invite_email(invite_request):
"""send out an invite code""" """send out an invite code"""
data = email_data() data = email_data()

View file

@ -3,22 +3,35 @@ from django.core.management.base import BaseCommand
from bookwyrm import activitystreams, models from bookwyrm import activitystreams, models
def populate_streams(): def populate_streams(stream=None):
"""build all the streams for all the users""" """build all the streams for all the users"""
streams = [stream] if stream else activitystreams.streams.keys()
print("Populations streams", streams)
users = models.User.objects.filter( users = models.User.objects.filter(
local=True, local=True,
is_active=True, is_active=True,
) ).order_by("-last_active_date")
print("This may take a long time! Please be patient.")
for user in users: for user in users:
for stream in activitystreams.streams.values(): for stream_key in streams:
stream.populate_streams(user) print(".", end="")
activitystreams.populate_stream_task.delay(stream_key, user.id)
class Command(BaseCommand): class Command(BaseCommand):
"""start all over with user streams""" """start all over with user streams"""
help = "Populate streams for all users" help = "Populate streams for all users"
def add_arguments(self, parser):
parser.add_argument(
"--stream",
default=None,
help="Specifies which time of stream to populate",
)
# pylint: disable=no-self-use,unused-argument # pylint: disable=no-self-use,unused-argument
def handle(self, *args, **options): def handle(self, *args, **options):
"""run feed builder""" """run feed builder"""
populate_streams() stream = options.get("stream")
populate_streams(stream=stream)

View file

@ -0,0 +1,19 @@
# Generated by Django 3.2.4 on 2021-08-06 02:51
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0080_alter_shelfbook_options"),
]
operations = [
migrations.AlterField(
model_name="user",
name="last_active_date",
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

View file

@ -0,0 +1,56 @@
# Generated by Django 3.2.4 on 2021-08-06 23:24
import bookwyrm.models.base_model
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0081_alter_user_last_active_date"),
]
operations = [
migrations.AddField(
model_name="sitesettings",
name="require_confirm_email",
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name="user",
name="confirmation_code",
field=models.CharField(
default=bookwyrm.models.base_model.new_access_code, max_length=32
),
),
migrations.AlterField(
model_name="connector",
name="deactivation_reason",
field=models.CharField(
blank=True,
choices=[
("pending", "Pending"),
("self_deletion", "Self Deletion"),
("moderator_deletion", "Moderator Deletion"),
("domain_block", "Domain Block"),
],
max_length=255,
null=True,
),
),
migrations.AlterField(
model_name="user",
name="deactivation_reason",
field=models.CharField(
blank=True,
choices=[
("pending", "Pending"),
("self_deletion", "Self Deletion"),
("moderator_deletion", "Moderator Deletion"),
("domain_block", "Domain Block"),
],
max_length=255,
null=True,
),
),
]

View file

@ -7,7 +7,7 @@ import operator
import logging import logging
from uuid import uuid4 from uuid import uuid4
import requests import requests
from requests.exceptions import HTTPError, SSLError from requests.exceptions import RequestException
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15 from Crypto.Signature import pkcs1_15
@ -43,7 +43,7 @@ class ActivitypubMixin:
reverse_unfurl = False reverse_unfurl = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
"""collect some info on model fields""" """collect some info on model fields for later use"""
self.image_fields = [] self.image_fields = []
self.many_to_many_fields = [] self.many_to_many_fields = []
self.simple_fields = [] # "simple" self.simple_fields = [] # "simple"
@ -503,7 +503,7 @@ def broadcast_task(sender_id, activity, recipients):
for recipient in recipients: for recipient in recipients:
try: try:
sign_and_send(sender, activity, recipient) sign_and_send(sender, activity, recipient)
except (HTTPError, SSLError, requests.exceptions.ConnectionError): except RequestException:
pass pass

View file

@ -1,4 +1,6 @@
""" base model with default fields """ """ base model with default fields """
import base64
from Crypto import Random
from django.db import models from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
@ -9,6 +11,7 @@ from .fields import RemoteIdField
DeactivationReason = models.TextChoices( DeactivationReason = models.TextChoices(
"DeactivationReason", "DeactivationReason",
[ [
"pending",
"self_deletion", "self_deletion",
"moderator_deletion", "moderator_deletion",
"domain_block", "domain_block",
@ -16,6 +19,11 @@ DeactivationReason = models.TextChoices(
) )
def new_access_code():
"""the identifier for a user invite"""
return base64.b32encode(Random.get_random_bytes(5)).decode("ascii")
class BookWyrmModel(models.Model): class BookWyrmModel(models.Model):
"""shared fields""" """shared fields"""

View file

@ -80,7 +80,7 @@ class ImportItem(models.Model):
else: else:
# don't fall back on title/author search is isbn is present. # don't fall back on title/author search is isbn is present.
# you're too likely to mismatch # you're too likely to mismatch
self.get_book_from_title_author() self.book = self.get_book_from_title_author()
def get_book_from_isbn(self): def get_book_from_isbn(self):
"""search by isbn""" """search by isbn"""

View file

@ -1,8 +1,6 @@
""" the particulars for this instance of BookWyrm """ """ the particulars for this instance of BookWyrm """
import base64
import datetime import datetime
from Crypto import Random
from django.db import models, IntegrityError from django.db import models, IntegrityError
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
@ -10,7 +8,7 @@ from model_utils import FieldTracker
from bookwyrm.preview_images import generate_site_preview_image_task from bookwyrm.preview_images import generate_site_preview_image_task
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES
from .base_model import BookWyrmModel from .base_model import BookWyrmModel, new_access_code
from .user import User from .user import User
@ -33,6 +31,7 @@ class SiteSettings(models.Model):
# registration # registration
allow_registration = models.BooleanField(default=True) allow_registration = models.BooleanField(default=True)
allow_invite_requests = models.BooleanField(default=True) allow_invite_requests = models.BooleanField(default=True)
require_confirm_email = models.BooleanField(default=True)
# images # images
logo = models.ImageField(upload_to="logos/", null=True, blank=True) logo = models.ImageField(upload_to="logos/", null=True, blank=True)
@ -61,11 +60,6 @@ class SiteSettings(models.Model):
return default_settings return default_settings
def new_access_code():
"""the identifier for a user invite"""
return base64.b32encode(Random.get_random_bytes(5)).decode("ascii")
class SiteInvite(models.Model): class SiteInvite(models.Model):
"""gives someone access to create an account on the instance""" """gives someone access to create an account on the instance"""

View file

@ -17,16 +17,22 @@ from bookwyrm.connectors import get_data, ConnectorException
from bookwyrm.models.shelf import Shelf from bookwyrm.models.shelf import Shelf
from bookwyrm.models.status import Status, Review from bookwyrm.models.status import Status, Review
from bookwyrm.preview_images import generate_user_preview_image_task from bookwyrm.preview_images import generate_user_preview_image_task
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, USE_HTTPS
from bookwyrm.signatures import create_key_pair from bookwyrm.signatures import create_key_pair
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.utils import regex from bookwyrm.utils import regex
from .activitypub_mixin import OrderedCollectionPageMixin, ActivitypubMixin from .activitypub_mixin import OrderedCollectionPageMixin, ActivitypubMixin
from .base_model import BookWyrmModel, DeactivationReason from .base_model import BookWyrmModel, DeactivationReason, new_access_code
from .federated_server import FederatedServer from .federated_server import FederatedServer
from . import fields, Review from . import fields, Review
def site_link():
"""helper for generating links to the site"""
protocol = "https" if USE_HTTPS else "http"
return f"{protocol}://{DOMAIN}"
class User(OrderedCollectionPageMixin, AbstractUser): class User(OrderedCollectionPageMixin, AbstractUser):
"""a user who wants to read books""" """a user who wants to read books"""
@ -111,7 +117,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
remote_id = fields.RemoteIdField(null=True, unique=True, activitypub_field="id") remote_id = fields.RemoteIdField(null=True, unique=True, activitypub_field="id")
created_date = models.DateTimeField(auto_now_add=True) created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True) updated_date = models.DateTimeField(auto_now=True)
last_active_date = models.DateTimeField(auto_now=True) last_active_date = models.DateTimeField(default=timezone.now)
manually_approves_followers = fields.BooleanField(default=False) manually_approves_followers = fields.BooleanField(default=False)
show_goal = models.BooleanField(default=True) show_goal = models.BooleanField(default=True)
discoverable = fields.BooleanField(default=False) discoverable = fields.BooleanField(default=False)
@ -123,11 +129,18 @@ class User(OrderedCollectionPageMixin, AbstractUser):
deactivation_reason = models.CharField( deactivation_reason = models.CharField(
max_length=255, choices=DeactivationReason.choices, null=True, blank=True max_length=255, choices=DeactivationReason.choices, null=True, blank=True
) )
confirmation_code = models.CharField(max_length=32, default=new_access_code)
name_field = "username" name_field = "username"
property_fields = [("following_link", "following")] property_fields = [("following_link", "following")]
field_tracker = FieldTracker(fields=["name", "avatar"]) field_tracker = FieldTracker(fields=["name", "avatar"])
@property
def confirmation_link(self):
"""helper for generating confirmation links"""
link = site_link()
return f"{link}/confirm-email/{self.confirmation_code}"
@property @property
def following_link(self): def following_link(self):
"""just how to find out the following info""" """just how to find out the following info"""
@ -207,7 +220,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
self.following.order_by("-updated_date").all(), self.following.order_by("-updated_date").all(),
remote_id=remote_id, remote_id=remote_id,
id_only=True, id_only=True,
**kwargs **kwargs,
) )
def to_followers_activity(self, **kwargs): def to_followers_activity(self, **kwargs):
@ -217,7 +230,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
self.followers.order_by("-updated_date").all(), self.followers.order_by("-updated_date").all(),
remote_id=remote_id, remote_id=remote_id,
id_only=True, id_only=True,
**kwargs **kwargs,
) )
def to_activity(self, **kwargs): def to_activity(self, **kwargs):
@ -259,9 +272,9 @@ class User(OrderedCollectionPageMixin, AbstractUser):
return return
# populate fields for local users # populate fields for local users
self.remote_id = "https://%s/user/%s" % (DOMAIN, self.localname) self.remote_id = "%s/user/%s" % (site_link(), self.localname)
self.inbox = "%s/inbox" % self.remote_id self.inbox = "%s/inbox" % self.remote_id
self.shared_inbox = "https://%s/inbox" % DOMAIN self.shared_inbox = "%s/inbox" % site_link()
self.outbox = "%s/outbox" % self.remote_id self.outbox = "%s/outbox" % self.remote_id
# an id needs to be set before we can proceed with related models # an id needs to be set before we can proceed with related models

View file

@ -29,6 +29,11 @@ body {
min-width: 75% !important; min-width: 75% !important;
} }
.clip-text {
max-height: 35em;
overflow: hidden;
}
/** Utilities not covered by Bulma /** Utilities not covered by Bulma
******************************************************************************/ ******************************************************************************/

View file

@ -164,7 +164,7 @@ let BookWyrm = new class {
} }
// Show/hide container. // Show/hide container.
let container = document.getElementById('hide-' + targetId); let container = document.getElementById('hide_' + targetId);
if (container) { if (container) {
this.toggleContainer(container, pressed); this.toggleContainer(container, pressed);
@ -219,7 +219,7 @@ let BookWyrm = new class {
/** /**
* Check or uncheck a checbox. * Check or uncheck a checbox.
* *
* @param {object} checkbox - DOM node * @param {string} checkbox - id of the checkbox
* @param {boolean} pressed - Is the trigger pressed? * @param {boolean} pressed - Is the trigger pressed?
* @return {undefined} * @return {undefined}
*/ */

View file

@ -19,7 +19,7 @@ class SuggestedUsers(RedisStore):
def get_rank(self, obj): def get_rank(self, obj):
"""get computed rank""" """get computed rank"""
return obj.mutuals + (1.0 - (1.0 / (obj.shared_books + 1))) return obj.mutuals # + (1.0 - (1.0 / (obj.shared_books + 1)))
def store_id(self, user): # pylint: disable=no-self-use def store_id(self, user): # pylint: disable=no-self-use
"""the key used to store this user's recs""" """the key used to store this user's recs"""
@ -31,7 +31,7 @@ class SuggestedUsers(RedisStore):
"""calculate mutuals count and shared books count from rank""" """calculate mutuals count and shared books count from rank"""
return { return {
"mutuals": math.floor(rank), "mutuals": math.floor(rank),
"shared_books": int(1 / (-1 * (rank % 1 - 1))) - 1, # "shared_books": int(1 / (-1 * (rank % 1 - 1))) - 1,
} }
def get_objects_for_store(self, store): def get_objects_for_store(self, store):
@ -95,7 +95,7 @@ class SuggestedUsers(RedisStore):
logger.exception(err) logger.exception(err)
continue continue
user.mutuals = counts["mutuals"] user.mutuals = counts["mutuals"]
user.shared_books = counts["shared_books"] # user.shared_books = counts["shared_books"]
results.append(user) results.append(user)
return results return results
@ -115,16 +115,16 @@ def get_annotated_users(viewer, *args, **kwargs):
), ),
distinct=True, distinct=True,
), ),
shared_books=Count( # shared_books=Count(
"shelfbook", # "shelfbook",
filter=Q( # filter=Q(
~Q(id=viewer.id), # ~Q(id=viewer.id),
shelfbook__book__parent_work__in=[ # shelfbook__book__parent_work__in=[
s.book.parent_work for s in viewer.shelfbook_set.all() # s.book.parent_work for s in viewer.shelfbook_set.all()
], # ],
), # ),
distinct=True, # distinct=True,
), # ),
) )
) )
@ -162,18 +162,18 @@ def update_suggestions_on_unfollow(sender, instance, **kwargs):
rerank_user_task.delay(instance.user_object.id, update_only=False) rerank_user_task.delay(instance.user_object.id, update_only=False)
@receiver(signals.post_save, sender=models.ShelfBook) # @receiver(signals.post_save, sender=models.ShelfBook)
@receiver(signals.post_delete, sender=models.ShelfBook) # @receiver(signals.post_delete, sender=models.ShelfBook)
# pylint: disable=unused-argument # # pylint: disable=unused-argument
def update_rank_on_shelving(sender, instance, *args, **kwargs): # def update_rank_on_shelving(sender, instance, *args, **kwargs):
"""when a user shelves or unshelves a book, re-compute their rank""" # """when a user shelves or unshelves a book, re-compute their rank"""
# if it's a local user, re-calculate who is rec'ed to them # # if it's a local user, re-calculate who is rec'ed to them
if instance.user.local: # if instance.user.local:
rerank_suggestions_task.delay(instance.user.id) # rerank_suggestions_task.delay(instance.user.id)
#
# if the user is discoverable, update their rankings # # if the user is discoverable, update their rankings
if instance.user.discoverable: # if instance.user.discoverable:
rerank_user_task.delay(instance.user.id) # rerank_user_task.delay(instance.user.id)
@receiver(signals.post_save, sender=models.User) @receiver(signals.post_save, sender=models.User)

View file

@ -109,7 +109,7 @@
<div class="columns is-multiline is-mobile"> <div class="columns is-multiline is-mobile">
{% for book in books %} {% for book in books %}
<div class="column is-one-fifth"> <div class="column is-one-fifth">
{% include 'discover/small-book.html' with book=book %} {% include 'landing/small-book.html' with book=book %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View file

@ -72,8 +72,8 @@
{% if user_authenticated and not book.cover %} {% if user_authenticated and not book.cover %}
<div class="block"> <div class="block">
{% trans "Add cover" as button_text %} {% trans "Add cover" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="add-cover" controls_uid=book.id focus="modal-title-add-cover" class="is-small" %} {% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="add_cover" controls_uid=book.id focus="modal_title_add_cover" class="is-small" %}
{% include 'book/cover_modal.html' with book=book controls_text="add-cover" controls_uid=book.id %} {% include 'book/cover_modal.html' with book=book controls_text="add_cover" controls_uid=book.id %}
{% if request.GET.cover_error %} {% if request.GET.cover_error %}
<p class="help is-danger">{% trans "Failed to load cover" %}</p> <p class="help is-danger">{% trans "Failed to load cover" %}</p>
{% endif %} {% endif %}
@ -128,19 +128,19 @@
{% if user_authenticated and can_edit_book and not book|book_description %} {% if user_authenticated and can_edit_book and not book|book_description %}
{% trans 'Add Description' as button_text %} {% trans 'Add Description' as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text controls_text="add-description" controls_uid=book.id focus="id_description" hide_active=True id="hide-description" %} {% include 'snippets/toggle/open_button.html' with text=button_text controls_text="add_description" controls_uid=book.id focus="id_description" hide_active=True id="hide_description" %}
<div class="box is-hidden" id="add-description-{{ book.id }}"> <div class="box is-hidden" id="add_description_{{ book.id }}">
<form name="add-description" method="POST" action="/add-description/{{ book.id }}"> <form name="add-description" method="POST" action="/add-description/{{ book.id }}">
{% csrf_token %} {% csrf_token %}
<p class="fields is-grouped"> <p class="fields is-grouped">
<label class="label"for="id_description">{% trans "Description:" %}</label> <label class="label"for="id_description_{{ book.id }}">{% trans "Description:" %}</label>
<textarea name="description" cols="None" rows="None" class="textarea" id="id_description"></textarea> <textarea name="description" cols="None" rows="None" class="textarea" id="id_description_{{ book.id }}"></textarea>
</p> </p>
<div class="field"> <div class="field">
<button class="button is-primary" type="submit">{% trans "Save" %}</button> <button class="button is-primary" type="submit">{% trans "Save" %}</button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="add-description" controls_uid=book.id hide_inactive=True %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="add_description" controls_uid=book.id hide_inactive=True %}
</div> </div>
</form> </form>
</div> </div>
@ -177,10 +177,10 @@
</div> </div>
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Add read dates" as button_text %} {% trans "Add read dates" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="plus" class="is-small" controls_text="add-readthrough" focus="add-readthrough-focus" %} {% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="plus" class="is-small" controls_text="add_readthrough" focus="add_readthrough_focus_" %}
</div> </div>
</header> </header>
<section class="is-hidden box" id="add-readthrough"> <section class="is-hidden box" id="add_readthrough">
<form name="add-readthrough" action="/create-readthrough" method="post"> <form name="add-readthrough" action="/create-readthrough" method="post">
{% include 'snippets/readthrough_form.html' with readthrough=None %} {% include 'snippets/readthrough_form.html' with readthrough=None %}
<div class="field is-grouped"> <div class="field is-grouped">
@ -189,7 +189,7 @@
</div> </div>
<div class="control"> <div class="control">
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="add-readthrough" %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="add_readthrough" %}
</div> </div>
</div> </div>
</form> </form>

View file

@ -2,7 +2,7 @@
{% load humanize %} {% load humanize %}
{% load tz %} {% load tz %}
<div class="content"> <div class="content">
<div id="hide-edit-readthrough-{{ readthrough.id }}" class="box is-shadowless has-background-white-bis"> <div id="hide_edit_readthrough_{{ readthrough.id }}" class="box is-shadowless has-background-white-bis">
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
{% trans "Progress Updates:" %} {% trans "Progress Updates:" %}
@ -24,7 +24,7 @@
{% if readthrough.progress %} {% if readthrough.progress %}
{% trans "Show all updates" as button_text %} {% trans "Show all updates" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="updates" controls_uid=readthrough.id class="is-small" %} {% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="updates" controls_uid=readthrough.id class="is-small" %}
<ul id="updates-{{ readthrough.id }}" class="is-hidden"> <ul id="updates_{{ readthrough.id }}" class="is-hidden">
{% for progress_update in readthrough.progress_updates %} {% for progress_update in readthrough.progress_updates %}
<li> <li>
<form name="delete-update" action="/delete-progressupdate" method="POST"> <form name="delete-update" action="/delete-progressupdate" method="POST">
@ -36,7 +36,7 @@
{{ progress_update.progress }}% {{ progress_update.progress }}%
{% endif %} {% endif %}
<input type="hidden" name="id" value="{{ progress_update.id }}"/> <input type="hidden" name="id" value="{{ progress_update.id }}"/>
<button type="submit" class="button is-small" for="delete-progressupdate-{{ progress_update.id }}" role="button" tabindex="0"> <button type="submit" class="button is-small" for="delete_progressupdate_{{ progress_update.id }}" role="button" tabindex="0">
<span class="icon icon-x" title="Delete this progress update"> <span class="icon icon-x" title="Delete this progress update">
<span class="is-sr-only">{% trans "Delete this progress update" %}</span> <span class="is-sr-only">{% trans "Delete this progress update" %}</span>
</span> </span>
@ -57,11 +57,11 @@
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
{% trans "Edit read dates" as button_text %} {% trans "Edit read dates" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with class="is-small" text=button_text icon="pencil" controls_text="edit-readthrough" controls_uid=readthrough.id focus="edit-readthrough" %} {% include 'snippets/toggle/toggle_button.html' with class="is-small" text=button_text icon="pencil" controls_text="edit_readthrough" controls_uid=readthrough.id focus="edit_readthrough" %}
</div> </div>
<div class="control"> <div class="control">
{% trans "Delete these read dates" as button_text %} {% trans "Delete these read dates" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with class="is-small" text=button_text icon="x" controls_text="delete-readthrough" controls_uid=readthrough.id focus="modal-title-delete-readthrough" %} {% include 'snippets/toggle/toggle_button.html' with class="is-small" text=button_text icon="x" controls_text="delete_readthrough" controls_uid=readthrough.id focus="modal_title_delete_readthrough" %}
</div> </div>
</div> </div>
</div> </div>
@ -69,15 +69,15 @@
</div> </div>
</div> </div>
<div class="box is-hidden" id="edit-readthrough-{{ readthrough.id }}" tabindex="0"> <div class="box is-hidden" id="edit_readthrough_{{ readthrough.id }}" tabindex="0">
<h3 class="title is-5">{% trans "Edit read dates" %}</h3> <h3 class="title is-5">{% trans "Edit read dates" %}</h3>
<form name="edit-readthrough" action="/edit-readthrough" method="post"> <form name="edit-readthrough" action="/edit-readthrough" method="post">
{% include 'snippets/readthrough_form.html' with readthrough=readthrough %} {% include 'snippets/readthrough_form.html' with readthrough=readthrough %}
<div class="field is-grouped"> <div class="field is-grouped">
<button class="button is-primary" type="submit">{% trans "Save" %}</button> <button class="button is-primary" type="submit">{% trans "Save" %}</button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="edit-readthrough" controls_uid=readthrough.id %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="edit_readthrough" controls_uid=readthrough.id %}
</div> </div>
</form> </form>
</div> </div>
{% include 'snippets/delete_readthrough_modal.html' with controls_text="delete-readthrough" controls_uid=readthrough.id no_body=True %} {% include 'snippets/delete_readthrough_modal.html' with controls_text="delete_readthrough" controls_uid=readthrough.id no_body=True %}

View file

@ -3,7 +3,7 @@
{% with 0|uuid as uuid %} {% with 0|uuid as uuid %}
<div <div
id="menu-{{ uuid }}" id="menu_{{ uuid }}"
class=" class="
dropdown control dropdown control
{% if right %}is-right{% endif %} {% if right %}is-right{% endif %}
@ -14,15 +14,15 @@
type="button" type="button"
aria-expanded="false" aria-expanded="false"
aria-haspopup="true" aria-haspopup="true"
aria-controls="menu-options-{{ uuid }}" aria-controls="menu_options_{{ uuid }}"
data-controls="menu-{{ uuid }}" data-controls="menu_{{ uuid }}"
> >
{% block dropdown-trigger %}{% endblock %} {% block dropdown-trigger %}{% endblock %}
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<ul <ul
id="menu-options-{{ uuid }}" id="menu_options_{{ uuid }}"
class="dropdown-content p-0 is-clipped" class="dropdown-content p-0 is-clipped"
role="menu" role="menu"
> >

View file

@ -1,7 +1,7 @@
{% load i18n %} {% load i18n %}
<section class="card is-hidden {{ class }}" id="{{ controls_text }}{% if controls_uid %}-{{ controls_uid }}{% endif %}"> <section class="card is-hidden {{ class }}" id="{{ controls_text }}{% if controls_uid %}-{{ controls_uid }}{% endif %}">
<header class="card-header has-background-white-ter"> <header class="card-header has-background-white-ter">
<h2 class="card-header-title" tabindex="0" id="{{ controls_text }}{% if controls_uid %}-{{ controls_uid }}{% endif %}-header"> <h2 class="card-header-title" tabindex="0" id="{{ controls_text }}{% if controls_uid %}-{{ controls_uid }}{% endif %}_header">
{% block header %}{% endblock %} {% block header %}{% endblock %}
</h2> </h2>
<span class="card-header-icon"> <span class="card-header-icon">

View file

@ -2,16 +2,16 @@
<div <div
role="dialog" role="dialog"
class="modal {% if active %}is-active{% else %}is-hidden{% endif %}" class="modal {% if active %}is-active{% else %}is-hidden{% endif %}"
id="{{ controls_text }}-{{ controls_uid }}" id="{{ controls_text }}_{{ controls_uid }}"
aria-labelledby="modal-card-title-{{ controls_text }}-{{ controls_uid }}" aria-labelledby="modal_card_title_{{ controls_text }}_{{ controls_uid }}"
aria-modal="true" aria-modal="true"
> >
{# @todo Implement focus traps to prevent tabbing out of the modal. #} {# @todo Implement focus traps to prevent tabbing out of the modal. #}
<div class="modal-background"></div> <div class="modal-background"></div>
{% trans "Close" as label %} {% trans "Close" as label %}
<div class="modal-card"> <div class="modal-card">
<header class="modal-card-head" tabindex="0" id="modal-title-{{ controls_text }}-{{ controls_uid }}"> <header class="modal-card-head" tabindex="0" id="modal_title_{{ controls_text }}_{{ controls_uid }}">
<h2 class="modal-card-title is-flex-shrink-1" id="modal-card-title-{{ controls_text }}-{{ controls_uid }}"> <h2 class="modal-card-title is-flex-shrink-1" id="modal_card_title_{{ controls_text }}_{{ controls_uid }}">
{% block modal-title %}{% endblock %} {% block modal-title %}{% endblock %}
</h2> </h2>
{% include 'snippets/toggle/toggle_button.html' with label=label class="delete" nonbutton=True %} {% include 'snippets/toggle/toggle_button.html' with label=label class="delete" nonbutton=True %}

View file

@ -27,7 +27,7 @@
{% if not draft %} {% if not draft %}
{% include 'snippets/create_status.html' %} {% include 'snippets/create_status.html' %}
{% else %} {% else %}
{% include 'snippets/create_status_form.html' %} {% include 'snippets/create_status/status.html' %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

View file

@ -0,0 +1,44 @@
{% extends "layout.html" %}
{% load i18n %}
{% block title %}{% trans "Confirm email" %}{% endblock %}
{% block content %}
<h1 class="title">{% trans "Confirm your email address" %}</h1>
<div class="columns">
<div class="column">
<div class="block content">
<section class="block">
<p>{% trans "A confirmation code has been sent to the email address you used to register your account." %}</p>
{% if not valid %}
<p class="notification is-warning">{% trans "Sorry! We couldn't find that code." %}</p>
{% endif %}
<form name="confirm" method="post" action="{% url 'confirm-email' %}">
{% csrf_token %}
<label class="label" for="confirmation_code">{% trans "Confirmation code:" %}</label>
<div class="field has-addons">
<div class="control">
<input class="input" type="text" name="code" id="confirmation_code" required>
</div>
<div class="control">
<button class="button is-link" type="submit">{% trans "Submit" %}</button>
</div>
</div>
</form>
</section>
<section class="block">
{% trans "Can't find your code?" as button_text %}
{% include "snippets/toggle/open_button.html" with text=button_text controls_text="resend_form" focus="resend_form_header" %}
{% include "confirm_email/resend_form.html" with controls_text="resend_form" %}
</section>
</div>
</div>
<div class="column">
<div class="box">
{% include 'snippets/about.html' %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends "components/inline_form.html" %}
{% load i18n %}
{% block header %}
{% trans "Resend confirmation link" %}
{% endblock %}
{% block form %}
<form name="resend" method="post" action="{% url 'resend-link' %}">
{% csrf_token %}
<div class="field">
<label class="label" for="email">{% trans "Email address:" %}</label>
<div class="control">
<input type="text" name="email" class="input" required id="email">
</div>
</div>
<div class="control">
<button class="button is-link">{% trans "Resend link" %}</button>
</div>
</form>
{% endblock %}

View file

@ -11,7 +11,7 @@
</header> </header>
{% if not request.user.discoverable %} {% if not request.user.discoverable %}
<div class="box has-text-centered content" data-hide="hide-join-directory"><div class="columns"> <div class="box has-text-centered content" data-hide="hide_join_directory"><div class="columns">
<div class="column"> <div class="column">
<p> <p>
{% trans "Make your profile discoverable to other BookWyrm users." %} {% trans "Make your profile discoverable to other BookWyrm users." %}
@ -27,7 +27,7 @@
</div> </div>
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Dismiss message" as button_text %} {% trans "Dismiss message" as button_text %}
<button type="button" class="delete set-display" data-id="hide-join-directory" data-value="true"> <button type="button" class="delete set-display" data-id="hide_join_directory" data-value="true">
<span>Dismiss message</span> <span>Dismiss message</span>
</button> </button>
</div> </div>

View file

@ -1,50 +1,89 @@
{% extends 'discover/landing_layout.html' %} {% extends "layout.html" %}
{% load i18n %} {% load i18n %}
{% block panel %}
<div class="block is-hidden-tablet"> {% block title %}{% trans "Discover" %}{% endblock %}
<h2 class="title has-text-centered">{% trans "Recent Books" %}</h2>
{% block content %}
<section class="block">
<header class="block content has-text-centered">
<h1 class="title">{% trans "Discover" %}</h1>
<p class="subtitle">
{% blocktrans trimmed with site_name=site.name %}
See what's new in the local {{ site_name }} community
{% endblocktrans %}
</p>
</header>
<div class="tile is-ancestor">
<div class="tile is-6 is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with status=large_activities.0 %}
</div>
</div>
<div class="tile is-6 is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with status=large_activities.1 %}
</div>
</div>
</div> </div>
<section class="tile is-ancestor"> <div class="tile is-ancestor">
<div class="tile is-vertical"> <div class="tile is-vertical is-6">
<div class="tile is-parent"> <div class="tile is-parent">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with book=books.0 %} {% include 'discover/large-book.html' with status=large_activities.2 %}
</div> </div>
</div> </div>
<div class="tile"> <div class="tile">
<div class="tile is-parent is-6"> <div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/small-book.html' with book=books.1 %} {% include 'discover/small-book.html' with status=small_activities.0 %}
</div> </div>
</div> </div>
<div class="tile is-parent is-6"> <div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/small-book.html' with book=books.2 %} {% include 'discover/small-book.html' with status=small_activities.1 %}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="tile is-vertical"> <div class="tile is-vertical is-6">
<div class="tile"> <div class="tile">
<div class="tile is-parent is-6"> <div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/small-book.html' with book=books.3 %} {% include 'discover/small-book.html' with status=small_activities.2 %}
</div> </div>
</div> </div>
<div class="tile is-parent is-6"> <div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/small-book.html' with book=books.4 %} {% include 'discover/small-book.html' with status=small_activities.3 %}
</div> </div>
</div> </div>
</div> </div>
<div class="tile is-parent"> <div class="tile is-parent">
<div class="tile is-child box has-background-white-ter"> <div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with book=books.5 %} {% include 'discover/large-book.html' with status=large_activities.3 %}
</div>
</div>
</div>
</div>
<div class="tile is-ancestor">
<div class="tile is-6 is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with status=large_activities.4 %}
</div>
</div>
<div class="tile is-6 is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'discover/large-book.html' with status=large_activities.5 %}
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<div class="block">
{% include 'snippets/pagination.html' with page=large_activities %}
</div>
{% endblock %} {% endblock %}

View file

@ -1,38 +1,73 @@
{% load bookwyrm_tags %} {% load bookwyrm_tags %}
{% load markdown %}
{% load i18n %} {% load i18n %}
{% load utilities %}
{% load status_display %}
{% if book %} {% if status.book or status.mention_books.exists %}
{% with book=book %} {% load_book status as book %}
<div class="columns is-gapless"> <div class="columns is-gapless">
<div class="column is-5-tablet is-cover"> <div class="column is-6-tablet is-cover">
<a <a
class="align to-b to-l" class="align to-b to-l"
href="{{ book.local_path }}" href="{{ book.local_path }}"
>{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto-tablet' %}</a> >{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto-tablet' %}</a>
{% include 'snippets/stars.html' with rating=book|rating:request.user %} {% include 'snippets/stars.html' with rating=book|rating:request.user %}
</div> <h3 class="title is-6">
<a href="{{ book.local_path }}">{{ book|book_title }}</a>
<div class="column mt-3-mobile ml-3-tablet">
<h3 class="title is-5">
<a href="{{ book.local_path }}">{{ book.title }}</a>
</h3> </h3>
{% if book.authors %} {% if book.authors %}
<p class="subtitle is-5"> <p class="subtitle is-6 mb-2">
{% trans "by" %} {% trans "by" %}
{% include 'snippets/authors.html' %} {% include 'snippets/authors.html' with limit=3 %}
</p> </p>
{% endif %} {% endif %}
{% if book|book_description %} {% include 'snippets/shelve_button/shelve_button.html' %}
<blockquote class="content"> </div>
{{ book|book_description|to_markdown|safe|truncatewords_html:50 }}
</blockquote> <div class="column mt-3-mobile ml-3-tablet">
<div class="media block mb-2">
<figure class="media-left" aria-hidden="true">
<a class="image is-48x48" href="{{ status.user.local_path }}">
{% include 'snippets/avatar.html' with user=status.user ariaHide="true" medium="true" %}
</a>
</figure>
<div class="media-content">
<h3 class="title is-6">
<a href="{{ status.user.local_path }}">
<span>{{ status.user.display_name }}</span>
</a>
{% if status.status_type == 'GeneratedNote' %}
{{ status.content|safe }}
{% elif status.status_type == 'Rating' %}
{% trans "rated" %}
{% elif status.status_type == 'Review' %}
{% trans "reviewed" %}
{% elif status.status_type == 'Comment' %}
{% trans "commented on" %}
{% elif status.status_type == 'Quotation' %}
{% trans "quoted" %}
{% endif %} {% endif %}
<a href="{{ book.local_path }}">{{ book.title }}</a>
</h3>
</div>
</div>
<div class="block">
{% include 'snippets/follow_button.html' with user=status.user show_username=True minimal=True %}
</div>
<div class="notification has-background-white p-2 mb-2 clip-text">
{% include "snippets/status/content_status.html" with hide_book=True trim_length=70 hide_more=True %}
</div>
<a href="{{ status.remote_id }}">
<span>{% trans "View status" %}</span>
<span class="icon icon-arrow-right" aria-hidden="true"></span>
</a>
</div> </div>
</div> </div>
{% endwith %}
{% endif %} {% endif %}

View file

@ -1,24 +1,59 @@
{% load bookwyrm_tags %} {% load bookwyrm_tags %}
{% load utilities %}
{% load i18n %} {% load i18n %}
{% load status_display %}
{% if book %} {% if status.book or status.mention_books.exists %}
{% with book=book %} {% load_book status as book %}
<a href="{{ book.local_path }}"> <a href="{{ book.local_path }}">
{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-h-l-tablet is-w-auto align to-b to-l' %} {% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto align to-b to-l' %}
</a> </a>
{% include 'snippets/stars.html' with rating=book|rating:request.user %} <div class="block mt-2">
{% include 'snippets/shelve_button/shelve_button.html' %}
</div>
<div class="media block mb-2">
<figure class="media-left" aria-hidden="true">
<a class="image is-48x48" href="{{ status.user.local_path }}">
{% include 'snippets/avatar.html' with user=status.user ariaHide="true" medium="true" %}
</a>
</figure>
<div class="media-content">
<h3 class="title is-6"> <h3 class="title is-6">
<a href="{{ status.user.local_path }}">
<span>{{ status.user.display_name }}</span>
</a>
{% if status.status_type == 'GeneratedNote' %}
{{ status.content|safe }}
{% elif status.status_type == 'Rating' %}
{% trans "rated" %}
{% elif status.status_type == 'Review' %}
{% trans "reviewed" %}
{% elif status.status_type == 'Comment' %}
{% trans "commented on" %}
{% elif status.status_type == 'Quotation' %}
{% trans "quoted" %}
{% endif %}
<a href="{{ book.local_path }}">{{ book.title }}</a> <a href="{{ book.local_path }}">{{ book.title }}</a>
</h3> </h3>
{% if status.rating %}
{% if book.authors %}
<p class="subtitle is-6"> <p class="subtitle is-6">
{% trans "by" %} {% include 'snippets/stars.html' with rating=status.rating %}
{% include 'snippets/authors.html' %}
</p> </p>
{% endif %} {% endif %}
{% endwith %} </div>
</div>
<div class="block">
<a href="{{ status.remote_id }}">
<span>{% trans "View status" %}</span>
<span class="icon icon-arrow-right" aria-hidden="true"></span>
</a>
</div>
<div class="block">
{% include 'snippets/follow_button.html' with user=status.user show_username=True minimal=True %}
</div>
{% endif %} {% endif %}

View file

@ -0,0 +1,20 @@
{% extends 'email/html_layout.html' %}
{% load i18n %}
{% block content %}
<p>
{% blocktrans trimmed %}
One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below:
{% endblocktrans %}
</p>
{% trans "Confirm Email" as text %}
{% include 'email/snippets/action.html' with path=confirmation_link text=text %}
<p>
{% blocktrans trimmed %}
Or enter the code "<code>{{ confirmation_code }}</code>" at login.
{% endblocktrans %}
</p>
{% endblock %}

View file

@ -0,0 +1,4 @@
{% load i18n %}
{% blocktrans trimmed %}
Please confirm your email
{% endblocktrans %}

View file

@ -0,0 +1,14 @@
{% extends 'email/text_layout.html' %}
{% load i18n %}
{% block content %}
{% blocktrans trimmed %}
One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below:
{% endblocktrans %}
{{ confirmation_link }}
{% blocktrans trimmed %}
Or enter the code "{{ confirmation_code }}" at login.
{% endblocktrans %}
{% endblock %}

View file

@ -14,7 +14,7 @@
</header> </header>
<div class="box"> <div class="box">
{% include 'snippets/create_status_form.html' with type="direct" uuid=1 mention=partner %} {% include 'snippets/create_status/status.html' with type="direct" uuid=1 mention=partner %}
</div> </div>
<section class="block"> <section class="block">

View file

@ -19,7 +19,7 @@
{# announcements and system messages #} {# announcements and system messages #}
{% if not activities.number > 1 %} {% if not activities.number > 1 %}
<a href="{{ request.path }}" class="transition-y is-hidden notification is-primary is-block" data-poll-wrapper> <a href="{{ request.path }}" class="transition-y is-hidden notification is-primary is-block" data-poll-wrapper>
{% blocktrans %}load <span data-poll="stream/{{ tab.key }}">0</span> unread status(es){% endblocktrans %} {% blocktrans with tab_key=tab.key %}load <span data-poll="stream/{{ tab_key }}">0</span> unread status(es){% endblocktrans %}
</a> </a>
{% if request.user.show_goal and not goal and tab.key == streams.first.key %} {% if request.user.show_goal and not goal and tab.key == streams.first.key %}

View file

@ -33,11 +33,11 @@
<li class="{% if active_book == book.id|stringformat:'d' %}is-active{% elif not active_book and shelf_counter == 1 and forloop.first %}is-active{% endif %}"> <li class="{% if active_book == book.id|stringformat:'d' %}is-active{% elif not active_book and shelf_counter == 1 and forloop.first %}is-active{% endif %}">
<a <a
href="{{ request.path }}?book={{ book.id }}" href="{{ request.path }}?book={{ book.id }}"
id="tab-book-{{ book.id }}" id="tab_book_{{ book.id }}"
role="tab" role="tab"
aria-label="{{ book.title }}" aria-label="{{ book.title }}"
aria-selected="{% if active_book == book.id|stringformat:'d' %}true{% elif shelf_counter == 1 and forloop.first %}true{% else %}false{% endif %}" aria-selected="{% if active_book == book.id|stringformat:'d' %}true{% elif shelf_counter == 1 and forloop.first %}true{% else %}false{% endif %}"
aria-controls="book-{{ book.id }}"> aria-controls="book_{{ book.id }}">
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' %} {% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' %}
</a> </a>
</li> </li>
@ -56,9 +56,9 @@
<div <div
class="suggested-tabs card" class="suggested-tabs card"
role="tabpanel" role="tabpanel"
id="book-{{ book.id }}" id="book_{{ book.id }}"
{% if active_book and active_book == book.id|stringformat:'d' %}{% elif not active_book and shelf_counter == 1 and forloop.first %}{% else %} hidden{% endif %} {% if active_book and active_book == book.id|stringformat:'d' %}{% elif not active_book and shelf_counter == 1 and forloop.first %}{% else %} hidden{% endif %}
aria-labelledby="tab-book-{{ book.id }}"> aria-labelledby="tab_book_{{ book.id }}">
<div class="card-header"> <div class="card-header">
<div class="card-header-title"> <div class="card-header-title">

View file

@ -6,12 +6,12 @@
{% block content %} {% block content %}
{% with site_name=site.name %} {% with site_name=site.name %}
<div class="modal is-active" role="dialog" aria-modal="true" aria-labelledby="get-started-header"> <div class="modal is-active" role="dialog" aria-modal="true" aria-labelledby="get_started_header">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-card is-fullwidth"> <div class="modal-card is-fullwidth">
<header class="modal-card-head"> <header class="modal-card-head">
<img class="image logo mr-2" src="{% if site.logo_small %}{% get_media_prefix %}{{ site.logo_small }}{% else %}{% static "images/logo-small.png" %}{% endif %}" aria-hidden="true"> <img class="image logo mr-2" src="{% if site.logo_small %}{% get_media_prefix %}{{ site.logo_small }}{% else %}{% static "images/logo-small.png" %}{% endif %}" aria-hidden="true">
<h1 class="modal-card-title" id="get-started-header"> <h1 class="modal-card-title" id="get_started_header">
{% blocktrans %}Welcome to {{ site_name }}!{% endblocktrans %} {% blocktrans %}Welcome to {{ site_name }}!{% endblocktrans %}
<span class="subtitle is-block"> <span class="subtitle is-block">
{% trans "These are some first steps to get you started." %} {% trans "These are some first steps to get you started." %}

View file

@ -9,7 +9,7 @@
{% if is_self and goal %} {% if is_self and goal %}
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Edit Goal" as button_text %} {% trans "Edit Goal" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="show-edit-goal" focus="edit-form-header" %} {% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="show_edit_goal" focus="edit_form_header" %}
</div> </div>
{% endif %} {% endif %}
</div> </div>
@ -18,11 +18,11 @@
{% block panel %} {% block panel %}
<section class="block"> <section class="block">
{% now 'Y' as current_year %} {% now 'Y' as current_year %}
{% if user == request.user and year == current_year %} {% if user == request.user and year|add:0 == current_year|add:0 %}
<div class="block"> <div class="block">
<section class="card {% if goal %}is-hidden{% endif %}" id="show-edit-goal"> <section class="card {% if goal %}is-hidden{% endif %}" id="show_edit_goal">
<header class="card-header"> <header class="card-header">
<h2 class="card-header-title has-background-primary has-text-white" tabindex="0" id="edit-form-header"> <h2 class="card-header-title has-background-primary has-text-white" tabindex="0" id="edit_form_header">
<span class="icon icon-book is-size-3 mr-2" aria-hidden="true"></span> {% blocktrans %}{{ year }} Reading Goal{% endblocktrans %} <span class="icon icon-book is-size-3 mr-2" aria-hidden="true"></span> {% blocktrans %}{{ year }} Reading Goal{% endblocktrans %}
</h2> </h2>
</header> </header>

View file

@ -53,11 +53,11 @@
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<fieldset id="failed-imports"> <fieldset id="failed_imports">
<ul> <ul>
{% for item in failed_items %} {% for item in failed_items %}
<li class="mb-2 is-flex is-align-items-start"> <li class="mb-2 is-flex is-align-items-start">
<input class="checkbox mt-1" type="checkbox" name="import_item" value="{{ item.id }}" id="import-item-{{ item.id }}"> <input class="checkbox mt-1" type="checkbox" name="import_item" value="{{ item.id }}" id="import_item_{{ item.id }}">
<label class="ml-1" for="import-item-{{ item.id }}"> <label class="ml-1" for="import-item-{{ item.id }}">
{% blocktrans with index=item.index title=item.data.Title author=item.data.Author %}Line {{ index }}: <strong>{{ title }}</strong> by {{ author }}{% endblocktrans %} {% blocktrans with index=item.index title=item.data.Title author=item.data.Author %}Line {{ index }}: <strong>{{ title }}</strong> by {{ author }}{% endblocktrans %}
<br/> <br/>

View file

@ -1,4 +1,4 @@
{% extends 'discover/landing_layout.html' %} {% extends 'landing/landing_layout.html' %}
{% load i18n %} {% load i18n %}
{% block panel %} {% block panel %}

View file

@ -0,0 +1,50 @@
{% extends 'landing/landing_layout.html' %}
{% load i18n %}
{% block panel %}
<div class="block is-hidden-tablet">
<h2 class="title has-text-centered">{% trans "Recent Books" %}</h2>
</div>
<section class="tile is-ancestor">
<div class="tile is-vertical is-6">
<div class="tile is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/large-book.html' with book=books.0 %}
</div>
</div>
<div class="tile">
<div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/small-book.html' with book=books.1 %}
</div>
</div>
<div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/small-book.html' with book=books.2 %}
</div>
</div>
</div>
</div>
<div class="tile is-vertical is-6">
<div class="tile">
<div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/small-book.html' with book=books.3 %}
</div>
</div>
<div class="tile is-parent is-6">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/small-book.html' with book=books.4 %}
</div>
</div>
</div>
<div class="tile is-parent">
<div class="tile is-child box has-background-white-ter">
{% include 'landing/large-book.html' with book=books.5 %}
</div>
</div>
</div>
</section>
{% endblock %}

View file

@ -0,0 +1,38 @@
{% load bookwyrm_tags %}
{% load markdown %}
{% load i18n %}
{% if book %}
{% with book=book %}
<div class="columns is-gapless">
<div class="column is-7-tablet is-cover">
<a
class="align to-b to-l"
href="{{ book.local_path }}"
>{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto-tablet' %}</a>
{% include 'snippets/stars.html' with rating=book|rating:request.user %}
</div>
<div class="column mt-3-mobile ml-3-tablet">
<h3 class="title is-5">
<a href="{{ book.local_path }}">{{ book.title }}</a>
</h3>
{% if book.authors %}
<p class="subtitle is-5">
{% trans "by" %}
{% include 'snippets/authors.html' with limit=3 %}
</p>
{% endif %}
{% if book|book_description %}
<blockquote class="content">
{{ book|book_description|to_markdown|safe|truncatewords_html:50 }}
</blockquote>
{% endif %}
</div>
</div>
{% endwith %}
{% endif %}

View file

@ -0,0 +1,23 @@
{% load bookwyrm_tags %}
{% load i18n %}
{% if book %}
{% with book=book %}
<a href="{{ book.local_path }}">
{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto align to-b to-l' %}
</a>
{% include 'snippets/stars.html' with rating=book|rating:request.user %}
<h3 class="title is-6">
<a href="{{ book.local_path }}">{{ book.title }}</a>
</h3>
{% if book.authors %}
<p class="subtitle is-6">
{% trans "by" %}
{% include 'snippets/authors.html' with limit=3 %}
</p>
{% endif %}
{% endwith %}
{% endif %}

View file

@ -37,7 +37,7 @@
<form class="navbar-item column" action="/search/"> <form class="navbar-item column" action="/search/">
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
<input aria-label="{% trans 'Search for a book or user' %}" id="search-input" class="input" type="text" name="q" placeholder="{% trans 'Search for a book or user' %}" value="{{ query }}"> <input aria-label="{% trans 'Search for a book or user' %}" id="search_input" class="input" type="text" name="q" placeholder="{% trans 'Search for a book or user' %}" value="{{ query }}">
</div> </div>
<div class="control"> <div class="control">
<button class="button" type="submit"> <button class="button" type="submit">
@ -49,7 +49,7 @@
</div> </div>
</form> </form>
<div role="button" tabindex="0" class="navbar-burger pulldown-menu" data-controls="main-nav" aria-expanded="false"> <div role="button" tabindex="0" class="navbar-burger pulldown-menu" data-controls="main_nav" aria-expanded="false">
<div class="navbar-item mt-3"> <div class="navbar-item mt-3">
<div class="icon icon-dots-three-vertical" title="{% trans 'Main navigation menu' %}"> <div class="icon icon-dots-three-vertical" title="{% trans 'Main navigation menu' %}">
<span class="is-sr-only">{% trans "Main navigation menu" %}</span> <span class="is-sr-only">{% trans "Main navigation menu" %}</span>
@ -58,7 +58,7 @@
</div> </div>
</div> </div>
<div class="navbar-menu" id="main-nav"> <div class="navbar-menu" id="main_nav">
<div class="navbar-start"> <div class="navbar-start">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<a href="/#feed" class="navbar-item"> <a href="/#feed" class="navbar-item">
@ -67,8 +67,8 @@
<a href="{% url 'lists' %}" class="navbar-item"> <a href="{% url 'lists' %}" class="navbar-item">
{% trans "Lists" %} {% trans "Lists" %}
</a> </a>
<a href="{% url 'directory' %}" class="navbar-item"> <a href="{% url 'discover' %}" class="navbar-item">
{% trans "Directory" %} {% trans "Discover" %}
</a> </a>
{% endif %} {% endif %}
</div> </div>
@ -88,7 +88,12 @@
{% include 'snippets/avatar.html' with user=request.user %} {% include 'snippets/avatar.html' with user=request.user %}
<span class="ml-2">{{ request.user.display_name }}</span> <span class="ml-2">{{ request.user.display_name }}</span>
</a> </a>
<ul class="navbar-dropdown" id="navbar-dropdown"> <ul class="navbar-dropdown" id="navbar_dropdown">
<li>
<a href="{% url 'directory' %}" class="navbar-item">
{% trans "Directory" %}
</a>
</li>
<li> <li>
<a href="{% url 'user-shelves' request.user.localname %}" class="navbar-item"> <a href="{% url 'user-shelves' request.user.localname %}" class="navbar-item">
{% trans 'Your Books' %} {% trans 'Your Books' %}

View file

@ -75,7 +75,7 @@
</div> </div>
{% csrf_token %} {% csrf_token %}
<div class="control"> <div class="control">
<input id="input-list-position" class="input is-small" type="number" min="1" name="position" value="{{ item.order }}"> <input id="input_list_position" class="input is-small" type="number" min="1" name="position" value="{{ item.order }}">
</div> </div>
<div class="control"> <div class="control">
<button type="submit" class="button is-info is-small is-tablet">{% trans "Set" %}</button> <button type="submit" class="button is-info is-small is-tablet">{% trans "Set" %}</button>

View file

@ -14,7 +14,7 @@
{% if request.user == list.user %} {% if request.user == list.user %}
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Edit List" as button_text %} {% trans "Edit List" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit-list" focus="edit-list-header" %} {% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_list" focus="edit_list_header" %}
</div> </div>
{% endif %} {% endif %}
</header> </header>
@ -24,7 +24,7 @@
</div> </div>
<div class="block"> <div class="block">
{% include 'lists/edit_form.html' with controls_text="edit-list" %} {% include 'lists/edit_form.html' with controls_text="edit_list" %}
</div> </div>
{% block panel %}{% endblock %} {% block panel %}{% endblock %}

View file

@ -18,13 +18,13 @@
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Create List" as button_text %} {% trans "Create List" as button_text %}
{% include 'snippets/toggle/open_button.html' with controls_text="create-list" icon_with_text="plus" text=button_text focus="create-list-header" %} {% include 'snippets/toggle/open_button.html' with controls_text="create_list" icon_with_text="plus" text=button_text focus="create_list_header" %}
</div> </div>
{% endif %} {% endif %}
</header> </header>
<div class="block"> <div class="block">
{% include 'lists/create_form.html' with controls_text="create-list" %} {% include 'lists/create_form.html' with controls_text="create_list" %}
</div> </div>
{% if lists %} {% if lists %}

View file

@ -11,8 +11,13 @@
{% if login_form.non_field_errors %} {% if login_form.non_field_errors %}
<p class="notification is-danger">{{ login_form.non_field_errors }}</p> <p class="notification is-danger">{{ login_form.non_field_errors }}</p>
{% endif %} {% endif %}
{% if show_confirmed_email %}
<p class="notification is-success">{% trans "Success! Email address confirmed." %}</p>
{% endif %}
<form name="login" method="post" action="/login"> <form name="login" method="post" action="/login">
{% csrf_token %} {% csrf_token %}
{% if show_confirmed_email %}<input type="hidden" name="first_login" value="true">{% endif %}
<div class="field"> <div class="field">
<label class="label" for="id_localname">{% trans "Username:" %}</label> <label class="label" for="id_localname">{% trans "Username:" %}</label>
<div class="control"> <div class="control">

View file

@ -9,6 +9,6 @@ Want to Read "{{ book_title }}"
{% block content %} {% block content %}
{% include "snippets/shelve_button/want_to_read_modal.html" with book=book active=True no_body=True %} {% include "snippets/shelve_button/want_to_read_modal.html" with book=book active=True %}
{% endblock %} {% endblock %}

View file

@ -1,16 +1 @@
{% load i18n %} {{ user.display_name }} {{ item_title|striptags }}
{{ obj.user.display_name }}{% if obj.status_type == 'GeneratedNote' %}
{{ obj.content | safe }}
{% elif obj.status_type == 'Review' and not obj.name and not obj.content%}
{% trans "rated" %}
{% elif obj.status_type == 'Review' %}
{% trans "reviewed" %}
{% elif obj.status_type == 'Comment' %}
{% trans "commented on" %}
{% elif obj.status_type == 'Quotation' %}
{% trans "quoted" %}
{% endif %}
{% if obj.book %}{{ obj.book.title | safe}}
{% elif obj.mention_books %}
{{ obj.mention_books.first.title }}
{% endif %}

View file

@ -28,14 +28,14 @@
</div> </div>
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Open" as button_text %} {% trans "Open" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text controls_text="more-results-panel" controls_uid=result_set.connector.identifier class="is-small" icon_with_text="arrow-down" pressed=forloop.first %} {% include 'snippets/toggle/open_button.html' with text=button_text controls_text="more_results_panel" controls_uid=result_set.connector.identifier class="is-small" icon_with_text="arrow-down" pressed=forloop.first %}
{% trans "Close" as button_text %} {% trans "Close" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="more-results-panel" controls_uid=result_set.connector.identifier class="is-small" icon_with_text="arrow-up" pressed=forloop.first %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="more_results_panel" controls_uid=result_set.connector.identifier class="is-small" icon_with_text="arrow-up" pressed=forloop.first %}
</div> </div>
</header> </header>
{% endif %} {% endif %}
<div class="box has-background-white is-shadowless{% if not forloop.first %} is-hidden{% endif %}" id="more-results-panel-{{ result_set.connector.identifier }}"> <div class="box has-background-white is-shadowless{% if not forloop.first %} is-hidden{% endif %}" id="more_results_panel_{{ result_set.connector.identifier }}">
<div class="is-flex is-flex-direction-row-reverse"> <div class="is-flex is-flex-direction-row-reverse">
<div> <div>
</div> </div>

View file

@ -11,7 +11,7 @@
{% trans "Edit Announcement" as button_text %} {% trans "Edit Announcement" as button_text %}
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
{% include 'snippets/toggle/open_button.html' with controls_text="edit-announcement" icon_with_text="pencil" text=button_text focus="edit-announcement-header" %} {% include 'snippets/toggle/open_button.html' with controls_text="edit_announcement" icon_with_text="pencil" text=button_text focus="edit_announcement_header" %}
</div> </div>
<form class="control" action="{% url 'settings-announcements-delete' announcement.id %}" method="post"> <form class="control" action="{% url 'settings-announcements-delete' announcement.id %}" method="post">
{% csrf_token %} {% csrf_token %}
@ -26,7 +26,7 @@
{% block panel %} {% block panel %}
<form name="edit-announcement" method="post" action="{% url 'settings-announcements' announcement.id %}" class="block"> <form name="edit-announcement" method="post" action="{% url 'settings-announcements' announcement.id %}" class="block">
{% include 'settings/announcement_form.html' with controls_text="edit-announcement" %} {% include 'settings/announcement_form.html' with controls_text="edit_announcement" %}
</form> </form>
<div class="block content"> <div class="block content">

View file

@ -6,13 +6,13 @@
{% block edit-button %} {% block edit-button %}
{% trans "Create Announcement" as button_text %} {% trans "Create Announcement" as button_text %}
{% include 'snippets/toggle/open_button.html' with controls_text="create-announcement" icon_with_text="plus" text=button_text focus="create-announcement-header" %} {% include 'snippets/toggle/open_button.html' with controls_text="create_announcement" icon_with_text="plus" text=button_text focus="create_announcement_header" %}
</a> </a>
{% endblock %} {% endblock %}
{% block panel %} {% block panel %}
<form name="create-announcement" method="post" action="{% url 'settings-announcements' %}" class="block"> <form name="create-announcement" method="post" action="{% url 'settings-announcements' %}" class="block">
{% include 'settings/announcement_form.html' with controls_text="create-announcement" %} {% include 'settings/announcement_form.html' with controls_text="create_announcement" %}
</form> </form>
<table class="table is-striped"> <table class="table is-striped">

View file

@ -83,13 +83,13 @@
</div> </div>
<div class="column is-narrow"> <div class="column is-narrow">
{% trans "Edit" as button_text %} {% trans "Edit" as button_text %}
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit-notes" %} {% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_notes" %}
</div> </div>
</header> </header>
{% if server.notes %} {% if server.notes %}
<div class="box" id="hide-edit-notes">{{ server.notes|to_markdown|safe }}</div> <div class="box" id="hide_edit_notes">{{ server.notes|to_markdown|safe }}</div>
{% endif %} {% endif %}
<form class="box is-hidden" method="POST" action="{% url 'settings-federated-server' server.id %}" id="edit-notes"> <form class="box is-hidden" method="POST" action="{% url 'settings-federated-server' server.id %}" id="edit_notes">
{% csrf_token %} {% csrf_token %}
<p> <p>
<label class="is-sr-only" for="id_notes">Notes:</label> <label class="is-sr-only" for="id_notes">Notes:</label>
@ -97,7 +97,7 @@
</p> </p>
<button type="submit" class="button is-primary">{% trans "Save" %}</button> <button type="submit" class="button is-primary">{% trans "Save" %}</button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="edit-notes" %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="edit_notes" %}
</form> </form>
</section> </section>

View file

@ -9,7 +9,7 @@
<form action="{% url 'settings-site' %}" method="POST" class="content" enctype="multipart/form-data"> <form action="{% url 'settings-site' %}" method="POST" class="content" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<section class="block" id="instance-info"> <section class="block" id="instance_info">
<h2 class="title is-4">{% trans "Instance Info" %}</h2> <h2 class="title is-4">{% trans "Instance Info" %}</h2>
<div class="field"> <div class="field">
<label class="label" for="id_name">{% trans "Instance Name:" %}</label> <label class="label" for="id_name">{% trans "Instance Name:" %}</label>
@ -91,6 +91,13 @@
{% trans "Allow invite requests" %} {% trans "Allow invite requests" %}
</label> </label>
</div> </div>
<div class="field">
<label class="label mb-0" for="id_allow_invite_requests">
{{ site_form.require_confirm_email }}
{% trans "Require users to confirm email address" %}
</label>
<p class="help">{% trans "(Recommended if registration is open)" %}</p>
</div>
<div class="field"> <div class="field">
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label> <label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
{{ site_form.registration_closed_text }} {{ site_form.registration_closed_text }}

View file

@ -2,7 +2,7 @@
{% with announcement.id|uuid as uuid %} {% with announcement.id|uuid as uuid %}
<aside <aside
class="notification mb-1 p-3{% if not admin_mode %} is-hidden{% endif %} transition-y" class="notification mb-1 p-3{% if not admin_mode %} is-hidden{% endif %} transition-y"
{% if not admin_mode %}data-hide="hide-announcement-{{ announcement.id }}"{% endif %} {% if not admin_mode %}data-hide="hide_announcement_{{ announcement.id }}"{% endif %}
> >
<div class="columns mb-0 is-mobile"> <div class="columns mb-0 is-mobile">
<div class="column pb-0"> <div class="column pb-0">
@ -21,7 +21,7 @@
{% endif %} {% endif %}
</div> </div>
{% if announcement.content %} {% if announcement.content %}
<div class="mb-2 mt-2 {% if not pressed %}is-hidden{% endif %}" id="announcement-{{ uuid }}"> <div class="mb-2 mt-2 {% if not pressed %}is-hidden{% endif %}" id="announcement_{{ uuid }}">
<div class="box is-shadowless mb-0"> <div class="box is-shadowless mb-0">
{{ announcement.content|safe }} {{ announcement.content|safe }}
</div> </div>
@ -31,7 +31,7 @@
<p>{% blocktrans with user_path=announcement.user.local_path username=announcement.user.display_name %}Posted by <a href="{{ user_path }}">{{ username }}</a>{% endblocktrans %}</p> <p>{% blocktrans with user_path=announcement.user.local_path username=announcement.user.display_name %}Posted by <a href="{{ user_path }}">{{ username }}</a>{% endblocktrans %}</p>
{% if not admin_mode %} {% if not admin_mode %}
<span class="mr-2 ml-2" aria-hidden="true">&middot;</span> <span class="mr-2 ml-2" aria-hidden="true">&middot;</span>
<a class="set-display" data-id="hide-announcement-{{ announcement.id }}" data-value="true">{% trans "Dismiss message" %}</a> <a class="set-display" data-id="hide_announcement_{{ announcement.id }}" data-value="true">{% trans "Dismiss message" %}</a>
{% endif %} {% endif %}
</div> </div>
</aside> </aside>

View file

@ -19,7 +19,7 @@
itemtype="https://schema.org/Thing" itemtype="https://schema.org/Thing"
><span ><span
itemprop="name" itemprop="name"
>{{ author.name }}<span></a>{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %} >{{ author.name }}</span></a>{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %}
and {{ remainder_count_display }} other and {{ remainder_count_display }} other
{% plural %} {% plural %}
and {{ remainder_count_display }} others and {{ remainder_count_display }} others

View file

@ -8,8 +8,8 @@
name="boost" name="boost"
action="/boost/{{ status.id }}" action="/boost/{{ status.id }}"
method="post" method="post"
class="interaction boost-{{ status.id }}-{{ uuid }} {% if boosted %}is-hidden{% endif %}" class="interaction boost_{{ status.id }}_{{ uuid }}{% if boosted %} is-hidden{% endif %}"
data-id="boost-{{ status.id }}-{{ uuid }}" data-id="boost_{{ status.id }}_{{ uuid }}"
> >
{% csrf_token %} {% csrf_token %}
<button <button
@ -25,8 +25,8 @@
name="unboost" name="unboost"
action="/unboost/{{ status.id }}" action="/unboost/{{ status.id }}"
method="post" method="post"
class="interaction boost-{{ status.id }}-{{ uuid }} active {% if not boosted %}is-hidden{% endif %}" class="interaction boost_{{ status.id }}_{{ uuid }} active {% if not boosted %}is-hidden{% endif %}"
data-id="boost-{{ status.id }}-{{ uuid }}" data-id="boost_{{ status.id }}_{{ uuid }}"
> >
{% csrf_token %} {% csrf_token %}
<button class="button is-small is-light is-transparent" type="submit"> <button class="button is-small is-light is-transparent" type="submit">

View file

@ -9,10 +9,10 @@
<li class="{% if status_type == 'review' or not status_type %}is-active{% endif %}"> <li class="{% if status_type == 'review' or not status_type %}is-active{% endif %}">
<a <a
href="{{ request.path }}?status_type=review&book={{ book.id }}" href="{{ request.path }}?status_type=review&book={{ book.id }}"
id="tab-review-{{ book.id }}" id="tab_review_{{ book.id }}"
role="tab" role="tab"
aria-selected="{% if status_type == 'review' or not status_type %}true{% else %}false{% endif %}" aria-selected="{% if status_type == 'review' or not status_type %}true{% else %}false{% endif %}"
aria-controls="review-{{ book.id }}" aria-controls="review_{{ book.id }}"
data-category="tab-option-{{ book.id }}"> data-category="tab-option-{{ book.id }}">
{% trans "Review" %} {% trans "Review" %}
</a> </a>
@ -20,10 +20,10 @@
<li class="{% if status_type == 'comment' %}is-active{% endif %}"> <li class="{% if status_type == 'comment' %}is-active{% endif %}">
<a <a
href="{{ request.path }}?status_type=comment&book={{ book.id}}" href="{{ request.path }}?status_type=comment&book={{ book.id}}"
id="tab-comment-{{ book.id }}" id="tab_comment_{{ book.id }}"
role="tab" role="tab"
aria-selected="{% if status_type == 'comment' %}true{% else %}false{% endif %}" aria-selected="{% if status_type == 'comment' %}true{% else %}false{% endif %}"
aria-controls="comment-{{ book.id}}" aria-controls="comment_{{ book.id}}"
data-category="tab-option-{{ book.id }}"> data-category="tab-option-{{ book.id }}">
{% trans "Comment" %} {% trans "Comment" %}
</a> </a>
@ -31,10 +31,10 @@
<li class="{% if status_type == 'quote' %}is-active{% endif %}"> <li class="{% if status_type == 'quote' %}is-active{% endif %}">
<a <a
href="{{ request.path }}?status_type=quote&book={{ book.id }}" href="{{ request.path }}?status_type=quote&book={{ book.id }}"
id="tab-quote-{{ book.id }}" id="tab_quote_{{ book.id }}"
role="tab" role="tab"
aria-selected="{% if status_type == 'quote' %}true{% else %}false{% endif %}" aria-selected="{% if status_type == 'quote' %}true{% else %}false{% endif %}"
aria-controls="quote-{{ book.id }}" aria-controls="quote_{{ book.id }}"
data-category="tab-option-{{ book.id }}"> data-category="tab-option-{{ book.id }}">
{% trans "Quote" %} {% trans "Quote" %}
</a> </a>
@ -42,21 +42,21 @@
</ul> </ul>
</div> </div>
<div class="tab-option-{{ book.id }}" id="review-{{ book.id }}" role="tabpanel" aria-labelledby="tab-review-{{ book.id }}" {% if status_type and status_type != "review" %}hidden{% endif %}> <div class="tab-option-{{ book.id }}" id="review_{{ book.id }}" role="tabpanel" aria-labelledby="tab_review_{{ book.id }}" {% if status_type and status_type != "review" %}hidden{% endif %}>
{% with 0|uuid as uuid %} {% with 0|uuid as uuid %}
{% include 'snippets/create_status_form.html' with type='review' %} {% include 'snippets/create_status/status.html' with type="review" %}
{% endwith %} {% endwith %}
</div> </div>
<div class="tab-option-{{ book.id }}" id="comment-{{ book.id }}" role="tabpanel" aria-labelledby="tab-comment-{{ book.id }}" {% if status_type != "comment" %}hidden{% endif %}> <div class="tab-option-{{ book.id }}" id="comment_{{ book.id }}" role="tabpanel" aria-labelledby="tab_comment_{{ book.id }}" {% if status_type != "comment" %}hidden{% endif %}>
{% with 0|uuid as uuid %} {% with 0|uuid as uuid %}
{% include 'snippets/create_status_form.html' with type="comment" placeholder="Some thoughts on '"|add:book.title|add:"'" %} {% include 'snippets/create_status/status.html' with type="comment" %}
{% endwith %} {% endwith %}
</div> </div>
<div class="tab-option-{{ book.id }}" id="quote-{{ book.id }}" role="tabpanel" aria-labelledby="tab-quote-{{ book.id }}" {% if status_type != "quote" %}hidden{% endif %}> <div class="tab-option-{{ book.id }}" id="quote_{{ book.id }}" role="tabpanel" aria-labelledby="tab_quote_{{ book.id }}" {% if status_type != "quote" %}hidden{% endif %}>
{% with 0|uuid as uuid %} {% with 0|uuid as uuid %}
{% include 'snippets/create_status_form.html' with type="quotation" placeholder="An excerpt from '"|add:book.title|add:"'" %} {% include 'snippets/create_status/status.html' with type="quotation" %}
{% endwith %} {% endwith %}
</div> </div>
</div> </div>

View file

@ -0,0 +1,49 @@
{% extends "snippets/create_status/layout.html" %}
{% load bookwyrm_tags %}
{% load i18n %}
{% load utilities %}
{% load status_display %}
{% comment %}
----- Variables
book: the Edition object this status is related to. Required unless the status is a reply
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
{% endcomment %}
{% with type="comment" %}
{% trans "Some thoughts on the book" as placeholder %}
{% block post_content_additions %}
{# Supplemental fields #}
<div>
{% active_shelf book as active_shelf %}
{% if active_shelf.shelf.identifier == 'reading' and book.latest_readthrough %}
{% with readthrough=book.latest_readthrough %}
<div class="field">
<input type="hidden" name="id" value="{{ readthrough.id }}"/>
<label class="label" for="progress_{{ uuid }}">{% trans "Progress:" %}</label>
<div class="field has-addons mb-0">
<div class="control">
<input aria-label="{% if draft.progress_mode == 'PG' or readthrough.progress_mode == 'PG' %}Current page{% else %}Percent read{% endif %}" class="input" type="number" min="0" name="progress" size="3" value="{% firstof draft.progress readthrough.progress '' %}" id="progress_{{ uuid }}">
</div>
<div class="control">
<div class="select">
<select name="progress_mode" aria-label="Progress mode">
<option value="PG" {% if draft.progress_mode == 'PG' or readthrough.progress_mode == 'PG' %}selected{% endif %}>{% trans "pages" %}</option>
<option value="PCT" {% if draft.progress_mode == 'PCT' or readthrough.progress_mode == 'PCT' %}selected{% endif %}>{% trans "percent" %}</option>
</select>
</div>
</div>
</div>
{% if readthrough.progress_mode == 'PG' and book.pages %}
<p class="help">{% blocktrans with pages=book.pages %}of {{ pages }} pages{% endblocktrans %}</p>
{% endif %}
</div>
{% endwith %}
{% endif %}
</div>
{% endblock %}
{% endwith %}

View file

@ -0,0 +1,19 @@
{% load i18n %}
{% load status_display %}
{% load utilities %}
{% comment %}
type: used to differentiate html id fields when multiple types of posting are available for a book (options: comment, quotation, review, direct, reply)
book: the Edition object related to the status
reply_parent: if applicable, the Status object that this post is in reply to
mention: a user who is @ mentioned by default in the post
draft: an existing Status object that is providing default values for input fields
{% endcomment %}
<textarea
name="content"
class="textarea"
id="id_content_{{ type }}_{{ book.id }}{{ reply_parent.id }}"
placeholder="{{ placeholder }}"
aria-label="{% if reply_parent %}{% trans 'Reply' %}{% else %}{% trans 'Content' %}{% endif %}"
{% if type != "quotation" %}required{% endif %}
>{% if reply_parent %}{{ reply_parent|mentions:request.user }}{% endif %}{% if mention %}@{{ mention|username }} {% endif %}{{ draft.content|default:'' }}</textarea>

View file

@ -1,12 +1,12 @@
{% load i18n %} {% load i18n %}
<div class="control{% if not parent_status.content_warning and not draft.content_warning %} is-hidden{% endif %}" id="spoilers-{{ uuid }}"> <div class="control{% if not parent_status.content_warning and not draft.content_warning %} is-hidden{% endif %}" id="spoilers_{{ uuid }}">
<label class="is-sr-only" for="id_content_warning-{{ uuid }}">{% trans "Spoiler alert:" %}</label> <label class="is-sr-only" for="id_content_warning_{{ uuid }}">{% trans "Spoiler alert:" %}</label>
<input <input
type="text" type="text"
name="content_warning" name="content_warning"
maxlength="255" maxlength="255"
class="input" class="input"
id="id_content_warning-{{ uuid }}" id="id_content_warning_{{ uuid }}"
placeholder="{% trans 'Spoilers ahead!' %}" placeholder="{% trans 'Spoilers ahead!' %}"
value="{% firstof draft.content_warning parent_status.content_warning '' %}"> value="{% firstof draft.content_warning parent_status.content_warning '' %}">
</div> </div>

View file

@ -0,0 +1,8 @@
{% load i18n %}
<div class="control">
<input type="checkbox" class="is-hidden" name="sensitive" id="id_show_spoilers_{{ uuid }}" {% if draft.content_warning or status.content_warning %}checked{% endif %} aria-hidden="true">
{% trans "Include spoiler alert" as button_text %}
{% firstof draft.content_warning status.content_warning as pressed %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text icon="warning is-size-4" controls_text="spoilers" controls_uid=uuid focus="id_content_warning" checkbox="id_show_spoilers" class="toggle-button" pressed=pressed %}
</div>

View file

@ -0,0 +1,7 @@
{% extends "snippets/create_status/layout.html" %}
{# ----- Variables -----
type: the format of the status. options are "comment" "quotation" "review" "direct" "reply"
mention: the User object of a user who will show up at @ mentioned by default
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
#}

View file

@ -0,0 +1,57 @@
{% load bookwyrm_tags %}
{% load i18n %}
{% load utilities %}
{% load status_display %}
{% comment %}
----- Variables
book: the Edition object this status is related to. Required unless the status is a reply
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
type: used for uniquely identifying the html elements when mutliple types of posts are available for a book, and usually the endpoint name that the form posts to
reply_parent: the Status object this post will be in reply to, if applicable
{% endcomment %}
{% block form_open %}
{# default form tag syntax, can be overriddden #}
<form class="is-flex-grow-1" name="{{ type }}" action="/post/{{ type }}" method="post" id="tab_{{ type }}_{{ book.id }}{{ reply_parent.id }}">
{% endblock %}
{% csrf_token %}
{% block initial_fields %}
<input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="user" value="{{ request.user.id }}">
<input type="hidden" name="reply_parent" value="{% firstof draft.reply_parent.id reply_parent.id %}">
{% endblock %}
<div class="field">
<div class="control">
{% include "snippets/create_status/content_warning_field.html" %}
</div>
{# fields that go between the content warnings and the content field (ie, quote) #}
{% block pre_content_additions %}{% endblock %}
<label class="label" for="id_content_{{ type }}_{{ book.id }}{{ reply_parent.id }}">
{% block content_label %}
{% trans "Comment:" %}
{% endblock %}
</label>
<div class="control">
{% include "snippets/create_status/content_field.html" with placeholder=placeholder %}
</div>
</div>
{# additional fields that go after the content block (ie, progress) #}
{% block post_content_additions %}{% endblock %}
{% block options_block %}
{# cw, post privacy, and submit button #}
{% include "snippets/create_status/post_options_block.html" %}
{% endblock %}
{% block form_close %}
</form>
{% endblock %}

View file

@ -0,0 +1,22 @@
{% load i18n %}
<div class="columns mt-1">
<div class="field has-addons column">
{% include "snippets/create_status/content_warning_toggle.html" %}
<div class="control">
{% if type == 'direct' %}
<input type="hidden" name="privacy" value="direct">
<button type="button" class="button" aria-label="Privacy" disabled>{% trans "Private" %}</button>
{% else %}
{% if draft %}
{% include 'snippets/privacy_select.html' with current=draft.privacy %}
{% else %}
{% include 'snippets/privacy_select.html' with current=reply_parent.privacy %}
{% endif %}
{% endif %}
</div>
</div>
<div class="column is-narrow">
<button class="button is-link" type="submit">{% trans "Post" %}</button>
</div>
</div>

View file

@ -0,0 +1,34 @@
{% extends "snippets/create_status/layout.html" %}
{% load bookwyrm_tags %}
{% load utilities %}
{% load status_display %}
{% load i18n %}
{% comment %}
----- Variables
book: the Edition object this status is related to. Required unless the status is a reply
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
{% endcomment %}
{% with type="quotation" %}
{% block pre_content_additions %}
<div class="field">
<label class="label" for="id_quote_{{ book.id }}_{{ type }}">
{% trans "Quote:" %}
</label>
<div class="control">
<textarea
name="quote"
class="textarea"
id="id_quote_{{ book.id }}_{{ type }}"
placeholder="{% blocktrans with book_title=book.title %}An excerpt from '{{ book_title }}'{% endblocktrans %}"
required
>{{ draft.quote|default:'' }}</textarea>
</div>
</div>
{% endblock %}
{% endwith %}

View file

@ -0,0 +1,10 @@
{% extends "snippets/create_status/layout.html" %}
{# ----- Variables -----
reply_parent: the parent status, if the status is a reply
type: the format of the status. options are "comment" "quotation" "review" "direct" "reply"
mention: the User object of a user who will show up at @ mentioned by default
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
#}
{% block content_label %}{% endblock %}

View file

@ -0,0 +1,35 @@
{% extends "snippets/create_status/layout.html" %}
{% load bookwyrm_tags %}
{% load utilities %}
{% load status_display %}
{% load i18n %}
{% comment %}
----- Variables
book: the Edition object this status is related to. Required unless the status is a reply
draft: the content of an existing Status object to be edited (used in delete and redraft)
uuid: a unique identifier used to make html "id" attributes unique and clarify javascript controls
{% endcomment %}
{% with type="review" %}
{% block pre_content_additions %}
<div class="field">
<label class="label" for="id_name_{{ book.id }}">{% trans "Title:" %}</label>
<div class="control">
<input type="text" name="name" maxlength="255" class="input" required="" id="id_name_{{ book.id }}" placeholder="{% blocktrans with book_title=book.title %}Your review of '{{ book_title }}'{% endblocktrans %}" value="{% firstof draft.name ''%}">
</div>
</div>
<fieldset class="mb-1">
<legend class="is-sr-only">{% trans "Rating" %}</legend>
{% include 'snippets/form_rate_stars.html' with book=book type=type|default:'summary' default_rating=draft.rating %}
</fieldset>
{% endblock %}
{% block content_label %}
{% trans "Review:" %}
{% endblock %}
{% endwith %}

View file

@ -0,0 +1,2 @@
{# allows the "type" variable to inherit properly to the layout #}
{% include 'snippets/create_status/'|add:type|add:'.html' %}

View file

@ -1,131 +0,0 @@
{% load bookwyrm_tags %}
{% load utilities %}
{% load status_display %}
{% load i18n %}
<form class="is-flex-grow-1" name="{{ type }}" action="/post/{% if type == 'direct' %}status{% else %}{{ type }}{% endif %}" method="post" id="tab-{{ type }}-{{ book.id }}{{ reply_parent.id }}">
{% csrf_token %}
<input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="user" value="{{ request.user.id }}">
<input type="hidden" name="reply_parent" value="{% firstof draft.reply_parent.id reply_parent.id %}">
{% if type == 'review' %}
<div class="field">
<label class="label" for="id_name_{{ book.id }}_{{ type }}">{% trans "Title" %}:</label>
<div class="control">
<input type="text" name="name" maxlength="255" class="input" required="" id="id_name_{{ book.id }}_{{ type }}" placeholder="My {{ type }} of '{{ book.title }}'" value="{% firstof draft.name ''%}">
</div>
</div>
{% endif %}
<div class="field">
{% if type != 'reply' and type != 'direct' %}
<label class="label{% if type == 'review' %} mb-0{% endif %}" for="id_{% if type == 'quotation' %}quote{% else %}content{% endif %}_{{ book.id }}_{{ type }}">
{% if type == 'comment' %}
{% trans "Comment:" %}
{% elif type == 'quotation' %}
{% trans "Quote:" %}
{% elif type == 'review' %}
{% trans "Review:" %}
{% endif %}
</label>
{% endif %}
{% if type == 'review' %}
<fieldset class="mb-1">
<legend class="is-sr-only">{% trans "Rating" %}</legend>
{% include 'snippets/form_rate_stars.html' with book=book type=type|default:'summary' default_rating=draft.rating %}
</fieldset>
{% endif %}
<div class="control">
{% if type == 'quotation' %}
<textarea
name="quote"
class="textarea"
id="id_quote_{{ book.id }}_{{ type }}"
placeholder="{{ placeholder }}"
required
>{{ draft.quote|default:'' }}</textarea>
{% else %}
{% include 'snippets/content_warning_field.html' with parent_status=status %}
<textarea
name="content"
class="textarea"
id="id_content_{{ type }}-{{ book.id }}{{reply_parent.id}}"
placeholder="{{ placeholder }}"
aria-label="{% if reply_parent %}{% trans 'Reply' %}{% else %}{% trans "Content" %}{% endif %}"
required
>{% if reply_parent %}{{ reply_parent|mentions:request.user }}{% endif %}{% if mention %}@{{ mention|username }} {% endif %}{{ draft.content|default:'' }}</textarea>
{% endif %}
</div>
</div>
{# Supplemental fields #}
{% if type == 'quotation' %}
<div class="field">
<label class="label" for="id_content_quote-{{ book.id }}">{% trans "Comment" %}:</label>
{% include 'snippets/content_warning_field.html' with parent_status=status %}
<div class="control">
<textarea name="content" class="textarea" rows="3" id="id_content_quote-{{ book.id }}">{{ draft.content|default:'' }}</textarea>
</div>
</div>
{% elif type == 'comment' %}
<div>
{% active_shelf book as active_shelf %}
{% if active_shelf.shelf.identifier == 'reading' and book.latest_readthrough %}
{% with readthrough=book.latest_readthrough %}
<div class="field">
<input type="hidden" name="id" value="{{ readthrough.id }}"/>
<label class="label" for="progress-{{ uuid }}">{% trans "Progress:" %}</label>
<div class="field has-addons mb-0">
<div class="control">
<input aria-label="{% if draft.progress_mode == 'PG' or readthrough.progress_mode == 'PG' %}Current page{% else %}Percent read{% endif %}" class="input" type="number" min="0" name="progress" size="3" value="{% firstof draft.progress readthrough.progress '' %}" id="progress-{{ uuid }}">
</div>
<div class="control">
<div class="select">
<select name="progress_mode" aria-label="Progress mode">
<option value="PG" {% if draft.progress_mode == 'PG' or readthrough.progress_mode == 'PG' %}selected{% endif %}>{% trans "pages" %}</option>
<option value="PCT" {% if draft.progress_mode == 'PCT' or readthrough.progress_mode == 'PCT' %}selected{% endif %}>{% trans "percent" %}</option>
</select>
</div>
</div>
</div>
{% if readthrough.progress_mode == 'PG' and book.pages %}
<p class="help">{% blocktrans with pages=book.pages %}of {{ pages }} pages{% endblocktrans %}</p>
{% endif %}
</div>
{% endwith %}
{% endif %}
</div>
{% endif %}
{# bottom bar #}
<input type="checkbox" class="is-hidden" name="sensitive" id="id_show_spoilers-{{ uuid }}" {% if draft.content_warning or status.content_warning %}checked{% endif %} aria-hidden="true">
<div class="columns mt-1">
<div class="field has-addons column">
<div class="control">
{% trans "Include spoiler alert" as button_text %}
{% firstof draft.content_warning status.content_warning as pressed %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text icon="warning is-size-4" controls_text="spoilers" controls_uid=uuid focus="id_content_warning" checkbox="id_show_spoilers" class="toggle-button" pressed=pressed %}
</div>
<div class="control">
{% if type == 'direct' %}
<input type="hidden" name="privacy" value="direct">
<button type="button" class="button" aria-label="Privacy" disabled>{% trans "Private" %}</button>
{% else %}
{% if draft %}
{% include 'snippets/privacy_select.html' with current=draft.privacy %}
{% else %}
{% include 'snippets/privacy_select.html' with current=reply_parent.privacy %}
{% endif %}
{% endif %}
</div>
</div>
<div class="column is-narrow">
<button class="button is-link" type="submit">{% trans "Post" %}</button>
</div>
</div>
</form>

View file

@ -15,6 +15,6 @@
{% trans "Delete" %} {% trans "Delete" %}
</button> </button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="delete-readthrough" controls_uid=readthrough.id %} {% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="delete_readthrough" controls_uid=readthrough.id %}
</form> </form>
{% endblock %} {% endblock %}

View file

@ -4,7 +4,7 @@
{% with status.id|uuid as uuid %} {% with status.id|uuid as uuid %}
{% with request.user|liked:status as liked %} {% with request.user|liked:status as liked %}
<form name="favorite" action="/favorite/{{ status.id }}" method="POST" class="interaction fav-{{ status.id }}-{{ uuid }} {% if liked %}is-hidden{% endif %}" data-id="fav-{{ status.id }}-{{ uuid }}"> <form name="favorite" action="/favorite/{{ status.id }}" method="POST" class="interaction fav_{{ status.id }}_{{ uuid }} {% if liked %}is-hidden{% endif %}" data-id="fav_{{ status.id }}_{{ uuid }}">
{% csrf_token %} {% csrf_token %}
<button class="button is-small is-light is-transparent" type="submit"> <button class="button is-small is-light is-transparent" type="submit">
<span class="icon icon-heart m-0-mobile" title="{% trans 'Like' %}"> <span class="icon icon-heart m-0-mobile" title="{% trans 'Like' %}">
@ -12,7 +12,7 @@
<span class="is-sr-only-mobile">{% trans "Like" %}</span> <span class="is-sr-only-mobile">{% trans "Like" %}</span>
</button> </button>
</form> </form>
<form name="unfavorite" action="/unfavorite/{{ status.id }}" method="POST" class="interaction fav-{{ status.id }}-{{ uuid }} active {% if not liked %}is-hidden{% endif %}" data-id="fav-{{ status.id }}-{{ uuid }}"> <form name="unfavorite" action="/unfavorite/{{ status.id }}" method="POST" class="interaction fav_{{ status.id }}_{{ uuid }} active {% if not liked %}is-hidden{% endif %}" data-id="fav_{{ status.id }}_{{ uuid }}">
{% csrf_token %} {% csrf_token %}
<button class="button is-light is-transparent is-small" type="submit"> <button class="button is-light is-transparent is-small" type="submit">
<span class="icon icon-heart has-text-primary m-0-mobile" title="{% trans 'Un-like' %}"></span> <span class="icon icon-heart has-text-primary m-0-mobile" title="{% trans 'Un-like' %}"></span>

View file

@ -6,18 +6,32 @@
<div class="field{% if not minimal %} has-addons{% else %} mb-0{% endif %}"> <div class="field{% if not minimal %} has-addons{% else %} mb-0{% endif %}">
<div class="control"> <div class="control">
<form action="{% url 'follow' %}" method="POST" class="interaction follow-{{ user.id }} {% if request.user in user.followers.all or request.user in user.follower_requests.all %}is-hidden{%endif %}" data-id="follow-{{ user.id }}"> <form action="{% url 'follow' %}" method="POST" class="interaction follow_{{ user.id }} {% if request.user in user.followers.all or request.user in user.follower_requests.all %}is-hidden{%endif %}" data-id="follow_{{ user.id }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ user.username }}"> <input type="hidden" name="user" value="{{ user.username }}">
<button class="button is-small{% if not minimal %} is-link{% endif %}" type="submit">{% trans "Follow" %}</button> <button class="button is-small{% if not minimal %} is-link{% endif %}" type="submit">
{% if show_username %}
{% blocktrans with username=user.localname %}Follow @{{ username }}{% endblocktrans %}
{% else %}
{% trans "Follow" %}
{% endif %}
</button>
</form> </form>
<form action="{% url 'unfollow' %}" method="POST" class="interaction follow-{{ user.id }} {% if not request.user in user.followers.all and not request.user in user.follower_requests.all %}is-hidden{%endif %}" data-id="follow-{{ user.id }}"> <form action="{% url 'unfollow' %}" method="POST" class="interaction follow_{{ user.id }} {% if not request.user in user.followers.all and not request.user in user.follower_requests.all %}is-hidden{%endif %}" data-id="follow_{{ user.id }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ user.username }}"> <input type="hidden" name="user" value="{{ user.username }}">
{% if user.manually_approves_followers and request.user not in user.followers.all %} {% if user.manually_approves_followers and request.user not in user.followers.all %}
<button class="button is-small is-danger is-light" type="submit">{% trans "Undo follow request" %}</button> <button class="button is-small is-danger is-light" type="submit">
{% trans "Undo follow request" %}
</button>
{% else %} {% else %}
<button class="button is-small is-danger is-light" type="submit">{% trans "Unfollow" %}</button> <button class="button is-small is-danger is-light" type="submit">
{% if show_username %}
{% blocktrans with username=user.localname %}Unfollow @{{ username }}{% endblocktrans %}
{% else %}
{% trans "Unfollow" %}
{% endif %}
</button>
{% endif %} {% endif %}
</form> </form>
</div> </div>

View file

@ -7,7 +7,7 @@
{% if classes %}{{classes}}{% endif%} {% if classes %}{{classes}}{% endif%}
"> ">
<input <input
id="{{ type|slugify }}-{{ book.id }}-no-rating" id="{{ type|slugify }}_{{ book.id }}_no_rating"
class="is-sr-only" class="is-sr-only"
type="radio" type="radio"
name="rating" name="rating"
@ -15,13 +15,13 @@
{% if default_rating == 0 or not default_rating %}checked{% endif %} {% if default_rating == 0 or not default_rating %}checked{% endif %}
> >
<label class="is-sr-only" for="{{ type|slugify }}-{{ book.id }}-no-rating"> <label class="is-sr-only" for="{{ type|slugify }}_{{ book.id }}_no_rating">
{% trans "No rating" %} {% trans "No rating" %}
</label> </label>
{% for i in '12345'|make_list %} {% for i in '12345'|make_list %}
<input <input
id="{{ type|slugify }}-book{{ book.id }}-star-{{ forloop.counter }}" id="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
class="is-sr-only" class="is-sr-only"
type="radio" type="radio"
name="rating" name="rating"
@ -38,7 +38,7 @@
icon-star-empty icon-star-empty
{% endif %} {% endif %}
" "
for="{{ type|slugify }}-book{{ book.id }}-star-{{ forloop.counter }}" for="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
> >
<span class="is-sr-only"> <span class="is-sr-only">
{% blocktranslate trimmed count rating=forloop.counter %} {% blocktranslate trimmed count rating=forloop.counter %}

View file

@ -1 +1,6 @@
{% load i18n %}{% load humanize %}{% blocktrans count counter=goal.goal with counter=goal.goal year=goal.year %}set a goal to read {{ counter }} book in {{ year }}{% plural %}set a goal to read {{ counter }} books in {{ year }}{% endblocktrans %} {% load i18n %}{% load humanize %}
{% blocktranslate trimmed count counter=goal.goal with counter=goal.goal year=goal.year %}
set a goal to read {{ counter }} book in {{ year }}
{% plural %}
set a goal to read {{ counter }} books in {{ year }}
{% endblocktranslate %}

View file

@ -1,3 +1,7 @@
{% load i18n %}{% load humanize %} {% load i18n %}{% load humanize %}{% load utilities %}
{% blocktrans with title=book.title path=book.remote_id display_rating=rating|floatformat:"0" count counter=rating %}Rated <em><a href="{{ path }}">{{ title }}</a></em>: {{ display_rating }} star{% plural %}Rated <em><a href="{{ path }}">{{ title }}</a></em>: {{ display_rating }} stars{% endblocktrans %} {% blocktrans trimmed with title=book|book_title path=book.remote_id display_rating=rating|floatformat:"0" count counter=rating|add:0 %}
rated <em><a href="{{ path }}">{{ title }}</a></em>: {{ display_rating }} star
{% plural %}
rated <em><a href="{{ path }}">{{ title }}</a></em>: {{ display_rating }} stars
{% endblocktrans %}

View file

@ -30,7 +30,7 @@
<button type="submit" class="button is-link">{% trans "Set goal" %}</button> <button type="submit" class="button is-link">{% trans "Set goal" %}</button>
{% if goal %} {% if goal %}
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="show-edit-goal" %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="show_edit_goal" %}
{% endif %} {% endif %}
</p> </p>
</form> </form>

View file

@ -3,10 +3,10 @@
<div class="select {{ class }}"> <div class="select {{ class }}">
{% with 0|uuid as uuid %} {% with 0|uuid as uuid %}
{% if not no_label %} {% if not no_label %}
<label class="is-sr-only" for="privacy-{{ uuid }}">{% trans "Post privacy" %}</label> <label class="is-sr-only" for="privacy_{{ uuid }}">{% trans "Post privacy" %}</label>
{% endif %} {% endif %}
{% firstof current user.default_post_privacy "public" as privacy %} {% firstof current user.default_post_privacy "public" as privacy %}
<select name="privacy" id="privacy-{{ uuid }}"> <select name="privacy" id="privacy_{{ uuid }}">
<option value="public" {% if privacy == 'public' %}selected{% endif %}> <option value="public" {% if privacy == 'public' %}selected{% endif %}>
{% trans "Public" %} {% trans "Public" %}
</option> </option>

View file

@ -3,19 +3,19 @@
<input type="hidden" name="id" value="{{ readthrough.id }}"> <input type="hidden" name="id" value="{{ readthrough.id }}">
<input type="hidden" name="book" value="{{ book.id }}"> <input type="hidden" name="book" value="{{ book.id }}">
<div class="field"> <div class="field">
<label class="label" tabindex="0" id="add-readthrough-focus" for="id_start_date-{{ readthrough.id }}"> <label class="label" tabindex="0" id="add_readthrough_focus_{{ readthrough.id }}" for="id_start_date_{{ readthrough.id }}">
{% trans "Started reading" %} {% trans "Started reading" %}
</label> </label>
<input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}"> <input type="date" name="start_date" class="input" id="id_start_date_{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</div> </div>
{# Only show progress for editing existing readthroughs #} {# Only show progress for editing existing readthroughs #}
{% if readthrough.id and not readthrough.finish_date %} {% if readthrough.id and not readthrough.finish_date %}
<label class="label" for="id_progress-{{ readthrough.id }}"> <label class="label" for="id_progress_{{ readthrough.id }}">
{% trans "Progress" %} {% trans "Progress" %}
</label> </label>
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
<input type="number" name="progress" class="input" id="id_progress-{{ readthrough.id }}" value="{{ readthrough.progress }}"> <input type="number" name="progress" class="input" id="id_progress_{{ readthrough.id }}" value="{{ readthrough.progress }}">
</div> </div>
<div class="control select"> <div class="control select">
<select name="progress_mode" aria-label="Progress mode"> <select name="progress_mode" aria-label="Progress mode">
@ -26,8 +26,8 @@
</div> </div>
{% endif %} {% endif %}
<div class="field"> <div class="field">
<label class="label" for="id_finish_date-{{ readthrough.id }}"> <label class="label" for="id_finish_date_{{ readthrough.id }}">
{% trans "Finished reading" %} {% trans "Finished reading" %}
</label> </label>
<input type="date" name="finish_date" class="input" id="id_finish_date-{{ readthrough.id }}" value="{{ readthrough.finish_date | date:"Y-m-d" }}"> <input type="date" name="finish_date" class="input" id="id_finish_date_{{ readthrough.id }}" value="{{ readthrough.finish_date | date:"Y-m-d" }}">
</div> </div>

View file

@ -12,7 +12,7 @@
<div class="field"> <div class="field">
<label class="label" for="id_email_register">{% trans "Email address:" %}</label> <label class="label" for="id_email_register">{% trans "Email address:" %}</label>
<div class="control"> <div class="control">
<input type="email" name="email" maxlength="254" class="input" id="id_email_register" value="{% if register_form.email.value %}{{ register_form.email.value }}{% endif %}"> <input type="email" name="email" maxlength="254" class="input" id="id_email_register" value="{% if register_form.email.value %}{{ register_form.email.value }}{% endif %}" required>
{% for error in register_form.email.errors %} {% for error in register_form.email.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}

View file

@ -4,7 +4,7 @@
{% with 0|uuid as report_uuid %} {% with 0|uuid as report_uuid %}
{% trans "Report" as button_text %} {% trans "Report" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with class="is-danger is-light is-small is-fullwidth" text=button_text controls_text="report" controls_uid=report_uuid focus="modal-title-report" disabled=is_current %} {% include 'snippets/toggle/toggle_button.html' with class="is-danger is-light is-small is-fullwidth" text=button_text controls_text="report" controls_uid=report_uuid focus="modal_title_report" disabled=is_current %}
{% include 'moderation/report_modal.html' with user=user reporter=request.user controls_text="report" controls_uid=report_uuid %} {% include 'moderation/report_modal.html' with user=user reporter=request.user controls_text="report" controls_uid=report_uuid %}

View file

@ -19,13 +19,13 @@
{% endif %} {% endif %}
</div> </div>
{% include 'snippets/shelve_button/want_to_read_modal.html' with book=active_shelf.book controls_text="want-to-read" controls_uid=uuid no_body=True %} {% include 'snippets/shelve_button/want_to_read_modal.html' with book=active_shelf.book controls_text="want_to_read" controls_uid=uuid %}
{% include 'snippets/shelve_button/start_reading_modal.html' with book=active_shelf.book controls_text="start-reading" controls_uid=uuid %} {% include 'snippets/shelve_button/start_reading_modal.html' with book=active_shelf.book controls_text="start_reading" controls_uid=uuid %}
{% include 'snippets/shelve_button/finish_reading_modal.html' with book=active_shelf.book controls_text="finish-reading" controls_uid=uuid readthrough=readthrough %} {% include 'snippets/shelve_button/finish_reading_modal.html' with book=active_shelf.book controls_text="finish_reading" controls_uid=uuid readthrough=readthrough %}
{% include 'snippets/shelve_button/progress_update_modal.html' with book=active_shelf_book.book controls_text="progress-update" controls_uid=uuid readthrough=readthrough %} {% include 'snippets/shelve_button/progress_update_modal.html' with book=active_shelf_book.book controls_text="progress_update" controls_uid=uuid readthrough=readthrough %}
{% endwith %} {% endwith %}
{% endif %} {% endif %}

View file

@ -10,7 +10,7 @@
{% trans "Start reading" as button_text %} {% trans "Start reading" as button_text %}
{% url 'reading-status' 'start' book.id as fallback_url %} {% url 'reading-status' 'start' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="start-reading" controls_uid=button_uuid focus="modal-title-start-reading" disabled=is_current fallback_url=fallback_url %} {% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="start_reading" controls_uid=button_uuid focus="modal_title_start_reading" disabled=is_current fallback_url=fallback_url %}
{% endif %}{% elif shelf.identifier == 'read' and active_shelf.shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %} {% endif %}{% elif shelf.identifier == 'read' and active_shelf.shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
<button type="button" class="button {{ class }}" disabled><span>{% trans "Read" %}</span> <button type="button" class="button {{ class }}" disabled><span>{% trans "Read" %}</span>
@ -18,13 +18,13 @@
{% trans "Finish reading" as button_text %} {% trans "Finish reading" as button_text %}
{% url 'reading-status' 'finish' book.id as fallback_url %} {% url 'reading-status' 'finish' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="finish-reading" controls_uid=button_uuid focus="modal-title-finish-reading" disabled=is_current fallback_url=fallback_url %} {% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="finish_reading" controls_uid=button_uuid focus="modal_title_finish_reading" disabled=is_current fallback_url=fallback_url %}
{% endif %}{% elif shelf.identifier == 'to-read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %} {% endif %}{% elif shelf.identifier == 'to-read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
{% trans "Want to read" as button_text %} {% trans "Want to read" as button_text %}
{% url 'reading-status' 'want' book.id as fallback_url %} {% url 'reading-status' 'want' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="want-to-read" controls_uid=button_uuid focus="modal-title-want-to-read" disabled=is_current fallback_url=fallback_url %} {% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="want_to_read" controls_uid=button_uuid focus="modal_title_want_to_read" disabled=is_current fallback_url=fallback_url %}
{% endif %}{% elif shelf.editable %} {% endif %}{% elif shelf.editable %}
<form name="shelve" action="/shelve/" method="post"> <form name="shelve" action="/shelve/" method="post">
@ -43,7 +43,7 @@
{% if readthrough and active_shelf.shelf.identifier != 'read' %} {% if readthrough and active_shelf.shelf.identifier != 'read' %}
<li role="menuitem" class="dropdown-item p-0"> <li role="menuitem" class="dropdown-item p-0">
{% trans "Update progress" as button_text %} {% trans "Update progress" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="progress-update" controls_uid=button_uuid focus="modal-title-progress-update" %} {% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="progress_update" controls_uid=button_uuid focus="modal_title_progress_update" %}
</li> </li>
{% endif %} {% endif %}

View file

@ -4,7 +4,7 @@
<span class="stars"> <span class="stars">
<span class="is-sr-only"> <span class="is-sr-only">
{% if rating %} {% if rating %}
{% blocktranslate trimmed with rating=rating|floatformat count counter=rating|length %} {% blocktranslate trimmed with rating=rating|floatformat:0 count counter=rating|floatformat:0|add:0 %}
{{ rating }} star {{ rating }} star
{% plural %} {% plural %}
{{ rating }} stars {{ rating }} stars

View file

@ -71,7 +71,7 @@
{% trans "Show more" as button_text %} {% trans "Show more" as button_text %}
{% with text=button_text class="is-small" controls_text="show-status-cw" controls_uid=status.id %} {% with text=button_text class="is-small" controls_text="show_status_cw" controls_uid=status.id %}
{% include 'snippets/toggle/open_button.html' %} {% include 'snippets/toggle/open_button.html' %}
{% endwith %} {% endwith %}
</div> </div>
@ -79,14 +79,14 @@
<div <div
{% if status.content_warning %} {% if status.content_warning %}
id="show-status-cw-{{ status.id }}" id="show_status_cw_{{ status.id }}"
class="is-hidden" class="is-hidden"
{% endif %} {% endif %}
> >
{% if status.content_warning %} {% if status.content_warning %}
{% trans "Show less" as button_text %} {% trans "Show less" as button_text %}
{% with text=button_text class="is-small" controls_text="show-status-cw" controls_uid=status.id %} {% with text=button_text class="is-small" controls_text="show_status_cw" controls_uid=status.id %}
{% include 'snippets/toggle/close_button.html' %} {% include 'snippets/toggle/close_button.html' %}
{% endwith %} {% endwith %}
{% endif %} {% endif %}

View file

@ -0,0 +1,48 @@
{% load utilities %}
{% load status_display %}
{% load i18n %}
{% load humanize %}
<div class="media">
<figure class="media-left" aria-hidden="true">
<a class="image is-48x48" href="{{ status.user.local_path }}">
{% include 'snippets/avatar.html' with user=status.user ariaHide="true" medium="true" %}
</a>
</figure>
<div class="media-content">
<h3 class="has-text-weight-bold">
<span
itemprop="author"
itemscope
itemtype="https://schema.org/Person"
>
{% if status.user.avatar %}
<meta itemprop="image" content="/images/{{ status.user.avatar }}">
{% endif %}
<a
href="{{ status.user.local_path }}"
itemprop="url"
>
<span itemprop="name">{{ status.user.display_name }}</span>
</a>
</span>
{% include "snippets/status/header_content.html" %}
</h3>
<p class="is-size-7 is-flex is-align-items-center">
<a href="{{ status.remote_id }}">{{ status.published_date|published_date }}</a>
{% if status.progress %}
<span class="ml-1">
{% if status.progress_mode == 'PG' %}
({% include 'snippets/page_text.html' with page=status.progress total_pages=status.book.pages %})
{% else %}
({{ status.progress }}%)
{% endif %}
</span>
{% endif %}
{% include 'snippets/privacy-icons.html' with item=status %}
</p>
</div>
</div>

View file

@ -0,0 +1,4 @@
{% spaceless %}
{% load status_display %}
{% get_header_template status %}
{% endspaceless %}

View file

@ -0,0 +1,2 @@
{% load i18n %}{% load utilities %}
{% blocktrans with book_path=book.local_path book=status.book|book_title %}commented on <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}

View file

@ -0,0 +1,5 @@
{% spaceless %}
{% load i18n %}{% load humanize %}
{{ status.content }}
{% endspaceless %}

View file

@ -0,0 +1,22 @@
{% spaceless %}
{% load i18n %}
{% load status_display %}
{% load utilities %}
{% if status.status_type == 'GeneratedNote' %}
{% with book=status.mention_books.first %}
{{ status.content|safe }} <a href="{{ book.local_path }}">{{ book|book_title }}</a>
{% endwith %}
{% else %}
{% with parent_status=status|parent %}
{% if parent_status %}
{% blocktrans trimmed with username=parent_status.user.display_name user_path=parent_status.user.local_path status_path=parent_status.local_path %}
replied to <a href="{{ user_path }}">{{ username}}</a>'s <a href="{{ status_path }}">status</a>
{% endblocktrans %}
{% endif %}
{% endwith %}
{% endif %}
{% endspaceless %}

View file

@ -0,0 +1,2 @@
{% load i18n %}{% load utilities %}
{% blocktrans with book_path=status.book.local_path book=status.book|book_title %}quoted <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}

View file

@ -0,0 +1,25 @@
{% load i18n %}{% load utilities %}
{% blocktrans with book_path=status.book.local_path book=status.book|book_title %}rated <a href="{{ book_path }}">{{ book }}</a>:{% endblocktrans %} {% include 'snippets/stars.html' with rating=status.rating %}
<span
itemprop="reviewRating"
itemscope
itemtype="https://schema.org/Rating"
>
<span class="is-hidden" {{ rating_type }}>
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
<span
itemprop="reviewRating"
itemscope
itemtype="https://schema.org/Rating"
>
<span class="is-hidden" {{ rating_type }}>
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
{# @todo Is it possible to not hard-code the value? #}
<meta itemprop="bestRating" content="5">
</span>
</span>
</span>
</span>

View file

@ -0,0 +1,7 @@
{% spaceless %}
{% load i18n %}{% load utilities %}
{% with book=status.mention_books.first %}
{% blocktrans with book_path=book.remote_id book=book|book_title %}finished reading <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}
{% endwith %}
{% endspaceless %}

View file

@ -0,0 +1,9 @@
{% spaceless %}
{% load i18n %}
{% load utilities %}
{% with book=status.mention_books.first %}
{% blocktrans with book_path=book.remote_id book=book|book_title %}started reading <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}
{% endwith %}
{% endspaceless %}

View file

@ -0,0 +1,3 @@
{% load i18n %}{% load utilities %}
{% blocktrans with book_path=status.book.local_path book=status.book|book_title %}reviewed <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}

View file

@ -0,0 +1,8 @@
{% spaceless %}
{% load i18n %}
{% load utilities %}
{% with book=status.mention_books.first %}
{% blocktrans with book_path=book.remote_id book=book|book_title %}<a href="{{ user_path }}">{{ username }}</a> wants to read <a href="{{ book_path }}">{{ book }}</a>{% endblocktrans %}
{% endwith %}
{% endspaceless %}

View file

@ -4,7 +4,7 @@
{% block card-header %} {% block card-header %}
<div class="card-header-title has-background-white-ter is-block"> <div class="card-header-title has-background-white-ter is-block">
{% include 'snippets/status/status_header.html' with status=status %} {% include 'snippets/status/header.html' with status=status %}
</div> </div>
{% endblock %} {% endblock %}
@ -12,8 +12,8 @@
{% block card-footer %} {% block card-footer %}
{% if moderation_mode and perms.bookwyrm.moderate_post %} {% if moderation_mode and perms.bookwyrm.moderate_post %}
<div class="card-footer-item">
<div class="card-footer-item">
{# moderation options #} {# moderation options #}
<form name="delete-{{ status.id }}" action="/delete-status/{{ status.id }}" method="post"> <form name="delete-{{ status.id }}" action="/delete-status/{{ status.id }}" method="post">
{% csrf_token %} {% csrf_token %}
@ -22,12 +22,14 @@
</button> </button>
</form> </form>
</div> </div>
{% elif no_interact %} {% elif no_interact %}
{# nothing here #} {# nothing here #}
{% elif request.user.is_authenticated %} {% elif request.user.is_authenticated %}
<div class="card-footer-item"> <div class="card-footer-item">
{% trans "Reply" as button_text %} {% trans "Reply" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with controls_text="show-comment" controls_uid=status.id text=button_text icon_with_text="comment" class="is-small is-light is-transparent toggle-button" focus="id_content_reply" %} {% include 'snippets/toggle/toggle_button.html' with controls_text="show_comment" controls_uid=status.id text=button_text icon_with_text="comment" class="is-small is-light is-transparent toggle-button" focus="id_content_reply" %}
</div> </div>
<div class="card-footer-item"> <div class="card-footer-item">
{% include 'snippets/boost_button.html' with status=status %} {% include 'snippets/boost_button.html' with status=status %}
@ -57,16 +59,17 @@
</span> </span>
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block card-bonus %} {% block card-bonus %}
{% if request.user.is_authenticated and not moderation_mode %} {% if request.user.is_authenticated and not moderation_mode %}
{% with status.id|uuid as uuid %} {% with status.id|uuid as uuid %}
<section class="is-hidden" id="show-comment-{{ status.id }}"> <section class="is-hidden" id="show_comment_{{ status.id }}">
<div class="card-footer"> <div class="card-footer">
<div class="card-footer-item"> <div class="card-footer-item">
{% include 'snippets/create_status_form.html' with reply_parent=status type="reply" %} {% include 'snippets/create_status/status.html' with type="reply" reply_parent=status book=None %}
</div> </div>
</div> </div>
</section> </section>

View file

@ -8,8 +8,8 @@
{{ status.user.display_name }} {{ status.user.display_name }}
</a> </a>
{% trans "boosted" %} {% trans "boosted" %}
{% include 'snippets/status/status_body.html' with status=status|boosted_status %} {% include 'snippets/status/body.html' with status=status|boosted_status %}
{% else %} {% else %}
{% include 'snippets/status/status_body.html' with status=status %} {% include 'snippets/status/body.html' with status=status %}
{% endif %} {% endif %}
{% endif %} {% endif %}

Some files were not shown because too many files have changed in this diff Show more