CSS reorg and cleans up ui

Fixes #93
This commit is contained in:
Mouse Reeve 2020-04-01 19:38:07 -07:00
parent cfff75764b
commit 976e7ddf79
13 changed files with 302 additions and 255 deletions

View file

@ -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

View file

@ -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()

View file

@ -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;
}

View file

@ -13,11 +13,16 @@
<div class="content-container">
<h2>Books by {{ author.name }}</h2>
<div class="book-grid row shrink wrap">
{% for book in books %}
<div class="book-preview">
{% include 'snippets/book.html' with book=book size=large description=True %}
<a href="{{ book.absolute_id }}">
{% include 'snippets/book_cover.html' with book=book %}
</a>
{% include 'snippets/shelve_button.html' with book=book %}
</div>
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -1,9 +1,9 @@
{% extends 'layout.html' %}
{% load fr_display %}
{% block content %}
<div class="content-container user-profile">
<h2><q>{{ book.title }}</q> by
{% include 'snippets/authors.html' with book=book %}
<div class="content-container">
<h2>
{% include 'snippets/book_titleby.html' with book=book %}
{% if request.user.is_authenticated %}
<a href="{{ book.fedireads_key }}/edit" class="edit-link">edit
@ -13,27 +13,14 @@
</a>
{% endif %}
</h2>
<div>
<div class="book-preview">
<div class="row">
<div class="cover-container">
{% include 'snippets/book_cover.html' with book=book size=large %}
<p>{{ active_tab }} rating: {{ rating | stars }}</p>
{% if book.parent_work.description %}
<blockquote>{{ book.parent_work.description | description }}</blockquote>
{% endif %}
<div>
<div id="tag-cloud">
{% for tag in tags %}
{% include 'snippets/tag.html' with tag=tag user=request.user user_tags=user_tag_names %}
{% endfor %}
</div>
</div>
<p><a href="/editions/{{ book.parent_work.id }}">{{ book.parent_work.edition_set.count }} other editions</a></p>
{% include 'snippets/shelve_button.html' %}
</div>
<div>
{% if request.user.is_authenticated and not book.cover %}
<form name="add-cover" method="POST" action="/upload_cover/{{book.id}}" enctype="multipart/form-data">
{% csrf_token %}
@ -41,21 +28,48 @@
<button type="submit">Add cover</button>
</form>
{% endif %}
</div>
</div>
</div>
{% if request.user.is_authenticated %}
<div class="content-container">
<h2>Leave a review</h2>
<dl>
{% for field in info_fields %}
{% if field.value %}
<dt>{{ field.name }}:</dt>
<dd>{{ field.value }}</dd>
{% endif %}
{% endfor %}
</dl>
</div>
<div class="column">
<h3>{{ active_tab }} rating: {{ rating | stars }}</h3>
{% include 'snippets/book_description.html' %}
{% if book.parent_work.edition_set.count > 1 %}
<p><a href="/editions/{{ book.parent_work.id }}">{{ book.parent_work.edition_set.count }} editions</a></p>
{% endif %}
<div id="tag-cloud">
{% for tag in tags %}
{% include 'snippets/tag.html' with tag=tag user=request.user user_tags=user_tag_names %}
{% endfor %}
</div>
<div>
{% if request.user.is_authenticated %}
<h3>Leave a review</h3>
<form class="review-form" name="review" action="/review/" method="post">
{% csrf_token %}
<input type="hidden" name="book" value="{{ book.fedireads_key }}"></input>
{{ review_form.as_p }}
<button type="submit">Post review</button>
</form>
{% endif %}
</div>
</div>
</div>
{% if request.user.is_authenticated %}
<div class="content-container tabs">
{% include 'snippets/tabs.html' with tabs=feed_tabs active_tab=active_tab path=path %}
</div>

View file

@ -22,10 +22,14 @@
<body>
<div id="top-bar">
<header>
<div id="branding"><a href="/"><img id="logo" src="/static/images/logo-small.png" alt="BookWyrm"></img></a></div>
<header class="row">
<div id="branding">
<a href="/">
<img id="logo" src="/static/images/logo-small.png" alt="BookWyrm"></img>
</a>
</div>
<ul class="menu">
<ul id="menu">
{% if request.user.is_authenticated %}
<li><a href="/user/{{request.user.localname}}/shelves">Your shelves</a></li>
{% endif %}

View file

