forked from mirrors/bookwyrm
Merge pull request #1399 from bookwyrm-social/half-stars
Support half star ratings
This commit is contained in:
commit
ec2dadc87e
4 changed files with 70 additions and 2 deletions
|
@ -170,6 +170,21 @@ body {
|
||||||
content: '\e9d9'; /* icon-star-full */
|
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. */
|
/* Icons directly following inputs that follow the checked input are emptied. */
|
||||||
.form-rate-stars input:checked ~ input + .icon::before {
|
.form-rate-stars input:checked ~ input + .icon::before {
|
||||||
content: '\e9d7'; /* icon-star-empty */
|
content: '\e9d7'; /* icon-star-empty */
|
||||||
|
@ -177,11 +192,11 @@ body {
|
||||||
|
|
||||||
/* When a label is hovered, repeat the fill-all-then-empty-following pattern. */
|
/* When a label is hovered, repeat the fill-all-then-empty-following pattern. */
|
||||||
.form-rate-stars:hover .icon.icon::before {
|
.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 {
|
.form-rate-stars .icon:hover ~ .icon::before {
|
||||||
content: '\e9d7'; /* icon-star-empty */
|
content: '\e9d7' !important; /* icon-star-empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Book covers
|
/** Book covers
|
||||||
|
|
|
@ -14,6 +14,9 @@ let StatusCache = new class {
|
||||||
'submit',
|
'submit',
|
||||||
this.submitStatus.bind(this))
|
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();
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% load stars %}
|
||||||
|
|
||||||
<div class="
|
<div class="
|
||||||
field is-grouped
|
field is-grouped
|
||||||
|
@ -20,6 +21,24 @@
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{% for i in '12345'|make_list %}
|
{% 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
|
<input
|
||||||
id="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
|
id="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
|
||||||
class="is-sr-only"
|
class="is-sr-only"
|
||||||
|
@ -39,6 +58,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
"
|
"
|
||||||
for="{{ type|slugify }}_book{{ book.id }}_star_{{ forloop.counter }}"
|
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">
|
<span class="is-sr-only">
|
||||||
{% blocktranslate trimmed count rating=forloop.counter %}
|
{% blocktranslate trimmed count rating=forloop.counter %}
|
||||||
|
|
11
bookwyrm/templatetags/stars.py
Normal file
11
bookwyrm/templatetags/stars.py
Normal 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"
|
Loading…
Reference in a new issue