mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-23 08:36:32 +00:00
Merge branch 'main' into frontend-book-cover
This commit is contained in:
commit
30bed6c963
17 changed files with 404 additions and 377 deletions
|
@ -29,6 +29,40 @@ body {
|
|||
min-width: 75% !important;
|
||||
}
|
||||
|
||||
/** Utilities not covered by Bulma
|
||||
******************************************************************************/
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.is-sr-only-mobile {
|
||||
border: none !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
height: 0.01em !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: absolute !important;
|
||||
white-space: nowrap !important;
|
||||
width: 0.01em !important;
|
||||
}
|
||||
|
||||
.m-0-mobile {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.card.is-stretchable {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.card.is-stretchable .card-content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/** Shelving
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -257,3 +291,53 @@ body {
|
|||
height: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Book preview table
|
||||
******************************************************************************/
|
||||
|
||||
.book-preview td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
table.is-mobile,
|
||||
table.is-mobile tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.is-mobile tr {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
border-top: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
table.is-mobile td {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 100%;
|
||||
order: 2;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
table.is-mobile td.book-preview-top-row {
|
||||
order: 1;
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
table.is-mobile td[data-title]:not(:empty)::before {
|
||||
content: attr(data-title);
|
||||
display: block;
|
||||
font-size: 0.75em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.is-mobile td:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.is-mobile th,
|
||||
table.is-mobile thead {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,7 +245,36 @@
|
|||
</div>
|
||||
|
||||
<div class="block" id="reviews">
|
||||
{% for review in reviews %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<nav class="tabs">
|
||||
<ul>
|
||||
{% url 'book' book.id as tab_url %}
|
||||
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
||||
<a href="{{ tab_url }}">{% trans "Reviews" %} ({{ review_count }})</a>
|
||||
</li>
|
||||
{% if user_statuses.review_count %}
|
||||
{% url 'book-user-statuses' book.id 'review' as tab_url %}
|
||||
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
||||
<a href="{{ tab_url }}">{% trans "Your reviews" %} ({{ user_statuses.review_count }})</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user_statuses.comment_count %}
|
||||
{% url 'book-user-statuses' book.id 'comment' as tab_url %}
|
||||
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
||||
<a href="{{ tab_url }}">{% trans "Your comments" %} ({{ user_statuses.comment_count }})</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if user_statuses.quotation_count %}
|
||||
{% url 'book-user-statuses' book.id 'quote' as tab_url %}
|
||||
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
||||
<a href="{{ tab_url }}">{% trans "Your quotes" %} ({{ user_statuses.quotation_count }})</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
{% for review in statuses %}
|
||||
<div
|
||||
class="block"
|
||||
itemprop="review"
|
||||
|
@ -286,7 +315,7 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
<div class="block">
|
||||
{% include 'snippets/pagination.html' with page=reviews path=book.local_path anchor="#reviews" %}
|
||||
{% include 'snippets/pagination.html' with page=statuses path=request.path anchor="#reviews" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<div class="columns is-multiline">
|
||||
{% for user in users %}
|
||||
<div class="column is-one-third">
|
||||
<div class="card block">
|
||||
<div class="card is-stretchable">
|
||||
<div class="card-content">
|
||||
<div class="media">
|
||||
<a href="{{ user.local_path }}" class="media-left">
|
||||
|
@ -56,13 +56,13 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div>
|
||||
{% if user.summary %}
|
||||
{{ user.summary | to_markdown | safe | truncatechars_html:40 }}
|
||||
{% else %} {% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<footer class="card-footer content">
|
||||
<footer class="card-footer">
|
||||
{% if user != request.user %}
|
||||
{% if user.mutuals %}
|
||||
<div class="card-footer-item">
|
||||
|
|
|
@ -4,18 +4,16 @@
|
|||
{% with status.id|uuid as uuid %}
|
||||
<form name="boost" action="/boost/{{ status.id }}" method="post" class="interaction boost-{{ status.id }}-{{ uuid }} {% if request.user|boosted:status %}is-hidden{% endif %}" data-id="boost-{{ status.id }}-{{ uuid }}">
|
||||
{% csrf_token %}
|
||||
<button class="button is-small" type="submit" {% if not status.boostable %}disabled{% endif %}>
|
||||
<span class="icon icon-boost" title="{% trans 'Boost status' %}">
|
||||
<span class="is-sr-only">{% trans "Boost status" %}</span>
|
||||
</span>
|
||||
<button class="button is-small is-light is-transparent" type="submit" {% if not status.boostable %}disabled{% endif %}>
|
||||
<span class="icon icon-boost m-0-mobile" title="{% trans 'Boost' %}"></span>
|
||||
<span class="is-sr-only-mobile">{% trans "Boost" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
<form name="unboost" action="/unboost/{{ status.id }}" method="post" class="interaction boost-{{ status.id }}-{{ uuid }} active {% if not request.user|boosted:status %}is-hidden{% endif %}" data-id="boost-{{ status.id }}-{{ uuid }}">
|
||||
{% csrf_token %}
|
||||
<button class="button is-small is-primary" type="submit">
|
||||
<span class="icon icon-boost" title="{% trans 'Un-boost status' %}">
|
||||
<span class="is-sr-only">{% trans "Un-boost status" %}</span>
|
||||
</span>
|
||||
<button class="button is-small is-light is-transparent" type="submit">
|
||||
<span class="icon icon-boost has-text-primary m-0-mobile" title="{% trans 'Un-boost' %}"></span>
|
||||
<span class="is-sr-only-mobile">{% trans "Un-boost" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
{% endwith %}
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
{% with status.id|uuid as uuid %}
|
||||
<form name="favorite" action="/favorite/{{ status.id }}" method="POST" class="interaction fav-{{ status.id }}-{{ uuid }} {% if request.user|liked:status %}is-hidden{% endif %}" data-id="fav-{{ status.id }}-{{ uuid }}">
|
||||
{% csrf_token %}
|
||||
<button class="button is-small" type="submit">
|
||||
<span class="icon icon-heart" title="{% trans 'Like status' %}">
|
||||
<span class="is-sr-only">{% trans "Like status" %}</span>
|
||||
<button class="button is-small is-light is-transparent" type="submit">
|
||||
<span class="icon icon-heart m-0-mobile" title="{% trans 'Like' %}">
|
||||
</span>
|
||||
<span class="is-sr-only-mobile">{% trans "Like" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
<form name="unfavorite" action="/unfavorite/{{ status.id }}" method="POST" class="interaction fav-{{ status.id }}-{{ uuid }} active {% if not request.user|liked:status %}is-hidden{% endif %}" data-id="fav-{{ status.id }}-{{ uuid }}">
|
||||
{% csrf_token %}
|
||||
<button class="button is-primary is-small" type="submit">
|
||||
<span class="icon icon-heart" title="{% trans 'Un-like status' %}">
|
||||
<span class="is-sr-only">{% trans "Un-like status" %}</span>
|
||||
</span>
|
||||
<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="is-sr-only-mobile">{% trans "Un-like" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
{% endwith %}
|
||||
|
|
|
@ -14,10 +14,17 @@
|
|||
{% if not hide_book %}
|
||||
{% with book=status.book|default:status.mention_books.first %}
|
||||
{% if book %}
|
||||
<div class="column is-narrow is-hidden-mobile">
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book %}</a>
|
||||
{% include 'snippets/stars.html' with rating=book|rating:request.user %}
|
||||
{% include 'snippets/shelve_button/shelve_button.html' with book=book %}
|
||||
<div class="column is-narrow">
|
||||
<div class="columns is-mobile">
|
||||
<div class="column is-narrow">
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book %}</a>
|
||||
{% include 'snippets/stars.html' with rating=book|rating:request.user %}
|
||||
{% include 'snippets/shelve_button/shelve_button.html' with book=book %}
|
||||
</div>
|
||||
<div class="column is-hidden-tablet">
|
||||
<p>{{ book|book_description|to_markdown|default:""|safe|truncatewords_html:15 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
{% load humanize %}
|
||||
|
||||
{% block card-header %}
|
||||
<h3 class="card-header-title has-background-white-ter is-block">
|
||||
{% include 'snippets/status/status_header.html' with status=status %}
|
||||
</h3>
|
||||
<div class="card-header-title has-background-white-ter is-block">
|
||||
{% include 'snippets/status/status_header.html' with status=status %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block card-content %}{% endblock %}
|
||||
|
||||
{% block card-footer %}
|
||||
{% if moderation_mode and perms.bookwyrm.moderate_post %}
|
||||
<div class="card-footer-item">
|
||||
{% if moderation_mode and perms.bookwyrm.moderate_post %}
|
||||
|
||||
{# moderation options #}
|
||||
<form name="delete-{{status.id}}" action="/delete-status/{{ status.id }}" method="post">
|
||||
|
@ -22,54 +22,45 @@
|
|||
{% trans "Delete status" %}
|
||||
</button>
|
||||
</form>
|
||||
{% elif no_interact %}
|
||||
{# nothing here #}
|
||||
{% elif request.user.is_authenticated %}
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
{% trans "Reply" as button_text %}
|
||||
{% include 'snippets/toggle/toggle_button.html' with controls_text="show-comment" controls_uid=status.id text=button_text icon="comment" class="is-small toggle-button" focus="id_content_reply" %}
|
||||
</div>
|
||||
<div class="control">
|
||||
{% include 'snippets/boost_button.html' with status=status %}
|
||||
</div>
|
||||
<div class="control">
|
||||
{% include 'snippets/fav_button.html' with status=status %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<a href="/login">
|
||||
<span class="icon icon-comment" title="{% trans 'Reply' %}">
|
||||
<span class="is-sr-only">{% trans "Reply" %}</span>
|
||||
</span>
|
||||
|
||||
<span class="icon icon-boost" title="{% trans 'Boost status' %}">
|
||||
<span class="is-sr-only">{% trans "Boost status" %}</span>
|
||||
</span>
|
||||
|
||||
<span class="icon icon-heart" title="{% trans 'Like status' %}">
|
||||
<span class="is-sr-only">{% trans "Like status" %}</span>
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% elif no_interact %}
|
||||
{# nothing here #}
|
||||
{% elif request.user.is_authenticated %}
|
||||
<div class="card-footer-item">
|
||||
{% include 'snippets/privacy-icons.html' with item=status %}
|
||||
{% 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" %}
|
||||
</div>
|
||||
|
||||
<div class="card-footer-item">
|
||||
<a href="{{ status.remote_id }}">{{ status.published_date|timesince }}</a>
|
||||
{% include 'snippets/boost_button.html' with status=status %}
|
||||
</div>
|
||||
<div class="card-footer-item">
|
||||
{% include 'snippets/fav_button.html' with status=status %}
|
||||
</div>
|
||||
{% if not moderation_mode %}
|
||||
<div class="card-footer-item">
|
||||
{% include 'snippets/status/status_options.html' with class="is-small" right=True %}
|
||||
{% include 'snippets/status/status_options.html' with class="is-small is-light is-transparent" right=True %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<div class="card-footer-item">
|
||||
<a href="/login">
|
||||
<span class="icon icon-comment is-small" title="{% trans 'Reply' %}">
|
||||
<span class="is-sr-only">{% trans "Reply" %}</span>
|
||||
</span>
|
||||
|
||||
<span class="icon icon-boost is-small ml-4" title="{% trans 'Boost status' %}">
|
||||
<span class="is-sr-only">{% trans "Boost status" %}</span>
|
||||
</span>
|
||||
|
||||
<span class="icon icon-heart is-small ml-4" title="{% trans 'Like status' %}">
|
||||
<span class="is-sr-only">{% trans "Like status" %}</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block card-bonus %}
|
||||
{% if request.user.is_authenticated and not moderation_mode %}
|
||||
{% with status.id|uuid as uuid %}
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% with status_type=status.status_type %}
|
||||
<div
|
||||
class="block"
|
||||
|
||||
{% if status_type == 'Review' %}
|
||||
{% firstof "reviewBody" as body_prop %}
|
||||
{% firstof 'itemprop="reviewRating" itemscope itemtype="https://schema.org/Rating"' as rating_type %}
|
||||
{% endif %}
|
||||
|
||||
{% if status_type == 'Rating' %}
|
||||
itemprop="rating"
|
||||
itemtype="https://schema.org/Rating"
|
||||
{% endif %}
|
||||
>
|
||||
{% if status_type == 'Review' or status_type == 'Rating' %}
|
||||
<div>
|
||||
{% if status.name %}
|
||||
<h3
|
||||
class="title is-5 has-subtitle"
|
||||
dir="auto"
|
||||
itemprop="name"
|
||||
>
|
||||
{{ status.name|escape }}
|
||||
</h3>
|
||||
{% endif %}
|
||||
|
||||
<span
|
||||
class="is-sr-only"
|
||||
{{ rating_type }}
|
||||
>
|
||||
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
|
||||
|
||||
{% if status_type == 'Rating' %}
|
||||
{# @todo Is it possible to not hard-code the value? #}
|
||||
<meta itemprop="bestRating" content="5">
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
{% include 'snippets/stars.html' with rating=status.rating %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if status.content_warning %}
|
||||
<div>
|
||||
<p>{{ status.content_warning }}</p>
|
||||
|
||||
{% trans "Show more" as button_text %}
|
||||
|
||||
{% with text=button_text class="is-small" controls_text="show-status-cw" controls_uid=status.id %}
|
||||
{% include 'snippets/toggle/open_button.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div
|
||||
{% if status.content_warning %}
|
||||
id="show-status-cw-{{ status.id }}"
|
||||
class="is-hidden"
|
||||
{% endif %}
|
||||
>
|
||||
{% if status.content_warning %}
|
||||
{% trans "Show less" as button_text %}
|
||||
|
||||
{% with text=button_text class="is-small" controls_text="show-status-cw" controls_uid=status.id %}
|
||||
{% include 'snippets/toggle/close_button.html' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if status.quote %}
|
||||
<div class="quote block">
|
||||
<blockquote dir="auto" class="content mb-2">{{ status.quote | safe }}</blockquote>
|
||||
|
||||
<p> — {% include 'snippets/book_titleby.html' with book=status.book %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if status.content and status_type != 'GeneratedNote' and status_type != 'Announce' %}
|
||||
{% with full=status.content|safe no_trim=status.content_warning itemprop=body_prop %}
|
||||
{% include 'snippets/trimmed_text.html' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if status.attachments.exists %}
|
||||
<div class="block">
|
||||
<div class="columns">
|
||||
{% for attachment in status.attachments.all %}
|
||||
<div class="column is-narrow">
|
||||
<figure class="image is-128x128">
|
||||
<a
|
||||
href="/images/{{ attachment.image }}"
|
||||
target="_blank"
|
||||
aria-label="{% trans 'Open image in new window' %}"
|
||||
>
|
||||
<img
|
||||
src="/images/{{ attachment.image }}"
|
||||
|
||||
{% if attachment.caption %}
|
||||
alt="{{ attachment.caption }}"
|
||||
title="{{ attachment.caption }}"
|
||||
{% endif %}
|
||||
>
|
||||
</a>
|
||||
</figure>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not hide_book %}
|
||||
{% if status.book or status.mention_books.count %}
|
||||
<div
|
||||
{% if status_type != 'GeneratedNote' %}
|
||||
class="box has-background-white-bis"
|
||||
{% endif %}
|
||||
>
|
||||
{% if status.book %}
|
||||
{% with book=status.book %}
|
||||
{% include 'snippets/status/book_preview.html' %}
|
||||
{% endwith %}
|
||||
{% elif status.mention_books.count %}
|
||||
{% with book=status.mention_books.first %}
|
||||
{% include 'snippets/status/book_preview.html' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
|
@ -1,72 +1,108 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load i18n %}
|
||||
<span
|
||||
itemprop="author"
|
||||
itemscope
|
||||
itemtype="https://schema.org/Person"
|
||||
>
|
||||
<a
|
||||
href="{{ status.user.local_path }}"
|
||||
itemprop="url"
|
||||
>
|
||||
{% include 'snippets/avatar.html' with user=status.user ariaHide="true" %}
|
||||
{% load humanize %}
|
||||
|
||||
<span itemprop="name">{{ status.user.display_name }}</span>
|
||||
</a>
|
||||
</span>
|
||||
<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>
|
||||
|
||||
{% 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" %}
|
||||
{% elif status.reply_parent %}
|
||||
{% with parent_status=status|parent %}
|
||||
<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 %}
|
||||
|
||||
{% if parent_status.status_type == 'Review' %}
|
||||
{% blocktrans 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}}'s</a> <a href="{{ status_path }}">review</a>{% endblocktrans %}
|
||||
{% elif parent_status.status_type == 'Comment' %}
|
||||
{% blocktrans 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}}'s</a> <a href="{{ status_path }}">comment</a>{% endblocktrans %}
|
||||
{% elif parent_status.status_type == 'Quotation' %}
|
||||
{% blocktrans 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}}'s</a> <a href="{{ status_path }}">quote</a>{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans 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}}'s</a> <a href="{{ status_path }}">status</a>{% endblocktrans %}
|
||||
{% endif %}
|
||||
<a
|
||||
href="{{ status.user.local_path }}"
|
||||
itemprop="url"
|
||||
>
|
||||
<span itemprop="name">{{ status.user.display_name }}</span>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% 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" %}
|
||||
{% elif status.reply_parent %}
|
||||
{% with parent_status=status|parent %}
|
||||
|
||||
{% if status.book %}
|
||||
{% if status.status_type == 'GeneratedNote' or status.status_type == 'Rating' %}
|
||||
<a href="/book/{{ status.book.id }}">{{ status.book|title }}</a>{% if status.status_type == 'Rating' %}:
|
||||
<span
|
||||
itemprop="reviewRating"
|
||||
itemscope
|
||||
itemtype="https://schema.org/Rating"
|
||||
>
|
||||
<span class="is-hidden" {{ rating_type }}>
|
||||
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
|
||||
{% blocktrans 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}}'s</a> <a href="{{ status_path }}">status</a>{% endblocktrans %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{# @todo Is it possible to not hard-code the value? #}
|
||||
<meta itemprop="bestRating" content="5">
|
||||
</span>
|
||||
{% if status.book %}
|
||||
{% if status.status_type == 'GeneratedNote' or status.status_type == 'Rating' %}
|
||||
<a href="/book/{{ status.book.id }}">{{ status.book|title }}</a>{% if status.status_type == 'Rating' %}:
|
||||
<span
|
||||
itemprop="reviewRating"
|
||||
itemscope
|
||||
itemtype="https://schema.org/Rating"
|
||||
>
|
||||
<span class="is-hidden" {{ rating_type }}>
|
||||
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
|
||||
|
||||
{% include 'snippets/stars.html' with rating=status.rating %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include 'snippets/book_titleby.html' with book=status.book %}
|
||||
{% endif %}
|
||||
{% elif status.mention_books %}
|
||||
<a href="/book/{{ status.mention_books.first.id }}">{{ status.mention_books.first|title }}</a>
|
||||
{% endif %}
|
||||
{% if status.book %}
|
||||
{% if status.status_type == 'GeneratedNote' or status.status_type == 'Rating' %}
|
||||
<a href="/book/{{ status.book.id }}">{{ status.book|title }}</a>{% if status.status_type == 'Rating' %}:
|
||||
<span
|
||||
itemprop="reviewRating"
|
||||
itemscope
|
||||
itemtype="https://schema.org/Rating"
|
||||
>
|
||||
<span class="is-hidden" {{ rating_type }}>
|
||||
<meta itemprop="ratingValue" content="{{ status.rating|floatformat }}">
|
||||
|
||||
{% if status.progress %}
|
||||
<p class="help">
|
||||
({% if status.progress_mode == 'PG' %}{% include 'snippets/page_text.html' with page=status.progress total_pages=status.book.pages %}{% else %}{{ status.progress }}%{% endif %})
|
||||
</p>
|
||||
{% endif %}
|
||||
{# @todo Is it possible to not hard-code the value? #}
|
||||
<meta itemprop="bestRating" content="5">
|
||||
</span>
|
||||
|
||||
{% include 'snippets/stars.html' with rating=status.rating %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include 'snippets/book_titleby.html' with book=status.book %}
|
||||
{% endif %}
|
||||
{% elif status.mention_books %}
|
||||
<a href="/book/{{ status.mention_books.first.id }}">
|
||||
{{ status.mention_books.first.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% include 'snippets/stars.html' with rating=status.rating %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include 'snippets/book_titleby.html' with book=status.book %}
|
||||
{% endif %}
|
||||
{% elif status.mention_books %}
|
||||
<a href="/book/{{ status.mention_books.first.id }}">{{ status.mention_books.first|title }}</a>
|
||||
{% endif %}
|
||||
|
||||
</h3>
|
||||
<p class="is-size-7 is-flex is-align-items-center">
|
||||
<a href="{{ status.remote_id }}">{{ status.published_date|timesince }}</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>
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
{% load bookwyrm_tags %}
|
||||
|
||||
{% block dropdown-trigger %}
|
||||
<span class="icon icon-dots-three">
|
||||
<span class="is-sr-only">{% trans "More options" %}</span>
|
||||
</span>
|
||||
<span class="icon icon-dots-three m-0-mobile"></span>
|
||||
<span class="is-sr-only-mobile">{% trans "More options" %}</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block dropdown-list %}
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
>
|
||||
|
||||
{% if icon %}
|
||||
<span class="icon icon-{{ icon }}" title="{{ text }}">
|
||||
<span class="icon icon-{{ icon }} m-0-mobile" title="{{ text }}">
|
||||
<span class="is-sr-only">{{ text }}</span>
|
||||
</span>
|
||||
{% elif icon_with_text %}
|
||||
<span class="icon icon-{{ icon_with_text }} m-0-mobile" title="{{ text }}"></span>
|
||||
<span class="is-sr-only-mobile">{{ text }}</span>
|
||||
{% else %}
|
||||
<span>{{ text }}</span>
|
||||
{% endif %}
|
||||
|
|
|
@ -68,63 +68,66 @@
|
|||
<div class="block">
|
||||
<div>
|
||||
{% if books|length > 0 %}
|
||||
<div class="scroll-x">
|
||||
<table class="table is-striped is-fullwidth">
|
||||
|
||||
<tr class="book-preview">
|
||||
<th>{% trans "Cover" %}</th>
|
||||
<th>{% trans "Title" %}</th>
|
||||
<th>{% trans "Author" %}</th>
|
||||
<th>{% trans "Shelved" %}</th>
|
||||
<th>{% trans "Started" %}</th>
|
||||
<th>{% trans "Finished" %}</th>
|
||||
{% if ratings %}<th>{% trans "Rating" %}</th>{% endif %}
|
||||
{% if shelf.user == request.user %}
|
||||
<th aria-hidden="true"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for book in books %}
|
||||
<tr class="book-preview">
|
||||
<td>
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book cover_class='is-h-small' %}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ book.local_path }}">{{ book.title }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{% include 'snippets/authors.html' %}
|
||||
</td>
|
||||
<td>
|
||||
{{ book.created_date | naturalday }}
|
||||
</td>
|
||||
{% latest_read_through book user as read_through %}
|
||||
<td>
|
||||
{{ read_through.start_date | naturalday |default_if_none:""}}
|
||||
</td>
|
||||
<td>
|
||||
{{ read_through.finish_date | naturalday |default_if_none:""}}
|
||||
</td>
|
||||
{% if ratings %}
|
||||
<td>
|
||||
{% include 'snippets/stars.html' with rating=ratings|dict_key:book.id %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if shelf.user == request.user %}
|
||||
<td>
|
||||
{% with right=True %}
|
||||
{% if not shelf.id %}
|
||||
{% active_shelf book as current %}
|
||||
{% include 'snippets/shelf_selector.html' with current=current.shelf class="is-small" %}
|
||||
{% else %}
|
||||
{% include 'snippets/shelf_selector.html' with current=shelf class="is-small" %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<table class="table is-striped is-fullwidth is-mobile">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Cover" %}</th>
|
||||
<th>{% trans "Title" %}</th>
|
||||
<th>{% trans "Author" %}</th>
|
||||
<th>{% trans "Shelved" %}</th>
|
||||
<th>{% trans "Started" %}</th>
|
||||
<th>{% trans "Finished" %}</th>
|
||||
{% if ratings %}<th>{% trans "Rating" %}</th>{% endif %}
|
||||
{% if shelf.user == request.user %}
|
||||
<th aria-hidden="true"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for book in books %}
|
||||
{% spaceless %}
|
||||
<tr class="book-preview">
|
||||
<td class="book-preview-top-row">
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book size="small" %}</a>
|
||||
</td>
|
||||
<td data-title="{% trans "Title" %}">
|
||||
<a href="{{ book.local_path }}">{{ book.title }}</a>
|
||||
</td>
|
||||
<td data-title="{% trans "Author" %}">
|
||||
{% include 'snippets/authors.html' %}
|
||||
</td>
|
||||
<td data-title="{% trans "Shelved" %}">
|
||||
{{ book.created_date | naturalday }}
|
||||
</td>
|
||||
{% latest_read_through book user as read_through %}
|
||||
<td data-title="{% trans "Started" %}">
|
||||
{{ read_through.start_date | naturalday |default_if_none:""}}
|
||||
</td>
|
||||
<td data-title="{% trans "Finished" %}">
|
||||
{{ read_through.finish_date | naturalday |default_if_none:""}}
|
||||
</td>
|
||||
{% if ratings %}
|
||||
<td data-title="{% trans "Rating" %}">
|
||||
{% include 'snippets/stars.html' with rating=ratings|dict_key:book.id %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if shelf.user == request.user %}
|
||||
<td class="book-preview-top-row has-text-right">
|
||||
{% with right=True %}
|
||||
{% if not shelf.id %}
|
||||
{% active_shelf book as current %}
|
||||
{% include 'snippets/shelf_selector.html' with current=current.shelf class="is-small" %}
|
||||
{% else %}
|
||||
{% include 'snippets/shelf_selector.html' with current=shelf class="is-small" %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endspaceless %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "This shelf is empty." %}</p>
|
||||
{% if shelf.id and shelf.editable %}
|
||||
|
|
|
@ -260,7 +260,12 @@ urlpatterns = [
|
|||
re_path(r"^boost/(?P<status_id>\d+)/?$", views.Boost.as_view()),
|
||||
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
|
||||
# books
|
||||
re_path(r"%s(.json)?/?$" % book_path, views.Book.as_view()),
|
||||
re_path(r"%s(.json)?/?$" % book_path, views.Book.as_view(), name="book"),
|
||||
re_path(
|
||||
r"%s/(?P<user_statuses>review|comment|quote)/?$" % book_path,
|
||||
views.Book.as_view(),
|
||||
name="book-user-statuses",
|
||||
),
|
||||
re_path(r"%s/edit/?$" % book_path, views.EditBook.as_view()),
|
||||
re_path(r"%s/confirm/?$" % book_path, views.ConfirmEditBook.as_view()),
|
||||
re_path(r"^create-book/?$", views.EditBook.as_view()),
|
||||
|
|
|
@ -28,7 +28,7 @@ from .helpers import is_api_request, get_edition, privacy_filter
|
|||
class Book(View):
|
||||
""" a book! this is the stuff """
|
||||
|
||||
def get(self, request, book_id):
|
||||
def get(self, request, book_id, user_statuses=False):
|
||||
""" info about a book """
|
||||
try:
|
||||
book = models.Book.objects.select_subclasses().get(id=book_id)
|
||||
|
@ -40,22 +40,39 @@ class Book(View):
|
|||
|
||||
if isinstance(book, models.Work):
|
||||
book = book.get_default_edition()
|
||||
if not book:
|
||||
if not book or not book.parent_work:
|
||||
return HttpResponseNotFound()
|
||||
|
||||
work = book.parent_work
|
||||
if not work:
|
||||
return HttpResponseNotFound()
|
||||
|
||||
# all reviews for the book
|
||||
reviews = models.Review.objects.filter(book__in=work.editions.all())
|
||||
reviews = privacy_filter(request.user, reviews)
|
||||
reviews = privacy_filter(
|
||||
request.user, models.Review.objects.filter(book__in=work.editions.all())
|
||||
)
|
||||
|
||||
# the reviews to show
|
||||
paginated = Paginator(
|
||||
reviews.exclude(Q(content__isnull=True) | Q(content="")), PAGE_LENGTH
|
||||
)
|
||||
reviews_page = paginated.get_page(request.GET.get("page"))
|
||||
if user_statuses and request.user.is_authenticated:
|
||||
if user_statuses == "review":
|
||||
queryset = book.review_set
|
||||
elif user_statuses == "comment":
|
||||
queryset = book.comment_set
|
||||
else:
|
||||
queryset = book.quotation_set
|
||||
queryset = queryset.filter(user=request.user)
|
||||
else:
|
||||
queryset = reviews.exclude(Q(content__isnull=True) | Q(content=""))
|
||||
paginated = Paginator(queryset, PAGE_LENGTH)
|
||||
|
||||
data = {
|
||||
"book": book,
|
||||
"statuses": paginated.get_page(request.GET.get("page")),
|
||||
"review_count": reviews.count(),
|
||||
"ratings": reviews.filter(Q(content__isnull=True) | Q(content="")),
|
||||
"rating": reviews.aggregate(Avg("rating"))["rating__avg"],
|
||||
"lists": privacy_filter(
|
||||
request.user, book.list_set.filter(listitem__approved=True)
|
||||
),
|
||||
}
|
||||
|
||||
if request.user.is_authenticated:
|
||||
readthroughs = models.ReadThrough.objects.filter(
|
||||
|
@ -67,29 +84,24 @@ class Book(View):
|
|||
readthrough.progress_updates = (
|
||||
readthrough.progressupdate_set.all().order_by("-updated_date")
|
||||
)
|
||||
data["readthroughs"] = readthroughs
|
||||
|
||||
user_shelves = models.ShelfBook.objects.filter(user=request.user, book=book)
|
||||
data["user_shelves"] = models.ShelfBook.objects.filter(
|
||||
user=request.user, book=book
|
||||
)
|
||||
|
||||
other_edition_shelves = models.ShelfBook.objects.filter(
|
||||
data["other_edition_shelves"] = models.ShelfBook.objects.filter(
|
||||
~Q(book=book),
|
||||
user=request.user,
|
||||
book__parent_work=book.parent_work,
|
||||
)
|
||||
|
||||
data = {
|
||||
"book": book,
|
||||
"reviews": reviews_page,
|
||||
"review_count": reviews.count(),
|
||||
"ratings": reviews.filter(Q(content__isnull=True) | Q(content="")),
|
||||
"rating": reviews.aggregate(Avg("rating"))["rating__avg"],
|
||||
"lists": privacy_filter(
|
||||
request.user, book.list_set.filter(listitem__approved=True)
|
||||
),
|
||||
"user_shelves": user_shelves,
|
||||
"other_edition_shelves": other_edition_shelves,
|
||||
"readthroughs": readthroughs,
|
||||
"path": "/book/%s" % book_id,
|
||||
}
|
||||
data["user_statuses"] = {
|
||||
"review_count": book.review_set.filter(user=request.user).count(),
|
||||
"comment_count": book.comment_set.filter(user=request.user).count(),
|
||||
"quotation_count": book.quotation_set.filter(user=request.user).count(),
|
||||
}
|
||||
|
||||
return TemplateResponse(request, "book/book.html", data)
|
||||
|
||||
|
||||
|
|
1
fr-dev
1
fr-dev
|
@ -1 +0,0 @@
|
|||
bw-dev
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-04-22 15:55+0000\n"
|
||||
"POT-Creation-Date: 2021-04-25 04:01+0000\n"
|
||||
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -18,57 +18,57 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: bookwyrm/forms.py:232
|
||||
#: bookwyrm/forms.py:224
|
||||
msgid "A user with this email already exists."
|
||||
msgstr "Ya existe un usuario con ese correo electrónico."
|
||||
|
||||
#: bookwyrm/forms.py:246
|
||||
#: bookwyrm/forms.py:238
|
||||
msgid "One Day"
|
||||
msgstr "Un día"
|
||||
|
||||
#: bookwyrm/forms.py:247
|
||||
#: bookwyrm/forms.py:239
|
||||
msgid "One Week"
|
||||
msgstr "Una semana"
|
||||
|
||||
#: bookwyrm/forms.py:248
|
||||
#: bookwyrm/forms.py:240
|
||||
msgid "One Month"
|
||||
msgstr "Un mes"
|
||||
|
||||
#: bookwyrm/forms.py:249
|
||||
#: bookwyrm/forms.py:241
|
||||
msgid "Does Not Expire"
|
||||
msgstr "Nunca se vence"
|
||||
|
||||
#: bookwyrm/forms.py:254
|
||||
#: bookwyrm/forms.py:246
|
||||
#, python-format
|
||||
msgid "%(count)d uses"
|
||||
msgstr "%(count)d usos"
|
||||
|
||||
#: bookwyrm/forms.py:257
|
||||
#: bookwyrm/forms.py:249
|
||||
msgid "Unlimited"
|
||||
msgstr "Sin límite"
|
||||
|
||||
#: bookwyrm/forms.py:301
|
||||
#: bookwyrm/forms.py:293
|
||||
msgid "List Order"
|
||||
msgstr "Orden de la lista"
|
||||
|
||||
#: bookwyrm/forms.py:302
|
||||
#: bookwyrm/forms.py:294
|
||||
msgid "Book Title"
|
||||
msgstr "Título"
|
||||
|
||||
#: bookwyrm/forms.py:303 bookwyrm/templates/snippets/create_status_form.html:31
|
||||
#: bookwyrm/forms.py:295 bookwyrm/templates/snippets/create_status_form.html:31
|
||||
#: bookwyrm/templates/user/shelf.html:81
|
||||
msgid "Rating"
|
||||
msgstr "Calificación"
|
||||
|
||||
#: bookwyrm/forms.py:305 bookwyrm/templates/lists/list.html:72
|
||||
#: bookwyrm/forms.py:297 bookwyrm/templates/lists/list.html:72
|
||||
msgid "Sort By"
|
||||
msgstr "Ordenar por"
|
||||
|
||||
#: bookwyrm/forms.py:309
|
||||
#: bookwyrm/forms.py:301
|
||||
msgid "Ascending"
|
||||
msgstr "Ascendente"
|
||||
|
||||
#: bookwyrm/forms.py:310
|
||||
#: bookwyrm/forms.py:302
|
||||
msgid "Descending"
|
||||
msgstr "Descendente"
|
||||
|
||||
|
@ -2047,7 +2047,7 @@ msgstr "Texto de registración cerrada:"
|
|||
msgid "No cover"
|
||||
msgstr "Sin portada"
|
||||
|
||||
#: bookwyrm/templates/snippets/book_titleby.html:3
|
||||
#: bookwyrm/templates/snippets/book_titleby.html:4
|
||||
#, python-format
|
||||
msgid "<a href=\"%(path)s\">%(title)s</a> by "
|
||||
msgstr "<a href=\"%(path)s\">%(title)s</a> por "
|
||||
|
@ -2527,19 +2527,6 @@ msgstr "En orden ascendente"
|
|||
msgid "Sorted descending"
|
||||
msgstr "En orden descendente"
|
||||
|
||||
#: bookwyrm/templates/snippets/tag.html:14
|
||||
msgid "Remove tag"
|
||||
msgstr "Eliminar etiqueta"
|
||||
|
||||
#: bookwyrm/templates/snippets/tag.html:18
|
||||
msgid "Add tag"
|
||||
msgstr "Agregar etiqueta"
|
||||
|
||||
#: bookwyrm/templates/tag.html:9
|
||||
#, python-format
|
||||
msgid "Books tagged \"%(tag.name)s\""
|
||||
msgstr "Libros etiquetados con \"%(tag.name)s\""
|
||||
|
||||
#: bookwyrm/templates/user/books_header.html:5
|
||||
#, python-format
|
||||
msgid "%(username)s's books"
|
||||
|
@ -2754,6 +2741,15 @@ msgstr "No se pudo encontrar un usuario con esa dirección de correo electrónic
|
|||
msgid "A password reset link sent to %s"
|
||||
msgstr "Un enlace para reestablecer tu contraseña se enviará a %s"
|
||||
|
||||
#~ msgid "Remove tag"
|
||||
#~ msgstr "Eliminar etiqueta"
|
||||
|
||||
#~ msgid "Add tag"
|
||||
#~ msgstr "Agregar etiqueta"
|
||||
|
||||
#~ msgid "Books tagged \"%(tag.name)s\""
|
||||
#~ msgstr "Libros etiquetados con \"%(tag.name)s\""
|
||||
|
||||
#~ msgid "Deactivate user"
|
||||
#~ msgstr "Desactivar usuario"
|
||||
|
||||
|
|
Loading…
Reference in a new issue