Add option for progress percentage

And rework display on book page as well
This commit is contained in:
Joel Bradshaw 2020-11-28 00:07:04 -08:00
parent 9ed7d23000
commit 500f05266a
6 changed files with 95 additions and 39 deletions

View file

@ -292,13 +292,21 @@ class Boost(Status):
# unique_together = ('user', 'boosted_status') # unique_together = ('user', 'boosted_status')
class ProgressMode(models.TextChoices):
PAGE = 'PG', 'page'
PERCENT = 'PCT', 'percent'
class ReadThrough(BookWyrmModel): class ReadThrough(BookWyrmModel):
''' Store a read through a book in the database. ''' ''' Store a read through a book in the database. '''
user = models.ForeignKey('User', on_delete=models.PROTECT) user = models.ForeignKey('User', on_delete=models.PROTECT)
book = models.ForeignKey('Book', on_delete=models.PROTECT) book = models.ForeignKey('Book', on_delete=models.PROTECT)
pages_read = models.IntegerField( progress = models.IntegerField(
null=True, null=True,
blank=True) blank=True)
progress_mode = models.CharField(
max_length=3,
choices=ProgressMode.choices,
default=ProgressMode.PAGE)
start_date = models.DateTimeField( start_date = models.DateTimeField(
blank=True, blank=True,
null=True) null=True)
@ -312,9 +320,13 @@ class ReadThrough(BookWyrmModel):
self.user.save() self.user.save()
super().save(*args, **kwargs) super().save(*args, **kwargs)
class ProgressMode(models.TextChoices): def create_update(self):
PAGE = 'PG', 'page' if self.progress:
PERCENT = 'PCT', 'percent' return self.progressupdate_set.create(
user=self.user,
progress=self.progress,
mode=self.progress_mode)
class ProgressUpdate(BookWyrmModel): class ProgressUpdate(BookWyrmModel):
''' Store progress through a book in the database. ''' ''' Store progress through a book in the database. '''

View file

@ -74,9 +74,13 @@
{% if readthrough.finish_date %} {% if readthrough.finish_date %}
<dt>Finished reading:</dt> <dt>Finished reading:</dt>
<dd>{{ readthrough.finish_date | naturalday }}</dd> <dd>{{ readthrough.finish_date | naturalday }}</dd>
{% elif readthrough.pages_read %} {% elif readthrough.progress %}
<dt>On page:</dt> <dt>Progress:</dt>
<dd>{{ readthrough.pages_read }} of {{ book.pages }}</dd> {% if readthrough.progress_mode == 'PG' %}
<dd>on page {{ readthrough.progress }} of {{ book.pages }}</dd>
{% else %}
<dd>{{ readthrough.progress }}%</dd>
{% endif %}
{% endif %} {% endif %}
</dl> </dl>
<div class="field is-grouped"> <div class="field is-grouped">
@ -93,12 +97,22 @@
</div> </div>
{% if show_progress %} {% if show_progress %}
Progress Updates: Progress Updates:
<dl class="progress-updates"> <ul>
{% if readthrough.finish_date %}
<li>{{ readthrough.start_date | naturalday }}: finished</li>
{% endif %}
{% for progress_update in readthrough.progress_updates %} {% for progress_update in readthrough.progress_updates %}
<dt>{{ progress_update.created_date | naturalday }}:</dt> <li>
<dd>{{ progress_update.progress }} of {{ book.pages }}</dd> {{ progress_update.created_date | naturalday }}:
{% if progress_update.mode == 'PG' %}
page {{ progress_update.progress }} of {{ book.pages }}
{% else %}
{{ progress_update.progress }}%
{% endif %}
</li>
{% endfor %} {% endfor %}
</dl> <li>{{ readthrough.start_date | naturalday }}: started</li>
</ul>
{% elif readthrough.progress_updates|length %} {% elif readthrough.progress_updates|length %}
<a href="?showprogress">Show {{ readthrough.progress_updates|length }} Progress Updates</a> <a href="?showprogress">Show {{ readthrough.progress_updates|length }} Progress Updates</a>
{% endif %} {% endif %}
@ -118,11 +132,27 @@
<input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}"> <input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</label> </label>
</div> </div>
<div class="field"> <div class="columns">
<label class="label"> <div class="column">
On page <div class="field">
<input type="number" name="pages_read" class="input" id="id_pages_read-{{ readthrough.id }}" value="{{ readthrough.pages_read }}"> <label class="label">
</label> Progress
<input type="number" name="progress" class="input" id="id_progress-{{ readthrough.id }}" value="{{ readthrough.progress }}">
</label>
</div>
</div>
<div class="column">
<div class="control mt-5">
<label class="radio">
<input type="radio" name="progress_mode" id="id_progress_mode-{{ readthrough.id }}" value="PG" {% if readthrough.progress_mode == 'PG' %}checked{% endif %}>
pages
</label>
<label class="radio">
<input type="radio" name="progress_mode" id="id_progress_mode-{{ readthrough.id }}" value="PCT" {% if readthrough.progress_mode == 'PCT' %}checked{% endif %}>
percent
</label>
</div>
</div>
</div> </div>
<div class="field"> <div class="field">
<label class="label"> <label class="label">

View file

