diff --git a/fedireads/connectors/openlibrary.py b/fedireads/connectors/openlibrary.py index dd68920d2..b58585bc1 100644 --- a/fedireads/connectors/openlibrary.py +++ b/fedireads/connectors/openlibrary.py @@ -203,7 +203,7 @@ def set_default_edition(work): options = [e for e in options if e.cover] or options options = sorted( options, - key=lambda e: e.published_date.year if e.published_date else None + key=lambda e: e.published_date.year if e.published_date else 3000 ) if len(options): options[0].default = True diff --git a/fedireads/routine_book_tasks.py b/fedireads/routine_book_tasks.py index b35ccf4d5..6c96ef3f5 100644 --- a/fedireads/routine_book_tasks.py +++ b/fedireads/routine_book_tasks.py @@ -7,7 +7,7 @@ from fedireads import models def sync_book_data(): ''' update books with any changes to their canonical source ''' expiry = timezone.now() - timedelta(days=1) - books = models.Book.objects.filter( + books = models.Edition.objects.filter( sync=True, last_sync_date__lte=expiry ).all() diff --git a/fedireads/static/format.css b/fedireads/static/format.css index 2215f80ed..0c1395c20 100644 --- a/fedireads/static/format.css +++ b/fedireads/static/format.css @@ -1,57 +1,55 @@ /* some colors that are okay: #247BA0 #70C1B2 #B2DBBF #F3FFBD #FF1654 */ + +/* general override */ * { margin: 0; padding: 0; line-height: 1.3em; font-family: sans-serif; } - html { background-color: #FFF; color: black; } -body { - padding-top: 90px; -} - a { color: #247BA0; } -input, button { - padding: 0.2em 0.5em; -} -button { - cursor: pointer; - width: max-content; -} - -h1, h2, h3, h4 { - font-weight: normal; -} - h1 { + font-weight: normal; font-size: 1.5rem; } - h2 { + font-weight: normal; font-size: 1rem; padding: 0.5rem 0.2rem; margin-bottom: 1rem; border-bottom: 3px solid #B2DBBF; } +h2 .edit-link { + text-decoration: none; + font-size: 0.9em; + float: right; +} +h2 .edit-link .icon { + font-size: 1.2em; +} h3 { font-size: 1rem; - margin: 1rem 0 0.5rem 0; - border-bottom: 3px solid #70C1B2; font-weight: bold; + margin-bottom: 0.5em; } h3 small { font-weight: normal; } + +/* fixed display top bar */ +body { + padding-top: 90px; +} #top-bar { overflow: visible; padding: 0.5rem; @@ -65,18 +63,31 @@ h3 small { z-index: 2; } -#warning { - background-color: #FF1654; +/* --- header bar content */ +#branding { + flex-grow: 0; +} +#menu { + list-style: none; text-align: center; + margin-top: 1.5rem; + flex-grow: 2; + font-size: 0.9em; +} +#menu li { + display: inline-block; + padding: 0 0.5em; + text-transform: uppercase; +} +#menu a { + color: #555; + text-decoration: none; + font-size: 0.9em; } -#branding a { - text-decoration: none; -} #actions { margin-top: 1em; } - #actions > * { display: inline-block; } @@ -106,7 +117,6 @@ h3 small { height: 1rem; width: 1rem; } - .notification { margin-bottom: 1em; padding: 1em 0; @@ -116,11 +126,6 @@ h3 small { background-color: #DDD; } - -button .icon { - font-size: 1.1rem; - vertical-align: sub; -} #search button { border: none; background: none; @@ -131,29 +136,6 @@ button .icon { max-width: 55rem; padding-right: 1em; } -header { - display: flex; - flex-direction: row; -} - -ul.menu { - list-style: none; - text-align: center; - margin-top: 1.5rem; - flex-grow: 1; - font-size: 0.9em; -} -ul.menu li { - display: inline-block; - background-color: white; - padding: 0 0.5em; - text-transform: uppercase; -} -ul.menu a { - color: #555; - text-decoration: none; - font-size: 0.9em; -} .pulldown-container { position: relative; @@ -175,15 +157,24 @@ ul.menu a { margin-bottom: 0.5em; } +/* content area */ +.content-container { + margin: 1rem; +} +.content-container > * { + padding-left: 1em; + padding-right: 1em; +} + #feed { display: flex; flex-direction: column; padding-top: 70px; position: relative; - top: -30px; z-index: 0; } +/* row component */ .row { display: flex; flex-direction: row; @@ -204,6 +195,16 @@ ul.menu a { flex-wrap: wrap; } +.column { + display: flex; + flex-direction: column; +} +.column > * { + margin-bottom: 1em; +} + + +/* discover books page grid of covers */ .book-grid .book-cover { height: 11em; width: auto; @@ -212,6 +213,17 @@ ul.menu a { margin-bottom: 2em; } +/* special case forms */ +.review-form label { + display: block; +} +.review-form textarea { + width: 30rem; + height: 10rem; +} + + + .follow-requests .row { margin-bottom: 0.5em; } @@ -219,6 +231,7 @@ ul.menu a { width: 20em; } + .login form { margin-top: 1em; } @@ -247,14 +260,14 @@ ul.menu a { .book-form .row label { width: max-content; } -form input { - flex-grow: 1; + +/* general form stuff */ +input, button { + padding: 0.2em 0.5em; } -form div { - margin-bottom: 1em; -} -textarea { - padding: 0.5em; +button, input[type="submit"] { + cursor: pointer; + width: max-content; } .content-container button { border: none; @@ -273,6 +286,36 @@ button.warning { background-color: #FF1654; } +form input { + flex-grow: 1; +} +form div { + margin-bottom: 1em; +} +textarea { + padding: 0.5em; +} + + +/* icons */ +a .icon { + color: black; + text-decoration: none; +} +button .icon { + font-size: 1.1rem; + vertical-align: sub; +} +.hidden-text { + height: 0; + width: 0; + position: absolute; + overflow: hidden; +} + + + +/* re-usable tab styles */ .tabs { display: flex; flex-direction: row; @@ -299,6 +342,7 @@ button.warning { color: black; } + .user-pic { width: 2em; height: 2em; @@ -312,51 +356,54 @@ button.warning { height: 5em; } -h2 .edit-link { - text-decoration: none; - font-size: 0.9em; - float: right; -} -h2 .edit-link .icon { - font-size: 1.2em; -} + .user-profile .row > * { flex-grow: 0; } .user-profile .row > *:last-child { flex-grow: 1; + margin-left: 2em; } -.review-form label { - display: block; -} - -.time-ago { - float: right; - display: block; - text-align: right; -} - +/* general book display */ .book-preview { overflow: hidden; z-index: 1; } - -.book-preview img { - float: left; - margin-right: 1em; -} - .book-preview.grid { float: left; } -.content-container { - margin: 1rem; +.cover-container { + flex-grow: 0; } -.content-container > * { - padding-left: 1em; - padding-right: 1em; +.cover-container button { + display: block; + margin: 0 auto; +} +.book-cover { + width: 180px; + height: auto; +} +.book-cover.small { + width: 50px; + height: auto; +} + +.no-cover { + position: relative; +} +.no-cover div { + position: absolute; + padding: 1em; + color: white; + top: 0; + left: 0; + text-align: center; +} +.no-cover .title { + text-transform: uppercase; + margin-bottom: 1em; } .all-shelves { @@ -379,51 +426,32 @@ h2 .edit-link .icon { padding-left: 1em; } -.user-shelves .covers-shelf { - flex-wrap: wrap; -} -.user-shelves > div { - margin: 1em 0; - padding: 0; -} -.user-shelves > div > * { - padding-left: 1em; -} -.user-shelves .covers-shelf .book-cover { - height: 9em; -} - .covers-shelf { display: flex; flex-direction: row; } -.covers-shelf .book-preview { +.covers-shelf .cover-container { margin-right: 1em; font-size: 0.9em; overflow: unset; width: min-content; position: relative; } -.covers-shelf .book-preview button { - display: block; - margin: 0 auto; - border: none; -} -.covers-shelf .book-preview:last-child { +.covers-shelf .cover-container:last-child { margin-right: 0; } -.covers-shelf .book-preview:hover { +.covers-shelf img:hover { cursor: pointer; -} -.covers-shelf .book-preview:hover img { box-shadow: #F3FFBD 0em 0em 1em 1em; } .covers-shelf .book-cover { - float: none; height: 11rem; width: auto; margin: 0; } +.covers-shelf button { + border: none; +} .close { float: right; @@ -437,29 +465,6 @@ h2 .edit-link .icon { .compose-suggestion.visible { display: block; } - -.no-cover { - position: relative; -} -.no-cover div { - position: absolute; - padding: 1em; - color: white; - top: 0; - left: 0; - text-align: center; -} -.no-cover .title { - text-transform: uppercase; - margin-bottom: 1em; -} -.book-cover { - width: 180px; -} -.book-cover.small { - width: 50px; - height: auto; -} .compose-suggestion .book-preview { background-color: #EEE; padding: 1em; @@ -476,14 +481,8 @@ h2 .edit-link .icon { display: inline; } -.review-form textarea { - width: 30rem; - height: 10rem; -} - blockquote { white-space: pre-line; - margin-left: 2em; } blockquote .icon-quote-open { float: left; @@ -557,8 +556,11 @@ th, td { color: #FF1654; } -.comment-thread .reply h2 { - background: none; +/* status css */ +.time-ago { + float: right; + display: block; + text-align: right; } .post { background-color: #EFEFEF; @@ -585,7 +587,10 @@ th, td { display: none; } - +/* status page with replies */ +.comment-thread .reply h2 { + background: none; +} .comment-thread .post { margin-left: 4em; border-left: 2px solid #247BA0; @@ -604,25 +609,16 @@ th, td { margin-left: 3em; } -a .icon { - color: black; - text-decoration: none; -} - -.hidden-text { - height: 0; - width: 0; - position: absolute; - overflow: hidden; -} - -.book-row .book-cover { - float: none; -} - +/* pagination */ .pagination a { text-decoration: none; } .pagination .next { text-align: right; } + +/* special one-off "delete all data" banner */ +#warning { + background-color: #FF1654; + text-align: center; +} diff --git a/fedireads/templates/author.html b/fedireads/templates/author.html index a240ada7c..cc06cccf3 100644 --- a/fedireads/templates/author.html +++ b/fedireads/templates/author.html @@ -13,11 +13,16 @@

Books by {{ author.name }}

- {% for book in books %} -
- {% include 'snippets/book.html' with book=book size=large description=True %} +
+ {% for book in books %} +
+ + {% include 'snippets/book_cover.html' with book=book %} + + {% include 'snippets/shelve_button.html' with book=book %} +
+ {% endfor %}
- {% endfor %}
{% endblock %} diff --git a/fedireads/templates/book.html b/fedireads/templates/book.html index 21cfbbe70..137d996b3 100644 --- a/fedireads/templates/book.html +++ b/fedireads/templates/book.html @@ -1,9 +1,9 @@ {% extends 'layout.html' %} {% load fr_display %} {% block content %} -
-

{{ book.title }} by - {% include 'snippets/authors.html' with book=book %} +
+

+ {% include 'snippets/book_titleby.html' with book=book %} {% if request.user.is_authenticated %} edit @@ -13,27 +13,14 @@ {% endif %}

-
-
+
+ +
{% include 'snippets/book_cover.html' with book=book size=large %} -

{{ active_tab }} rating: {{ rating | stars }}

- {% if book.parent_work.description %} -
{{ book.parent_work.description | description }}
- {% endif %} -
-
- {% for tag in tags %} - {% include 'snippets/tag.html' with tag=tag user=request.user user_tags=user_tag_names %} - {% endfor %} -
-
-

{{ book.parent_work.edition_set.count }} other editions

{% include 'snippets/shelve_button.html' %} -
-
{% if request.user.is_authenticated and not book.cover %}
{% csrf_token %} @@ -41,21 +28,48 @@
{% endif %} + +
+ {% for field in info_fields %} + {% if field.value %} +
{{ field.name }}:
+
{{ field.value }}
+ {% endif %} + {% endfor %} +
+ +
+

{{ active_tab }} rating: {{ rating | stars }}

+ + {% include 'snippets/book_description.html' %} + + {% if book.parent_work.edition_set.count > 1 %} +

{{ book.parent_work.edition_set.count }} editions

+ {% endif %} + +
+ {% for tag in tags %} + {% include 'snippets/tag.html' with tag=tag user=request.user user_tags=user_tag_names %} + {% endfor %} +
+ +
+ {% if request.user.is_authenticated %} +

Leave a review

+
+ {% csrf_token %} + + {{ review_form.as_p }} + +
+ {% endif %} +
-{% if request.user.is_authenticated %} -
-

Leave a review

-
- {% csrf_token %} - - {{ review_form.as_p }} - -
-
+{% if request.user.is_authenticated %}
{% include 'snippets/tabs.html' with tabs=feed_tabs active_tab=active_tab path=path %}
diff --git a/fedireads/templates/layout.html b/fedireads/templates/layout.html index 22dfddbd0..4dcf1ac0a 100644 --- a/fedireads/templates/layout.html +++ b/fedireads/templates/layout.html @@ -22,10 +22,14 @@
-
-
+
+
+ + + +
-

-
+
{% for book in shelf.books %} -
- {% include 'snippets/book_cover.html' with book=book %} - {% include 'snippets/shelve_button.html' with book=book %} +
+ + {% include 'snippets/shelve_button.html' with book=book %}
{% endfor %}
diff --git a/fedireads/templates/snippets/status.html b/fedireads/templates/snippets/status.html index 2ddcbe29c..2566bac58 100644 --- a/fedireads/templates/snippets/status.html +++ b/fedireads/templates/snippets/status.html @@ -11,7 +11,9 @@ {% endif %} - {% include 'snippets/status_content.html' with status=status %} +
+ {% include 'snippets/status_content.html' with status=status %} +
{% if status.status_type == 'Boost' %} diff --git a/fedireads/templates/snippets/status_content.html b/fedireads/templates/snippets/status_content.html index 7029ce9db..4d4a1c613 100644 --- a/fedireads/templates/snippets/status_content.html +++ b/fedireads/templates/snippets/status_content.html @@ -1,36 +1,52 @@ {% load fr_display %} {% if not hide_book and status.mention_books.count %} -
-{% for book in status.mention_books.all|slice:"0:3" %} -
- {% if status.status_type == 'Review' %} - {% include 'snippets/book.html' with book=book %} - {% else %} - {% include 'snippets/book.html' with book=book description=True %} - {% endif %} -
-{% endfor %} -
+
+ {% for book in status.mention_books.all|slice:"0:4" %} +
+
+ {% include 'snippets/book_cover.html' with book=book %} + {% if status.mention_books.count > 1 %} +

{% include 'snippets/book_titleby.html' with book=book %}

+ {% endif %} + {% include 'snippets/shelve_button.html' with book=book %} +
+ {% if status.mention_books.count == 1 %} +
+

{% include 'snippets/book_titleby.html' with book=book %}

+ {% include 'snippets/book_description.html' with book=book %} +
+ {% endif %} +
+ {% endfor %} +
{% endif %} -{% if not hide_book and status.book%} -
- {% if status.status_type == 'Review' %} - {% include 'snippets/book.html' with book=status.book %} - {% else %} - {% include 'snippets/book.html' with book=status.book description=True %} +
+ {% if not hide_book and status.book %} +
+ {% include 'snippets/book_cover.html' with book=status.book %} + {% include 'snippets/shelve_button.html' with book=status.book %} +
{% endif %} -
-{% endif %} -{% if status.status_type == 'Review' %}

{{ status.name }} - {{ status.rating | stars }} stars, by {% include 'snippets/username.html' with user=status.user %} -

{% endif %} -{% if status.status_type != 'Update' and status.status_type != 'Boost' %} -
{{ status.content | safe }}
-{% endif %} -{% if status.status_type == 'Boost' %} - {% include 'snippets/status_content.html' with status=status|boosted_status %} -{% endif %} -{% if not max_depth and status.reply_parent or status|replies %}

Thread{% endif %} + +

+ {% if status.status_type == 'Review' %} +

+ {{ status.name }}
+ {{ status.rating | stars }} +

+ {% endif %} + + {% if status.status_type != 'Update' and status.status_type != 'Boost' %} +
{{ status.content | safe }}
+ {% endif %} + + {% if status.status_type == 'Boost' %} + {% include 'snippets/status_content.html' with status=status|boosted_status %} + {% endif %} + + {% if not max_depth and status.reply_parent or status|replies %}

Thread{% endif %} +

+
diff --git a/fedireads/views.py b/fedireads/views.py index 2b406913b..a62b8027f 100644 --- a/fedireads/views.py +++ b/fedireads/views.py @@ -415,6 +415,14 @@ def book_page(request, book_identifier, tab='friends'): 'active_tab': tab, 'path': '/book/%s' % book_identifier, 'cover_form': forms.CoverForm(instance=book), + 'info_fields': [ + {'name': 'ISBN', 'value': book.isbn}, + {'name': 'OCLC number', 'value': book.oclc_number}, + {'name': 'OpenLibrary ID', 'value': book.openlibrary_key}, + {'name': 'Goodreads ID', 'value': book.goodreads_key}, + {'name': 'Format', 'value': book.physical_format}, + {'name': 'Pages', 'value': book.pages}, + ], } return TemplateResponse(request, 'book.html', data)