@ -1,18 +0,0 @@
{% load fr_display %}
{% include 'snippets/book_cover.html' with book=book %}
<p class="title">
<a href="/book/{{ book.fedireads_key }}">{{ book.title }}</a>
</p>
<p>
by {% include 'snippets/authors.html' with book=book %}
</p>
{% if rating %}
{{ rating | stars }} {{ rating }}
{% endif %}
{% if description %}
<blockquote>{{ book.description | description }}</blockquote>
{% endif %}
{% include 'snippets/shelve_button.html' with book=book pulldown=shelf_pulldown %}

View file

@ -0,0 +1,7 @@
{% load fr_display %}
{% if book.description %}
<blockquote>{{ book.description | description }}</blockquote>
{% elif book.parent_work.description %}
<blockquote>{{ book.parent_work.description | description }}</blockquote>
{% endif %}

View file

@ -0,0 +1,9 @@
<span class="title">
<a href="/book/{{ book.fedireads_key }}">{{ book.title }}</a>
</span>
{% if book.authors %}
<span class="author">
by {% include 'snippets/authors.html' with book=book %}
</span>
{% endif %}

View file

@ -9,10 +9,14 @@
<small>(<a href="/shelf/{{ user | username }}/{{ shelf.identifier }}">See all {{ shelf.size }}</a>)</small>
{% endif %}
</h2>
<div class="covers-shelf {{ shelf.identifier }}">
<div class="covers-shelf {{ shelf.identifier }} ">
{% for book in shelf.books %}
<div class="book-preview" onclick="show_compose(this, event)" id="book-{{ book.id }}">
<a href="{{ book.absolute_id }}">{% include 'snippets/book_cover.html' with book=book %}</a>
<div class="cover-container">
<div >
<a href="{{ book.absolute_id }}" onclick="show_compose(this, event)" id="book-{{ book.id }}">
{% include 'snippets/book_cover.html' with book=book %}
</a>
</div>
{% include 'snippets/shelve_button.html' with book=book %}
</div>
{% endfor %}

View file

@ -11,7 +11,9 @@
{% endif %}
</h2>
<div class="status-content">
{% include 'snippets/status_content.html' with status=status %}
</div>
</div>
{% if status.status_type == 'Boost' %}

View file

@ -1,36 +1,52 @@
{% load fr_display %}
{% if not hide_book and status.mention_books.count %}
<div class="row book-row">
{% for book in status.mention_books.all|slice:"0:3" %}
<div class="book-preview">
{% if status.status_type == 'Review' %}
{% include 'snippets/book.html' with book=book %}
{% else %}
{% include 'snippets/book.html' with book=book description=True %}
<div class="row">
{% for book in status.mention_books.all|slice:"0:4" %}
<div class="row">
<div class="cover-container">
{% include 'snippets/book_cover.html' with book=book %}
{% if status.mention_books.count > 1 %}
<p>{% include 'snippets/book_titleby.html' with book=book %}</p>
{% endif %}
</div>
{% endfor %}
</div>
{% include 'snippets/shelve_button.html' with book=book %}
</div>
{% if status.mention_books.count == 1 %}
<div>
<p>{% include 'snippets/book_titleby.html' with book=book %}</p>
{% include 'snippets/book_description.html' with book=book %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
{% if not hide_book and status.book%}
<div class="book-preview">
{% if status.status_type == 'Review' %}
{% include 'snippets/book.html' with book=status.book %}
{% else %}
{% include 'snippets/book.html' with book=status.book description=True %}
<div class="row">
{% if not hide_book and status.book %}
<div class="cover-container">
{% include 'snippets/book_cover.html' with book=status.book %}
{% include 'snippets/shelve_button.html' with book=status.book %}
</div>
{% endif %}
</div>
{% endif %}
{% if status.status_type == 'Review' %}<h4>{{ status.name }}
<small>{{ status.rating | stars }} stars, by {% include 'snippets/username.html' with user=status.user %}</small>
</h4>{% endif %}
{% if status.status_type != 'Update' and status.status_type != 'Boost' %}
<blockquote>{{ status.content | safe }}</blockquote>
{% endif %}
{% if status.status_type == 'Boost' %}
<div>
{% if status.status_type == 'Review' %}
<h3>
{{ status.name }}<br>
{{ status.rating | stars }}
</h3>
{% endif %}
{% if status.status_type != 'Update' and status.status_type != 'Boost' %}
<blockquote>{{ status.content | safe }}</blockquote>
{% 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 %}<p><a href="{{ status.absolute_id }}">Thread</a>{% endif %}
{% endif %}
{% if not max_depth and status.reply_parent or status|replies %}<p><a href="{{ status.absolute_id }}">Thread</a>{% endif %}
</div>
</div>

View file

@ -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)