@ -1,13 +1,26 @@
<form class="field is-grouped is-small pl-2" action="/edit-readthrough" method="POST"> <form class="field is-grouped is-small pl-2" 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 }}"/>
<div class="control">on page</div>
<div class="control"> <div class="control">
<input aria-label="Current page" class="input is-small" type="text" name="pages_read" size="3" value="{{ readthrough.pages_read }}"> {% if readthrough.progress_mode == 'PG' %}
on page
{% else %}
currently at
{% endif %}
</div>
<div class="control">
<input
aria-label="{% if readthrough.progress_mode == 'PG' %}Current page{% else %}Perent read{% endif%}"
class="input is-small" type="text"
name="progress" size="3" value="{{ readthrough.progress }}">
</div>
<div class="control">
{% if readthrough.progress_mode == 'PG' and book.pages %}
of {{ book.pages }}
{% else %}
%
{% endif %}
</div> </div>
{% if book.pages %}
<div class="control">of {{ book.pages }}</div>
{% endif %}
<div class="control"> <div class="control">
<button class="button is-small px-2" type="submit">Go</button> <button class="button is-small px-2" type="submit">Go</button>
</div> </div>

View file

@ -36,7 +36,7 @@ class ReadThrough(TestCase):
self.assertEqual(readthroughs[0].progressupdate_set.count(), 0) self.assertEqual(readthroughs[0].progressupdate_set.count(), 0)
self.assertEqual(readthroughs[0].start_date, self.assertEqual(readthroughs[0].start_date,
datetime(2020, 11, 27, tzinfo=timezone.utc)) datetime(2020, 11, 27, tzinfo=timezone.utc))
self.assertEqual(readthroughs[0].pages_read, None) self.assertEqual(readthroughs[0].progress, None)
self.assertEqual(readthroughs[0].finish_date, None) self.assertEqual(readthroughs[0].finish_date, None)
def test_create_progress_readthrough(self): def test_create_progress_readthrough(self):
@ -44,14 +44,14 @@ class ReadThrough(TestCase):
self.client.post('/start-reading/{}'.format(self.edition.id), { self.client.post('/start-reading/{}'.format(self.edition.id), {
'start_date': '2020-11-27', 'start_date': '2020-11-27',
'pages_read': 50, 'progress': 50,
}) })
readthroughs = self.edition.readthrough_set.all() readthroughs = self.edition.readthrough_set.all()
self.assertEqual(len(readthroughs), 1) self.assertEqual(len(readthroughs), 1)
self.assertEqual(readthroughs[0].start_date, self.assertEqual(readthroughs[0].start_date,
datetime(2020, 11, 27, tzinfo=timezone.utc)) datetime(2020, 11, 27, tzinfo=timezone.utc))
self.assertEqual(readthroughs[0].pages_read, 50) self.assertEqual(readthroughs[0].progress, 50)
self.assertEqual(readthroughs[0].finish_date, None) self.assertEqual(readthroughs[0].finish_date, None)
progress_updates = readthroughs[0].progressupdate_set.all() progress_updates = readthroughs[0].progressupdate_set.all()
@ -62,7 +62,7 @@ class ReadThrough(TestCase):
# Update progress # Update progress
self.client.post('/edit-readthrough', { self.client.post('/edit-readthrough', {
'id': readthroughs[0].id, 'id': readthroughs[0].id,
'pages_read': 100, 'progress': 100,
}) })
progress_updates = readthroughs[0].progressupdate_set\ progress_updates = readthroughs[0].progressupdate_set\

View file

@ -364,11 +364,7 @@ def start_reading(request, book_id):
readthrough.save() readthrough.save()
# create a progress update if we have a page # create a progress update if we have a page
if readthrough.pages_read: readthrough.create_update()
readthrough.progressupdate_set.create(
user=request.user,
progress=readthrough.pages_read,
mode=models.ProgressMode.PAGE)
# shelve the book # shelve the book
if request.POST.get('reshelve', True): if request.POST.get('reshelve', True):
@ -440,10 +436,7 @@ def edit_readthrough(request):
# record the progress update individually # record the progress update individually
# use default now for date field # use default now for date field
readthrough.progressupdate_set.create( readthrough.create_update()
user=request.user,
progress=readthrough.pages_read,
mode=models.ProgressMode.PAGE)
return redirect(request.headers.get('Referer', '/')) return redirect(request.headers.get('Referer', '/'))
@ -750,11 +743,19 @@ def update_readthrough(request, book=None, create=True):
except ParserError: except ParserError:
pass pass
pages_read = request.POST.get('pages_read') progress = request.POST.get('progress')
if pages_read: if progress:
try: try:
pages_read = int(pages_read) progress = int(progress)
readthrough.pages_read = pages_read readthrough.progress = progress
except ValueError:
pass
progress_mode = request.POST.get('progress_mode')
if progress_mode:
try:
progress_mode = models.ProgressMode(progress_mode)
readthrough.progress_mode = progress_mode
except ValueError: except ValueError:
pass pass

View file

@ -564,7 +564,7 @@ def book_page(request, book_id):
for readthrough in readthroughs: for readthrough in readthroughs:
readthrough.progress_updates = \ readthrough.progress_updates = \
readthrough.progressupdate_set.all().order_by('updated_date') readthrough.progressupdate_set.all().order_by('-updated_date')
rating = reviews.aggregate(Avg('rating')) rating = reviews.aggregate(Avg('rating'))
tags = models.Tag.objects.filter( tags = models.Tag.objects.filter(