Merge pull request #1399 from bookwyrm-social/half-stars

Support half star ratings
This commit is contained in:
Mouse Reeve 2021-09-10 15:11:33 -07:00 committed by GitHub
commit ec2dadc87e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 2 deletions

View file

@ -170,6 +170,21 @@ body {
content: '\e9d9'; /* icon-star-full */
}
/* Icons directly following half star inputs are marked as half */
.form-rate-stars input.half:checked ~ .icon::before {
content: '\e9d8'; /* icon-star-half */
}
/* stylelint-disable no-descending-specificity */
.form-rate-stars input.half:checked + input + .icon:hover::before {
content: '\e9d8' !important; /* icon-star-half */
}
/* Icons directly following half check inputs that follow the checked input are emptied. */
.form-rate-stars input.half:checked + input + .icon ~ .icon::before {
content: '\e9d7'; /* icon-star-empty */
}
/* Icons directly following inputs that follow the checked input are emptied. */
.form-rate-stars input:checked ~ input + .icon::before {
content: '\e9d7'; /* icon-star-empty */
@ -177,11 +192,11 @@ body {
/* When a label is hovered, repeat the fill-all-then-empty-following pattern. */
.form-rate-stars:hover .icon.icon::before {
content: '\e9d9'; /* icon-star-full */
content: '\e9d9' !important; /* icon-star-full */
}
.form-rate-stars .icon:hover ~ .icon::before {
content: '\e9d7'; /* icon-star-empty */
content: '\e9d7' !important; /* icon-star-empty */
}
/** Book covers

View file

@ -14,6 +14,9 @@ let StatusCache = new class {
'submit',
this.submitStatus.bind(this))
);
document.querySelectorAll('.form-rate-stars label.icon')
.forEach(button => button.addEventListener('click', this.toggleStar.bind(this)));
}
/**
@ -198,5 +201,24 @@ let StatusCache = new class {
menu.click();
}
}
/**
* Reveal half-stars
*
* @param {Event} event
* @return {undefined}
*/
toggleStar(event) {
const label = event.currentTarget;
let wholeStar = document.getElementById(label.getAttribute("for"));
if (wholeStar.checked) {
event.preventDefault();
let halfStar = document.getElementById(label.dataset.forHalf);
wholeStar.checked = null;
halfStar.checked = "checked";
}
}
}();

View file

@ -1,5 +1,6 @@
{% spaceless %}
{% load i18n %}
{% load stars %}
<div class="
field is-grouped
@ -20,6 +21,24 @@
</label>
{% for i in '12345'|make_list %}
<label
class="is-sr-only"
for="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter0 }}_half"
>
{% blocktranslate trimmed count rating=forloop.counter0 with half_rating=forloop.counter0|half_star %}
{{ half_rating }} star
{% plural %}
{{ half_rating }} stars
{% endblocktranslate %}
</label>
<input
id="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter0 }}_half"
class="is-sr-only half"
type="radio"
name="rating"
value="{{ forloop.counter0 }}.5"
{% if default_rating == forloop.counter %}checked{% endif %}
/>
<input
id="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
class="is-sr-only"
@ -39,6 +58,7 @@
{% endif %}
"
for="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
data-for-half="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter0 }}_half"
>
<span class="is-sr-only">
{% blocktranslate trimmed count rating=forloop.counter %}

View file

@ -0,0 +1,11 @@
""" template filters """
from django import template
register = template.Library()
@register.filter(name="half_star")
def get_half_star(value):
"""one of those things that's weirdly hard with templates"""
return f"{value}.5"