forked from mirrors/bookwyrm
Merge branch 'main' into load_remote_statuses
This commit is contained in:
commit
275527f255
33 changed files with 249 additions and 244 deletions
|
@ -1,6 +1,6 @@
|
||||||
''' handles all of the activity coming in to the server '''
|
''' handles all of the activity coming in to the server '''
|
||||||
import json
|
import json
|
||||||
from urllib.parse import urldefrag
|
from urllib.parse import urldefrag, unquote_plus
|
||||||
|
|
||||||
import django.db.utils
|
import django.db.utils
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
@ -286,9 +286,10 @@ def handle_boost(activity):
|
||||||
@app.task
|
@app.task
|
||||||
def handle_unboost(activity):
|
def handle_unboost(activity):
|
||||||
''' someone gave us a boost! '''
|
''' someone gave us a boost! '''
|
||||||
boost = models.Boost.objects.filter(remote_id=activity['object']['id']).first()
|
boost = models.Boost.objects.filter(
|
||||||
if not boost:
|
remote_id=activity['object']['id']
|
||||||
return
|
).first()
|
||||||
|
if boost:
|
||||||
status_builder.delete_status(boost)
|
status_builder.delete_status(boost)
|
||||||
|
|
||||||
|
|
||||||
|
@ -297,8 +298,15 @@ def handle_tag(activity):
|
||||||
''' someone is tagging a book '''
|
''' someone is tagging a book '''
|
||||||
user = get_or_create_remote_user(activity['actor'])
|
user = get_or_create_remote_user(activity['actor'])
|
||||||
if not user.local:
|
if not user.local:
|
||||||
book = activity['target']['id']
|
# ordered collection weirndess so we can't just to_model
|
||||||
status_builder.create_tag(user, book, activity['object']['name'])
|
book = books_manager.get_or_create_book(activity['object']['id'])
|
||||||
|
name = activity['object']['target'].split('/')[-1]
|
||||||
|
name = unquote_plus(name)
|
||||||
|
models.Tag.objects.get_or_create(
|
||||||
|
user=user,
|
||||||
|
book=book,
|
||||||
|
name=name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
|
|
|
@ -35,8 +35,8 @@ class Tag(OrderedCollectionMixin, BookWyrmModel):
|
||||||
return activitypub.Add(
|
return activitypub.Add(
|
||||||
id='%s#add' % self.remote_id,
|
id='%s#add' % self.remote_id,
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
object=self.book.to_activity(),
|
object=self.book.local_id,
|
||||||
target=self.to_activity(),
|
target=self.remote_id,
|
||||||
).serialize()
|
).serialize()
|
||||||
|
|
||||||
def to_remove_activity(self, user):
|
def to_remove_activity(self, user):
|
||||||
|
|
|
@ -136,6 +136,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
''' an ordered collection of statuses '''
|
''' an ordered collection of statuses '''
|
||||||
queryset = Status.objects.filter(
|
queryset = Status.objects.filter(
|
||||||
user=self,
|
user=self,
|
||||||
|
deleted=False,
|
||||||
).select_subclasses()
|
).select_subclasses()
|
||||||
return self.to_ordered_collection(queryset, \
|
return self.to_ordered_collection(queryset, \
|
||||||
remote_id=self.outbox, **kwargs)
|
remote_id=self.outbox, **kwargs)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import requests
|
||||||
from bookwyrm import activitypub
|
from bookwyrm import activitypub
|
||||||
from bookwyrm import models
|
from bookwyrm import models
|
||||||
from bookwyrm.broadcast import broadcast
|
from bookwyrm.broadcast import broadcast
|
||||||
from bookwyrm.status import create_tag, create_notification
|
from bookwyrm.status import create_notification
|
||||||
from bookwyrm.status import create_generated_note
|
from bookwyrm.status import create_generated_note
|
||||||
from bookwyrm.status import delete_status
|
from bookwyrm.status import delete_status
|
||||||
from bookwyrm.remote_user import get_or_create_remote_user
|
from bookwyrm.remote_user import get_or_create_remote_user
|
||||||
|
@ -257,9 +257,8 @@ def handle_status(user, form):
|
||||||
broadcast(user, remote_activity, software='other')
|
broadcast(user, remote_activity, software='other')
|
||||||
|
|
||||||
|
|
||||||
def handle_tag(user, book, name):
|
def handle_tag(user, tag):
|
||||||
''' tag a book '''
|
''' tag a book '''
|
||||||
tag = create_tag(user, book, name)
|
|
||||||
broadcast(user, tag.to_add_activity(user))
|
broadcast(user, tag.to_add_activity(user))
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -30,6 +30,7 @@
|
||||||
<glyph unicode="" glyph-name="home" horiz-adv-x="951" d="M804.571 384v-274.286c0-20-16.571-36.571-36.571-36.571h-219.429v219.429h-146.286v-219.429h-219.429c-20 0-36.571 16.571-36.571 36.571v274.286c0 1.143 0.571 2.286 0.571 3.429l328.571 270.857 328.571-270.857c0.571-1.143 0.571-2.286 0.571-3.429zM932 423.428l-35.429-42.286c-2.857-3.429-7.429-5.714-12-6.286h-1.714c-4.571 0-8.571 1.143-12 4l-395.429 329.714-395.429-329.714c-4-2.857-8.571-4.571-13.714-4-4.571 0.571-9.143 2.857-12 6.286l-35.429 42.286c-6.286 7.429-5.143 19.429 2.286 25.714l410.857 342.286c24 20 62.857 20 86.857 0l139.429-116.571v111.429c0 10.286 8 18.286 18.286 18.286h109.714c10.286 0 18.286-8 18.286-18.286v-233.143l125.143-104c7.429-6.286 8.571-18.286 2.286-25.714z" />
|
<glyph unicode="" glyph-name="home" horiz-adv-x="951" d="M804.571 384v-274.286c0-20-16.571-36.571-36.571-36.571h-219.429v219.429h-146.286v-219.429h-219.429c-20 0-36.571 16.571-36.571 36.571v274.286c0 1.143 0.571 2.286 0.571 3.429l328.571 270.857 328.571-270.857c0.571-1.143 0.571-2.286 0.571-3.429zM932 423.428l-35.429-42.286c-2.857-3.429-7.429-5.714-12-6.286h-1.714c-4.571 0-8.571 1.143-12 4l-395.429 329.714-395.429-329.714c-4-2.857-8.571-4.571-13.714-4-4.571 0.571-9.143 2.857-12 6.286l-35.429 42.286c-6.286 7.429-5.143 19.429 2.286 25.714l410.857 342.286c24 20 62.857 20 86.857 0l139.429-116.571v111.429c0 10.286 8 18.286 18.286 18.286h109.714c10.286 0 18.286-8 18.286-18.286v-233.143l125.143-104c7.429-6.286 8.571-18.286 2.286-25.714z" />
|
||||||
<glyph unicode="" glyph-name="local" horiz-adv-x="1097" d="M338.857 438.857c-59.429-1.714-113.143-27.429-151.429-73.143h-76.571c-57.143 0-110.857 27.429-110.857 90.857 0 46.286-1.714 201.714 70.857 201.714 12 0 71.429-48.571 148.571-48.571 26.286 0 51.429 4.571 76 13.143-1.714-12.571-2.857-25.143-2.857-37.714 0-52 16.571-103.429 46.286-146.286zM950.857 74.857c0-92.571-61.143-148-152.571-148h-499.429c-91.429 0-152.571 55.429-152.571 148 0 129.143 30.286 327.429 197.714 327.429 19.429 0 90.286-79.429 204.571-79.429s185.143 79.429 204.571 79.429c167.429 0 197.714-198.286 197.714-327.429zM365.714 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286zM768 585.143c0-121.143-98.286-219.429-219.429-219.429s-219.429 98.286-219.429 219.429 98.286 219.429 219.429 219.429 219.429-98.286 219.429-219.429zM1097.143 456.571c0-63.429-53.714-90.857-110.857-90.857h-76.571c-38.286 45.714-92 71.429-151.429 73.143 29.714 42.857 46.286 94.286 46.286 146.286 0 12.571-1.143 25.143-2.857 37.714 24.571-8.571 49.714-13.143 76-13.143 77.143 0 136.571 48.571 148.571 48.571 72.571 0 70.857-155.429 70.857-201.714zM1024 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286z" />
|
<glyph unicode="" glyph-name="local" horiz-adv-x="1097" d="M338.857 438.857c-59.429-1.714-113.143-27.429-151.429-73.143h-76.571c-57.143 0-110.857 27.429-110.857 90.857 0 46.286-1.714 201.714 70.857 201.714 12 0 71.429-48.571 148.571-48.571 26.286 0 51.429 4.571 76 13.143-1.714-12.571-2.857-25.143-2.857-37.714 0-52 16.571-103.429 46.286-146.286zM950.857 74.857c0-92.571-61.143-148-152.571-148h-499.429c-91.429 0-152.571 55.429-152.571 148 0 129.143 30.286 327.429 197.714 327.429 19.429 0 90.286-79.429 204.571-79.429s185.143 79.429 204.571 79.429c167.429 0 197.714-198.286 197.714-327.429zM365.714 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286zM768 585.143c0-121.143-98.286-219.429-219.429-219.429s-219.429 98.286-219.429 219.429 98.286 219.429 219.429 219.429 219.429-98.286 219.429-219.429zM1097.143 456.571c0-63.429-53.714-90.857-110.857-90.857h-76.571c-38.286 45.714-92 71.429-151.429 73.143 29.714 42.857 46.286 94.286 46.286 146.286 0 12.571-1.143 25.143-2.857 37.714 24.571-8.571 49.714-13.143 76-13.143 77.143 0 136.571 48.571 148.571 48.571 72.571 0 70.857-155.429 70.857-201.714zM1024 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286z" />
|
||||||
<glyph unicode="" glyph-name="dots-three" d="M512.051 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64zM153.651 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.483 112.589 112.64s-50.381 112.64-112.589 112.64zM870.451 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64z" />
|
<glyph unicode="" glyph-name="dots-three" d="M512.051 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64zM153.651 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.483 112.589 112.64s-50.381 112.64-112.589 112.64zM870.451 573.44c-62.208 0-112.691-50.432-112.691-112.64s50.483-112.64 112.691-112.64c62.208 0 112.589 50.432 112.589 112.64s-50.381 112.64-112.589 112.64z" />
|
||||||
|
<glyph unicode="" glyph-name="check" d="M424.653 102.502c-22.272 0-43.366 10.394-56.883 28.314l-182.938 241.715c-23.808 31.386-17.613 76.083 13.824 99.891 31.488 23.91 76.186 17.613 99.994-13.824l120.371-158.925 302.643 485.99c20.838 33.382 64.87 43.622 98.355 22.784 33.434-20.787 43.725-64.819 22.835-98.304l-357.581-573.952c-12.39-20.019-33.843-32.512-57.344-33.587-1.126-0.102-2.15-0.102-3.277-0.102z" />
|
||||||
<glyph unicode="" glyph-name="search" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" />
|
<glyph unicode="" glyph-name="search" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" />
|
||||||
<glyph unicode="" glyph-name="star-empty" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
|
<glyph unicode="" glyph-name="star-empty" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
|
||||||
<glyph unicode="" glyph-name="star-half" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-0.942-0.496 0.942 570.768 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
|
<glyph unicode="" glyph-name="star-half" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-0.942-0.496 0.942 570.768 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
|
||||||
|
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Binary file not shown.
|
@ -1,10 +1,10 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'icomoon';
|
font-family: 'icomoon';
|
||||||
src: url('fonts/icomoon.eot?ouoizu');
|
src: url('fonts/icomoon.eot?aeb2zb');
|
||||||
src: url('fonts/icomoon.eot?ouoizu#iefix') format('embedded-opentype'),
|
src: url('fonts/icomoon.eot?aeb2zb#iefix') format('embedded-opentype'),
|
||||||
url('fonts/icomoon.ttf?ouoizu') format('truetype'),
|
url('fonts/icomoon.ttf?aeb2zb') format('truetype'),
|
||||||
url('fonts/icomoon.woff?ouoizu') format('woff'),
|
url('fonts/icomoon.woff?aeb2zb') format('woff'),
|
||||||
url('fonts/icomoon.svg?ouoizu#icomoon') format('svg');
|
url('fonts/icomoon.svg?aeb2zb#icomoon') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
|
@ -25,6 +25,9 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-check:before {
|
||||||
|
content: "\e917";
|
||||||
|
}
|
||||||
.icon-dots-three:before {
|
.icon-dots-three:before {
|
||||||
content: "\e916";
|
content: "\e916";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
''' Handle user activity '''
|
''' Handle user activity '''
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.db import IntegrityError
|
|
||||||
|
|
||||||
from bookwyrm import activitypub, books_manager, models
|
from bookwyrm import activitypub, books_manager, models
|
||||||
from bookwyrm.books_manager import get_or_create_book
|
from bookwyrm.books_manager import get_or_create_book
|
||||||
|
@ -65,17 +64,6 @@ def create_generated_note(user, content, mention_books=None, privacy='public'):
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
def create_tag(user, possible_book, name):
|
|
||||||
''' add a tag to a book '''
|
|
||||||
book = get_or_create_book(possible_book)
|
|
||||||
|
|
||||||
try:
|
|
||||||
tag = models.Tag.objects.create(name=name, book=book, user=user)
|
|
||||||
except IntegrityError:
|
|
||||||
return models.Tag.objects.get(name=name, book=book, user=user)
|
|
||||||
return tag
|
|
||||||
|
|
||||||
|
|
||||||
def create_notification(user, notification_type, related_user=None, \
|
def create_notification(user, notification_type, related_user=None, \
|
||||||
related_book=None, related_status=None, related_import=None):
|
related_book=None, related_status=None, related_import=None):
|
||||||
''' let a user know when someone interacts with their content '''
|
''' let a user know when someone interacts with their content '''
|
||||||
|
|
|
@ -27,11 +27,18 @@
|
||||||
{% include 'snippets/shelve_button.html' %}
|
{% include 'snippets/shelve_button.html' %}
|
||||||
|
|
||||||
{% if request.user.is_authenticated and not book.cover %}
|
{% if request.user.is_authenticated and not book.cover %}
|
||||||
|
<div class="box p-2">
|
||||||
<form name="add-cover" method="POST" action="/upload_cover/{{ book.id }}" enctype="multipart/form-data">
|
<form name="add-cover" method="POST" action="/upload_cover/{{ book.id }}" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ cover_form.as_p }}
|
<div class="field">
|
||||||
<button class="button" type="submit">Add cover</button>
|
<label class="label" for="id_cover">Cover:</label>
|
||||||
|
<input type="file" name="cover" accept="image/*" class="" id="id_cover">
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<button class="button is-small" type="submit">Add cover</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<dl class="content">
|
<dl class="content">
|
||||||
|
@ -60,33 +67,34 @@
|
||||||
<input class="toggle-control" type="radio" name="show-edit-readthrough" id="show-readthrough-{{ readthrough.id }}" checked>
|
<input class="toggle-control" type="radio" name="show-edit-readthrough" id="show-readthrough-{{ readthrough.id }}" checked>
|
||||||
<div class="toggle-content hidden">
|
<div class="toggle-content hidden">
|
||||||
<dl>
|
<dl>
|
||||||
|
{% if readthrough.start_date %}
|
||||||
<dt>Started reading:</dt>
|
<dt>Started reading:</dt>
|
||||||
<dd>{{ readthrough.start_date | naturalday }}</dd>
|
<dd>{{ readthrough.start_date | naturalday }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
{% if readthrough.finish_date %}
|
||||||
<dt>Finished reading:</dt>
|
<dt>Finished reading:</dt>
|
||||||
<dd>{{ readthrough.finish_date | naturalday }}</dd>
|
<dd>{{ readthrough.finish_date | naturalday }}</dd>
|
||||||
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<label class="button is-small" for="edit-readthrough-{{ readthrough.id }}">
|
<label class="button is-small" for="edit-readthrough-{{ readthrough.id }}">
|
||||||
<span class="icon icon-pencil">
|
<span class="icon icon-pencil">
|
||||||
<span class="is-sr-only">Edit readthrough dates</span>
|
<span class="is-sr-only">Edit read-through dates</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<form name="delete-readthrough-{{ readthrough.id }}" action="/delete-readthrough" method="POST">
|
<label class="button is-small" for="delete-readthrough-{{ readthrough.id }}">
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="id" value="{{ readthrough.id }}">
|
|
||||||
<button class="button is-small" type="submit">
|
|
||||||
<span class="icon icon-x">
|
<span class="icon icon-x">
|
||||||
<span class="is-sr-only">Delete this readthrough</span>
|
<span class="is-sr-only">Delete this read-through</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</label>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content block">
|
<div class="block">
|
||||||
<input class="toggle-control" type="radio" name="show-edit-readthrough" id="edit-readthrough-{{ readthrough.id }}">
|
<input class="toggle-control" type="radio" name="show-edit-readthrough" id="edit-readthrough-{{ readthrough.id }}">
|
||||||
<div class="toggle-content hidden">
|
<div class="toggle-content hidden">
|
||||||
|
<div class="box">
|
||||||
<form name="edit-readthrough" action="/edit-readthrough" method="post">
|
<form name="edit-readthrough" action="/edit-readthrough" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="id" value="{{ readthrough.id }}">
|
<input type="hidden" name="id" value="{{ readthrough.id }}">
|
||||||
|
@ -103,16 +111,41 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<button class="button is-small" type="submit">Save</button>
|
<button class="button is-primary" type="submit">Save</button>
|
||||||
<label class="button is-small" for="show-readthrough-{{ readthrough.id }}">Cancel</label>
|
<label class="button" for="show-readthrough-{{ readthrough.id }}">Cancel</label>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input class="toggle-control" type="checkbox" name="delete-readthrough-{{ readthrough.id }}" id="delete-readthrough-{{ readthrough.id }}">
|
||||||
|
<div class="modal toggle-content hidden">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Delete this read-though?</p>
|
||||||
|
<label class="delete" for="delete-readthrough-{{ readthrough.id }}" aria-label="close"></label>
|
||||||
|
</header>
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<form name="delete-readthrough-{{ readthrough.id }}" action="/delete-readthrough" method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="id" value="{{ readthrough.id }}">
|
||||||
|
<button class="button is-danger" type="submit">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
<label for="delete-readthrough-{{ readthrough.id }}" class="button">Cancel</button>
|
||||||
|
</form>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
<label class="modal-close is-large" for="delete-readthrough-{{ readthrough.id }}" aria-label="close"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<div class="block">
|
<div class="box">
|
||||||
{% include 'snippets/create_status.html' with book=book hide_cover=True %}
|
{% include 'snippets/create_status.html' with book=book hide_cover=True %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% load fr_display %}
|
{% load fr_display %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'user_header.html' with user=user %}
|
{% include 'snippets/user_header.html' with user=user %}
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h2 class="title">Followers</h2>
|
<h2 class="title">Followers</h2>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% load fr_display %}
|
{% load fr_display %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'user_header.html' %}
|
{% include 'snippets/user_header.html' with user=user %}
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h2 class="title">Following</h2>
|
<h2 class="title">Following</h2>
|
||||||
|
|
|
@ -57,6 +57,5 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -29,23 +29,20 @@
|
||||||
|
|
||||||
<form name="invite" action="/create_invite/" method="post">
|
<form name="invite" action="/create_invite/" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="field">
|
<div class="field is-grouped">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="label" for="id_expiry">Expiry:</label>
|
<label class="label" for="id_expiry">Expiry:</label>
|
||||||
</div>
|
|
||||||
<div class="select">
|
<div class="select">
|
||||||
{{ form.expiry }}
|
{{ form.expiry }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<label class="label" for="id_use_limit">Use limit:</label>
|
<label class="label" for="id_use_limit">Use limit:</label>
|
||||||
</div>
|
|
||||||
<div class="select">
|
<div class="select">
|
||||||
{{ form.use_limit }}
|
{{ form.use_limit }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="button is-primary" type="submit">Create Invite</button>
|
<button class="button is-primary" type="submit">Create Invite</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -59,4 +59,3 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button is-primary" type="submit">Reset password</button>
|
<button class="button is-link" type="submit">Reset password</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="remote_id" value="{{ result.key }}">
|
<input type="hidden" name="remote_id" value="{{ result.key }}">
|
||||||
<div>{% include 'snippets/search_result_text.html' with result=result link=False %}</div>
|
<div>{% include 'snippets/search_result_text.html' with result=result link=False %}</div>
|
||||||
<button type="submit" class="button is-small is-link is-light">Import book</button>
|
<button type="submit" class="button is-small is-link">Import book</button>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% load fr_display %}
|
{% load fr_display %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'user_header.html' with user=user %}
|
{% include 'snippets/user_header.html' with user=user %}
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
{% load humanize %}
|
{% load humanize %}
|
||||||
{% load fr_display %}
|
{% load fr_display %}
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<div class="tabs is-boxed">
|
<div class="tabs is-boxed">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="is-active" data-id="tab-review-{{ book.id }}" data-category="tab-option-{{ book.id }}">
|
<li class="is-active" data-id="tab-review-{{ book.id }}" data-category="tab-option-{{ book.id }}">
|
||||||
|
@ -19,91 +17,15 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="review-{{ book.id }}" checked>
|
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="review-{{ book.id }}" checked>
|
||||||
<form class="toggle-content hidden tab-option-{{ book.id }}" name="review" action="/review/" method="post" id="tab-review-{{ book.id }}">
|
{% include 'snippets/create_status_form.html' with type='review' %}
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
|
||||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
|
||||||
<div class="control">
|
|
||||||
<label class="label" for="id_name_{{ book.id }}_review">Title:</label>
|
|
||||||
<input type="text" name="name" maxlength="255" class="input" required="" id="id_name_{{ book.id }}_review" placeholder="My review of '{{ book.title }}'">
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<label class="label" for="id_content_{{ book.id }}_review">Review:</label>
|
|
||||||
|
|
||||||
<span class="is-sr-only">Rating</span>
|
|
||||||
<div class="field is-grouped stars form-rate-stars">
|
|
||||||
<input class="hidden" type="radio" name="rating" value="" checked>
|
|
||||||
{% for i in '12345'|make_list %}
|
|
||||||
<input class="hidden" id="book{{book.id}}-star-{{ forloop.counter }}" type="radio" name="rating" value="{{ forloop.counter }}">
|
|
||||||
<label class="icon icon-star-empty" for="book{{book.id}}-star-{{ forloop.counter }}">
|
|
||||||
<span class="is-sr-only">{{ forloop.counter }} star{{ forloop.counter | pluralize }}</span>
|
|
||||||
</label>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<textarea name="content" class="textarea" id="id_content_{{ book.id }}_review"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="control is-grouped">
|
|
||||||
{% include 'snippets/privacy_select.html' %}
|
|
||||||
<button class="button is-primary" type="submit">post review</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="comment-{{ book.id }}">
|
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="comment-{{ book.id }}">
|
||||||
<form class="toggle-content hidden tab-option-{{ book.id }}" name="comment" action="/comment/" method="post" id="tab-comment-{{ book.id }}">
|
{% include 'snippets/create_status_form.html' with type="comment" placeholder="Some thougts on '"|add:book.title|add:"'" %}
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
|
||||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
|
||||||
<input type="hidden" name="privacy" value="public">
|
|
||||||
<div class="control">
|
|
||||||
<label class="label" for="id_content_{{ book.id }}_comment">Comment:</label>
|
|
||||||
<textarea name="content" class="textarea" id="id_content_{{ book.id }}_comment" placeholder="Some thoughts on '{{ book.title }}'"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="control is-grouped">
|
|
||||||
<div class="select">
|
|
||||||
<select name="privacy">
|
|
||||||
<option value="public" selected>Public</option>
|
|
||||||
<option value="unlisted">Unlisted</option>
|
|
||||||
<option value="followers">Followers only</option>
|
|
||||||
<option value="direct">Private</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button class="button is-primary" type="submit">post comment</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="quote-{{ book.id }}">
|
<input class="toggle-control" type="radio" name="status-tabs-{{ book.id }}" id="quote-{{ book.id }}">
|
||||||
<form class="toggle-content hidden tab-option-{{ book.id }}" name="quotation" action="/quotate/" method="post" id="tab-quotation-{{ book.id }}">
|
{% include 'snippets/create_status_form.html' with type="quote" placeholder="An excerpt from '"|add:book.title|add:"'" %}
|
||||||
{% csrf_token %}
|
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
|
||||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
|
||||||
<input type="hidden" name="privacy" value="public">
|
|
||||||
<div class="control">
|
|
||||||
<label class="label" for="id_quote_{{ book.id }}_quote">Quote:</label>
|
|
||||||
<textarea name="quote" class="textarea" required="" id="id_quote_{{ book.id }}_quote" placeholder="An except from '{{ book.title }}'"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<label class="label" for="id_content_{{ book.id }}_quote">Comment:</label>
|
|
||||||
<textarea name="content" class="textarea is-small" id="id_content_{{ book.id }}_quote"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="control is-grouped">
|
|
||||||
<div class="select">
|
|
||||||
<select name="privacy">
|
|
||||||
<option value="public" selected>Public</option>
|
|
||||||
<option value="unlisted">Unlisted</option>
|
|
||||||
<option value="followers">Followers only</option>
|
|
||||||
<option value="direct">Private</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button class="button is-primary" type="submit">post quote</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
40
bookwyrm/templates/snippets/create_status_form.html
Normal file
40
bookwyrm/templates/snippets/create_status_form.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<form class="toggle-content hidden tab-option-{{ book.id }}" name="{{ type }}" action="/{{ type }}" method="post" id="tab-{{ type }}-{{ book.id }}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="book" value="{{ book.id }}">
|
||||||
|
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||||
|
{% if type == 'review' %}
|
||||||
|
<div class="control">
|
||||||
|
<label class="label" for="id_name_{{ book.id }}_{{ type }}">Title:</label>
|
||||||
|
<input type="text" name="name" maxlength="255" class="input" required="" id="id_name_{{ book.id }}_{{ type }}" placeholder="My {{ type }} of '{{ book.title }}'">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="control">
|
||||||
|
<label class="label" for="id_content_{{ book.id }}_{{ type }}">{{ type|title }}:</label>
|
||||||
|
|
||||||
|
{% if type == 'review' %}
|
||||||
|
<span class="is-sr-only">Rating</span>
|
||||||
|
<div class="field is-grouped stars form-rate-stars">
|
||||||
|
<input class="hidden" type="radio" name="rating" value="" checked>
|
||||||
|
{% for i in '12345'|make_list %}
|
||||||
|
<input class="hidden" id="book{{book.id}}-star-{{ forloop.counter }}" type="radio" name="rating" value="{{ forloop.counter }}">
|
||||||
|
<label class="icon icon-star-empty" for="book{{book.id}}-star-{{ forloop.counter }}">
|
||||||
|
<span class="is-sr-only">{{ forloop.counter }} star{{ forloop.counter | pluralize }}</span>
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<textarea name="{% if type == 'quote' %}quote{% else %}content{% endif %}" class="textarea" id="id_content_{{ book.id }}_{{ type }}" placeholder="{{ placeholder }}" required></textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% if type == 'quote' %}
|
||||||
|
<div class="control">
|
||||||
|
<label class="label" for="id_content_{{ book.id }}_quote">Comment:</label>
|
||||||
|
<textarea name="content" class="textarea is-small" id="id_content_{{ book.id }}_quote"></textarea>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="control is-grouped">
|
||||||
|
{% include 'snippets/privacy_select.html' %}
|
||||||
|
<button class="button is-primary" type="submit">post {{ type }}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
|
@ -11,14 +11,14 @@ Follow request already sent.
|
||||||
{% 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 %}
|
{% if user.manually_approves_followers %}
|
||||||
<button class="button is-small is-link is-light" type="submit">Send follow request</button>
|
<button class="button is-small is-primary" type="submit">Send follow request</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="button is-small is-link is-light" type="submit">Follow</button>
|
<button class="button is-small is-primary" type="submit">Follow</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
<form action="/unfollow/" method="POST" onsubmit="interact(event)" class="follow-{{ user.id }} {% if not request.user in user.followers.all %}hidden{%endif %}" data-id="follow-{{ user.id }}">
|
<form action="/unfollow/" method="POST" onsubmit="interact(event)" class="follow-{{ user.id }} {% if not request.user in user.followers.all %}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 is-danger is-light" type="submit">Unfollow</button>
|
<button class="button is-small is-danger" type="submit">Unfollow</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
<form action="/accept_follow_request/" method="POST">
|
<form action="/accept_follow_request/" method="POST">
|
||||||
{% 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" type="submit">Accept</button>
|
<button class="button is-primary is-small" type="submit">Accept</button>
|
||||||
</form>
|
</form>
|
||||||
<form action="/delete_follow_request/" method="POST">
|
<form action="/delete_follow_request/" method="POST">
|
||||||
{% 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" type="submit" class="warning">Delete</button>
|
<button class="button is-danger is-small" type="submit" class="warning">Delete</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
<input type="hidden" name="book" value="{{ book.id }}">
|
||||||
<input type="hidden" name="shelf" value="{{ shelf.id }}">
|
<input type="hidden" name="shelf" value="{{ shelf.id }}">
|
||||||
<button class="button is-small" type="submit" style="">
|
<button class="button is-danger is-small" type="submit" style="">
|
||||||
<span class="icon icon-x">
|
<span class="icon icon-x">
|
||||||
<span class="is-sr-only">Remove from shelf</span>
|
<span class="is-sr-only">Remove from shelf</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
{% active_shelf book as active_shelf %}
|
{% active_shelf book as active_shelf %}
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
{% if active_shelf.identifier == 'read' %}
|
{% if active_shelf.identifier == 'read' %}
|
||||||
<button class="button is-small" disabled>Read ✓</button>
|
<button class="button is-small" disabled>
|
||||||
|
<span>Read</span> <span class="icon icon-check"></span>
|
||||||
|
</button>
|
||||||
{% elif active_shelf.identifier == 'reading' %}
|
{% elif active_shelf.identifier == 'reading' %}
|
||||||
<label class="button is-small" for="finish-reading-{{ uuid }}">
|
<label class="button is-small" for="finish-reading-{{ uuid }}">
|
||||||
I'm done!
|
I'm done!
|
||||||
|
@ -42,7 +44,10 @@
|
||||||
<form class="dropdown-item pt-0 pb-0" name="shelve" action="/shelve/" method="post">
|
<form class="dropdown-item pt-0 pb-0" name="shelve" action="/shelve/" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
<input type="hidden" name="book" value="{{ book.id }}">
|
||||||
<button class="button is-small" name="shelf" type="submit" value="{{ shelf.identifier }}" {% if shelf in book.shelf_set.all %} disabled {% endif %}>{{ shelf.name }} {% if shelf in book.shelf_set.all %} ✓ {% endif %}</button>
|
<button class="button is-small" name="shelf" type="submit" value="{{ shelf.identifier }}" {% if shelf in book.shelf_set.all %} disabled {% endif %}>
|
||||||
|
<span>{{ shelf.name }}</span>
|
||||||
|
{% if shelf in book.shelf_set.all %}<span class="icon icon-check"></span>{% endif %}
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
@ -58,7 +63,7 @@
|
||||||
<div class="modal-background"></div>
|
<div class="modal-background"></div>
|
||||||
<div class="modal-card">
|
<div class="modal-card">
|
||||||
<header class="modal-card-head">
|
<header class="modal-card-head">
|
||||||
<p class="modal-card-title">Started "{{ book.title }}"</p>
|
<p class="modal-card-title">Start "{{ book.title }}"</p>
|
||||||
<label class="delete" for="start-reading-{{ uuid }}" aria-label="close"></label>
|
<label class="delete" for="start-reading-{{ uuid }}" aria-label="close"></label>
|
||||||
</header>
|
</header>
|
||||||
<form name="start-reading" action="/start-reading" method="post">
|
<form name="start-reading" action="/start-reading" method="post">
|
||||||
|
@ -82,14 +87,14 @@
|
||||||
{% include 'snippets/privacy_select.html' %}
|
{% include 'snippets/privacy_select.html' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<button type="submit" class="button is-success">Save</button>
|
<button class="button is-success" type="submit">Save</button>
|
||||||
<label for="start-reading-{{ uuid }}" class="button">Cancel</button>
|
<label for="start-reading-{{ uuid }}" class="button">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<label class="modal-close is-large" for="finish-reading-{{ uuid }}" aria-label="close"></label>
|
<label class="modal-close is-large" for="start-reading-{{ uuid }}" aria-label="close"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -99,7 +104,7 @@
|
||||||
<div class="modal-background"></div>
|
<div class="modal-background"></div>
|
||||||
<div class="modal-card">
|
<div class="modal-card">
|
||||||
<header class="modal-card-head">
|
<header class="modal-card-head">
|
||||||
<p class="modal-card-title">Finished "{{ book.title }}"</p>
|
<p class="modal-card-title">Finish "{{ book.title }}"</p>
|
||||||
<label class="delete" for="finish-reading-{{ uuid }}" aria-label="close"></label>
|
<label class="delete" for="finish-reading-{{ uuid }}" aria-label="close"></label>
|
||||||
</header>
|
</header>
|
||||||
{% active_read_through book user as readthrough %}
|
{% active_read_through book user as readthrough %}
|
||||||
|
|
|
@ -5,18 +5,20 @@
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<header class="card-header">
|
<header class="card-header">
|
||||||
<div class="card-header-title">
|
<div class="card-header-title">
|
||||||
<p>
|
<div class="columns">
|
||||||
|
<div class="column is-narrow">
|
||||||
{% if status.status_type == 'Boost' %}
|
{% if status.status_type == 'Boost' %}
|
||||||
{% include 'snippets/avatar.html' with user=status.user %}
|
{% include 'snippets/avatar.html' with user=status.user %}
|
||||||
{% include 'snippets/username.html' with user=status.user %}
|
{% include 'snippets/username.html' with user=status.user %}
|
||||||
boosted
|
boosted
|
||||||
</p>
|
</div>
|
||||||
<p>
|
<div class="column">
|
||||||
{% include 'snippets/status_header.html' with status=status|boosted_status %}
|
{% include 'snippets/status_header.html' with status=status|boosted_status %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% include 'snippets/status_header.html' with status=status %}
|
{% include 'snippets/status_header.html' with status=status %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@
|
||||||
<form name="delete-{{status.id}}" action="/delete-status" method="post">
|
<form name="delete-{{status.id}}" action="/delete-status" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="status" value="{{ status.id }}">
|
<input type="hidden" name="status" value="{{ status.id }}">
|
||||||
<button type="submit" class="button">
|
<button class="button is-danger" type="submit">
|
||||||
Delete post
|
Delete post
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
<div class="control">
|
<div class="control">
|
||||||
|
<form name="tag" action="/{% if tag.identifier in user_tags %}untag{% else %}tag{% endif %}/" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="book" value="{{ book.id }}">
|
||||||
|
<input type="hidden" name="name" value="{{ tag.name }}">
|
||||||
|
|
||||||
<div class="tags has-addons">
|
<div class="tags has-addons">
|
||||||
<a class="tag is-link" href="/tag/{{ tag.identifier|urlencode }}">
|
<a class="tag" href="/tag/{{ tag.identifier|urlencode }}">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</a>
|
</a>
|
||||||
<div class="tag">
|
|
||||||
{% if tag.identifier in user_tags %}
|
{% if tag.identifier in user_tags %}
|
||||||
<form name="tag" action="/untag/" method="post">
|
<button class="tag is-delete" type="submit">
|
||||||
{% csrf_token %}
|
<span class="is-sr-only">remove tag</span>
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
</button>
|
||||||
<input type="hidden" name="name" value="{{ tag.name }}">
|
|
||||||
<button type="submit">x<span class="is-sr-only"> remove tag</span></button>
|
|
||||||
</form>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<form name="tag" action="/tag/" method="post">
|
<button class="tag" type="submit">+
|
||||||
{% csrf_token %}
|
<span class="is-sr-only">add tag</span>
|
||||||
<input type="hidden" name="book" value="{{ book.id }}">
|
</button>
|
||||||
<input type="hidden" name="name" value="{{ tag.name }}">
|
|
||||||
<button type="submit">+<span class="is-sr-only"> add tag</span></button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,15 +18,18 @@
|
||||||
<div class="column is-narrow">
|
<div class="column is-narrow">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
|
<a href="/user/{{ user|username }}">
|
||||||
{% include 'snippets/avatar.html' with user=user large=True %}
|
{% include 'snippets/avatar.html' with user=user large=True %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-content">
|
<div class="media-content">
|
||||||
<p>{% if user.name %}{{ user.name }}{% else %}{{ user.localname }}{% endif %}</p>
|
<p>{% if user.name %}{{ user.name }}{% else %}{{ user.localname }}{% endif %}</p>
|
||||||
<p>{{ user.username }}</p>
|
<p><a href="{{ user.remote_id }}">{{ user.username }}</a></p>
|
||||||
<p>Joined {{ user.created_date | naturaltime }}</p>
|
<p>Joined {{ user.created_date | naturaltime }}</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="/user/{{ user | username }}/followers">{{ user.followers.count }} follower{{ user.followers.count | pluralize }}</a>,
|
<a href="/user/{{ user | username }}/followers">{{ user.followers.count }} follower{{ user.followers.count | pluralize }}</a>,
|
||||||
<a href="/user/{{ user | username }}/following">{{ user.following.count }} following</a></p>
|
<a href="/user/{{ user | username }}/following">{{ user.following.count }} following</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,9 +1,7 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="block">
|
{% include 'snippets/user_header.html' with user=user %}
|
||||||
{% include 'user_header.html' with user=user %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h2 class="title">Shelves</h2>
|
<h2 class="title">Shelves</h2>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% load fr_display %}
|
{% load fr_display %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'user_header.html' with user=user %}
|
{% include 'snippets/user_header.html' with user=user %}
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
|
|
|
@ -75,7 +75,7 @@ urlpatterns = [
|
||||||
# books
|
# books
|
||||||
re_path(r'%s(.json)?/?$' % book_path, views.book_page),
|
re_path(r'%s(.json)?/?$' % book_path, views.book_page),
|
||||||
re_path(r'%s/edit/?$' % book_path, views.edit_book_page),
|
re_path(r'%s/edit/?$' % book_path, views.edit_book_page),
|
||||||
re_path(r'%s/editions(.json)?/?' % book_path, views.editions_page),
|
re_path(r'%s/editions(.json)?/?$' % book_path, views.editions_page),
|
||||||
|
|
||||||
re_path(r'^author/(?P<author_id>[\w\-]+)(.json)?/?$', views.author_page),
|
re_path(r'^author/(?P<author_id>[\w\-]+)(.json)?/?$', views.author_page),
|
||||||
# TODO: tag needs a .json path
|
# TODO: tag needs a .json path
|
||||||
|
@ -107,7 +107,7 @@ urlpatterns = [
|
||||||
|
|
||||||
re_path(r'^rate/?$', actions.rate),
|
re_path(r'^rate/?$', actions.rate),
|
||||||
re_path(r'^review/?$', actions.review),
|
re_path(r'^review/?$', actions.review),
|
||||||
re_path(r'^quotate/?$', actions.quotate),
|
re_path(r'^quote/?$', actions.quotate),
|
||||||
re_path(r'^comment/?$', actions.comment),
|
re_path(r'^comment/?$', actions.comment),
|
||||||
re_path(r'^tag/?$', actions.tag),
|
re_path(r'^tag/?$', actions.tag),
|
||||||
re_path(r'^untag/?$', actions.untag),
|
re_path(r'^untag/?$', actions.untag),
|
||||||
|
|
|
@ -468,9 +468,18 @@ def tag(request):
|
||||||
# field which doesn't validate
|
# field which doesn't validate
|
||||||
name = request.POST.get('name')
|
name = request.POST.get('name')
|
||||||
book_id = request.POST.get('book')
|
book_id = request.POST.get('book')
|
||||||
remote_id = 'https://%s/book/%s' % (DOMAIN, book_id)
|
try:
|
||||||
|
book = models.Edition.objects.get(id=book_id)
|
||||||
|
except models.Edition.DoesNotExist:
|
||||||
|
return HttpResponseNotFound()
|
||||||
|
tag_obj, created = models.Tag.objects.get_or_create(
|
||||||
|
name=name,
|
||||||
|
book=book,
|
||||||
|
user=request.user
|
||||||
|
)
|
||||||
|
|
||||||
outgoing.handle_tag(request.user, remote_id, name)
|
if created:
|
||||||
|
outgoing.handle_tag(request.user, tag_obj)
|
||||||
return redirect('/book/%s' % book_id)
|
return redirect('/book/%s' % book_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -430,7 +430,7 @@ def status_page(request, username, status_id):
|
||||||
return JsonResponse(status.to_activity(), encoder=ActivityEncoder)
|
return JsonResponse(status.to_activity(), encoder=ActivityEncoder)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'title': status.type,
|
'title': 'Status by %s' % user.username,
|
||||||
'status': status,
|
'status': status,
|
||||||
}
|
}
|
||||||
return TemplateResponse(request, 'status.html', data)
|
return TemplateResponse(request, 'status.html', data)
|
||||||
|
|
Loading…
Reference in a new issue