mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-04 15:26:48 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
fd91a79558
21 changed files with 2411 additions and 51 deletions
|
@ -29,3 +29,8 @@ trim_trailing_whitespace = false
|
|||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
max_line_length = off
|
||||
|
||||
[{package.json,yarn.lock}]
|
||||
indent_size = unset
|
||||
indent_style = unset
|
||||
max_line_length = unset
|
||||
|
|
10
.eslintrc.js
Normal file
10
.eslintrc.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* global module */
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
|
||||
"extends": "eslint:recommended"
|
||||
};
|
29
.github/workflows/lint-frontend.yaml
vendored
Normal file
29
.github/workflows/lint-frontend.yaml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
# @url https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
|
||||
name: Lint Frontend
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, ci ]
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'static/**'
|
||||
pull_request:
|
||||
branches: [ main, ci ]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint with stylelint and ESLint.
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install modules
|
||||
run: yarn
|
||||
|
||||
- name: Run stylelint
|
||||
run: yarn stylelint **/static/**/*.css --report-needless-disables --report-invalid-scope-disables
|
||||
|
||||
- name: Run ESLint
|
||||
run: yarn eslint . --ext .js,.jsx,.ts,.tsx
|
|
@ -1,5 +1,5 @@
|
|||
# @url https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
|
||||
name: Lint Project
|
||||
name: Lint project globally
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -8,8 +8,8 @@ on:
|
|||
branches: [ main, ci ]
|
||||
|
||||
jobs:
|
||||
linters:
|
||||
name: linters
|
||||
lint:
|
||||
name: Lint with EditorConfig.
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -21,3 +21,6 @@
|
|||
|
||||
#PyCharm
|
||||
.idea
|
||||
|
||||
#Node tools
|
||||
/node_modules/
|
||||
|
|
2
.stylelintignore
Normal file
2
.stylelintignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
bookwyrm/static/css/bulma.*.css*
|
||||
bookwyrm/static/css/icons.css
|
17
.stylelintrc.js
Normal file
17
.stylelintrc.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* global module */
|
||||
|
||||
module.exports = {
|
||||
"extends": "stylelint-config-standard",
|
||||
|
||||
"plugins": [
|
||||
"stylelint-order"
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"order/order": [
|
||||
"custom-properties",
|
||||
"declarations"
|
||||
],
|
||||
"indentation": 4
|
||||
}
|
||||
};
|
|
@ -15,6 +15,8 @@ class ConnectorException(HTTPError):
|
|||
|
||||
def search(query, min_confidence=0.1):
|
||||
""" find books based on arbitary keywords """
|
||||
if not query:
|
||||
return []
|
||||
results = []
|
||||
|
||||
# Have we got a ISBN ?
|
||||
|
|
|
@ -7,6 +7,7 @@ html {
|
|||
.image {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.navbar .logo {
|
||||
max-height: 50px;
|
||||
}
|
||||
|
@ -21,25 +22,33 @@ html {
|
|||
}
|
||||
|
||||
/* --- SHELVING --- */
|
||||
|
||||
/** @todo Replace icons with SVG symbols.
|
||||
@see https://www.youtube.com/watch?v=9xXBYcWgCHA */
|
||||
.shelf-option:disabled > *::after {
|
||||
font-family: "icomoon";
|
||||
font-family: "icomoon"; /* stylelint-disable font-family-no-missing-generic-family-keyword */
|
||||
content: "\e918";
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
/* --- TOGGLES --- */
|
||||
.toggle-button[aria-pressed=true], .toggle-button[aria-pressed=true]:hover {
|
||||
.toggle-button[aria-pressed=true],
|
||||
.toggle-button[aria-pressed=true]:hover {
|
||||
background-color: hsl(171, 100%, 41%);
|
||||
color: white;
|
||||
}
|
||||
.hide-active[aria-pressed=true], .hide-inactive[aria-pressed=false] {
|
||||
|
||||
.hide-active[aria-pressed=true],
|
||||
.hide-inactive[aria-pressed=false] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
.hidden.transition-y, .hidden.transition-x {
|
||||
|
||||
.hidden.transition-y,
|
||||
.hidden.transition-x {
|
||||
display: block !important;
|
||||
visibility: hidden !important;
|
||||
height: 0;
|
||||
|
@ -47,18 +56,22 @@ html {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.transition-y {
|
||||
transition-property: height, margin-top, margin-bottom, padding-top, padding-bottom;
|
||||
transition-duration: 0.5s;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
.transition-x {
|
||||
transition-property: width, margin-left, margin-right, padding-left, padding-right;
|
||||
transition-duration: 0.5s;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.transition-x, .transition-y {
|
||||
.transition-x,
|
||||
.transition-y {
|
||||
transition-duration: 0.001ms !important;
|
||||
}
|
||||
}
|
||||
|
@ -71,36 +84,46 @@ html {
|
|||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
.rate-stars:hover .icon:before {
|
||||
|
||||
.rate-stars:hover .icon::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.rate-stars form:hover ~ form .icon:before{
|
||||
|
||||
.rate-stars form:hover ~ form .icon::before {
|
||||
content: '\e9d7';
|
||||
}
|
||||
|
||||
/* stars in a review form */
|
||||
.form-rate-stars:hover .icon:before {
|
||||
/** stars in a review form
|
||||
*
|
||||
* @todo Simplify the logic for those icons.
|
||||
*/
|
||||
.form-rate-stars input + .icon.icon::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.form-rate-stars input + .icon:before {
|
||||
|
||||
.form-rate-stars:hover .icon.icon::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.form-rate-stars input:checked + .icon:before {
|
||||
|
||||
.form-rate-stars input:checked + .icon.icon::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.form-rate-stars input:checked + * ~ .icon:before {
|
||||
content: '\e9d7';
|
||||
}
|
||||
.form-rate-stars:hover label.icon:before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.form-rate-stars label.icon:hover:before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
.form-rate-stars label.icon:hover ~ label.icon:before{
|
||||
|
||||
.form-rate-stars input:checked + * ~ .icon.icon::before {
|
||||
content: '\e9d7';
|
||||
}
|
||||
|
||||
.form-rate-stars:hover label.icon.icon::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
|
||||
.form-rate-stars label.icon:hover::before {
|
||||
content: '\e9d9';
|
||||
}
|
||||
|
||||
.form-rate-stars label.icon:hover ~ label.icon.icon::before {
|
||||
content: '\e9d7';
|
||||
}
|
||||
|
||||
/* --- BOOK COVERS --- */
|
||||
.cover-container {
|
||||
|
@ -108,46 +131,46 @@ html {
|
|||
width: max-content;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.cover-container.is-large {
|
||||
height: max-content;
|
||||
max-width: 330px;
|
||||
}
|
||||
|
||||
.cover-container.is-large img {
|
||||
max-height: 500px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cover-container.is-medium {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.cover-container.is-small {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.cover-container {
|
||||
height: 200px;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.cover-container.is-medium {
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.cover-container.is-medium .no-cover div {
|
||||
font-size: 0.9em;
|
||||
padding: 0.3em;
|
||||
}
|
||||
.cover-container.is-small .no-cover div {
|
||||
font-size: 0.7em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
.book-cover {
|
||||
height: 100%;
|
||||
object-fit: scale-down;
|
||||
}
|
||||
|
||||
.no-cover {
|
||||
position: relative;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.no-cover div {
|
||||
position: absolute;
|
||||
padding: 1em;
|
||||
|
@ -157,38 +180,51 @@ html {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.cover-container.is-medium .no-cover div {
|
||||
font-size: 0.9em;
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
.cover-container.is-small .no-cover div {
|
||||
font-size: 0.7em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
/* --- AVATAR --- */
|
||||
.avatar {
|
||||
vertical-align: middle;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.is-32x32 {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.is-96x96 {
|
||||
min-width: 96px;
|
||||
min-height: 96px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --- QUOTES --- */
|
||||
.quote blockquote {
|
||||
position: relative;
|
||||
padding-left: 2em;
|
||||
}
|
||||
.quote blockquote:before, .quote blockquote:after {
|
||||
|
||||
.quote blockquote::before,
|
||||
.quote blockquote::after {
|
||||
font-family: 'icomoon';
|
||||
position: absolute;
|
||||
}
|
||||
.quote blockquote:before {
|
||||
|
||||
.quote blockquote::before {
|
||||
content: "\e906";
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.quote blockquote:after {
|
||||
|
||||
.quote blockquote::after {
|
||||
content: "\e905";
|
||||
right: 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Toggle all checkboxes.
|
||||
/* exported toggleAllCheckboxes */
|
||||
|
||||
/**
|
||||
* Toggle all descendant checkboxes of a target.
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* exported updateDisplay */
|
||||
/* globals addRemoveClass */
|
||||
|
||||
// set javascript listeners
|
||||
function updateDisplay(e) {
|
||||
// used in set reading goal
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* globals setDisplay TabGroup toggleAllCheckboxes updateDisplay */
|
||||
|
||||
// set up javascript listeners
|
||||
window.onload = function() {
|
||||
// buttons that display or hide content
|
||||
|
@ -93,7 +95,7 @@ function toggleAction(e) {
|
|||
|
||||
// show/hide container
|
||||
var container = document.getElementById('hide-' + targetId);
|
||||
if (!!container) {
|
||||
if (container) {
|
||||
addRemoveClass(container, 'hidden', pressed);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* exported TabGroup */
|
||||
|
||||
/*
|
||||
* The content below is licensed according to the W3C Software License at
|
||||
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
||||
|
|
|
@ -55,11 +55,9 @@
|
|||
</h2>
|
||||
<div class="columns is-multiline">
|
||||
{% for book in goal.books %}
|
||||
<div class="column is-narrow">
|
||||
<div class="box">
|
||||
<a href="{{ book.book.local_path }}">
|
||||
{% include 'discover/small-book.html' with book=book.book rating=goal.ratings %}
|
||||
</a>
|
||||
<div class="column is-one-fifth">
|
||||
<div class="is-clipped">
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book.book %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load bookwyrm_tags %}
|
||||
<div class="cover-container is-{{ size }}">
|
||||
{% if book.cover %}
|
||||
<img class="book-cover" src="/images/{{ book.cover }}" alt="{{ book.alt_text }}">
|
||||
<img class="book-cover" src="/images/{{ book.cover }}" alt="{{ book.alt_text }}" title="{{ book.alt_text }}">
|
||||
{% else %}
|
||||
<div class="no-cover book-cover">
|
||||
<img class="book-cover" src="/static/images/no_cover.jpg" alt="No cover">
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<form class="dropdown-item pt-0 pb-0" name="shelve" action="/shelve/" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="book" value="{{ book.id }}">
|
||||
<input type="hidden" name="change-shelf-from" value={{ current.identifier }}>
|
||||
<input type="hidden" name="change-shelf-from" value="{{ current.identifier }}">
|
||||
<input type="hidden" name="shelf" value="{{ shelf.identifier }}">
|
||||
<button class="button is-fullwidth is-small" type="submit">{{ shelf.name }}</button>
|
||||
</form>
|
||||
|
|
|
@ -111,7 +111,12 @@
|
|||
{% endif %}
|
||||
{% if shelf.user == request.user %}
|
||||
<td>
|
||||
{% include 'snippets/shelf_selector.html' with current=shelf %}
|
||||
{% 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 %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
|
|
@ -31,7 +31,7 @@ class Search(View):
|
|||
return JsonResponse([r.json() for r in book_results], safe=False)
|
||||
|
||||
# use webfinger for mastodon style account@domain.com username
|
||||
if re.match(r"\B%s" % regex.full_username, query):
|
||||
if query and re.match(regex.full_username, query):
|
||||
handle_remote_webfinger(query)
|
||||
|
||||
# do a user search
|
||||
|
@ -73,6 +73,6 @@ class Search(View):
|
|||
"book_results": book_results,
|
||||
"user_results": user_results,
|
||||
"list_results": list_results,
|
||||
"query": query,
|
||||
"query": query or "",
|
||||
}
|
||||
return TemplateResponse(request, "search_results.html", data)
|
||||
|
|
|
@ -102,7 +102,7 @@ def create_shelf(request):
|
|||
return redirect(request.headers.get("Referer", "/"))
|
||||
|
||||
shelf = form.save()
|
||||
return redirect("/user/%s/shelf/%s" % (request.user.localname, shelf.identifier))
|
||||
return redirect(shelf.local_path)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -114,7 +114,7 @@ def delete_shelf(request, shelf_id):
|
|||
return HttpResponseBadRequest()
|
||||
|
||||
shelf.delete()
|
||||
return redirect("/user/%s/shelves" % request.user.localname)
|
||||
return redirect("user-shelves", request.user.localname)
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
8
package.json
Normal file
8
package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"eslint": "^7.23.0",
|
||||
"stylelint": "^13.12.0",
|
||||
"stylelint-config-standard": "^21.0.0",
|
||||
"stylelint-order": "^4.1.0"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue