From dca6e825948340117253bcdcfdcb5e465b5afaed Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 21 Aug 2023 00:13:22 +0100 Subject: [PATCH] Add JS to vote on reviews without form submit Fixes #329 --- app/public/static/collection_editor.js | 4 +- app/public/static/quick_review_voting.js | 86 ++++++++++++++++++++++ app/templates/collections/create_edit.html | 2 +- app/templates/index.html | 1 + app/templates/macros/reviews.html | 2 +- app/templates/packages/reviews_list.html | 4 + app/templates/packages/view.html | 1 + app/templates/threads/view.html | 4 + app/templates/users/profile.html | 4 + 9 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 app/public/static/quick_review_voting.js diff --git a/app/public/static/collection_editor.js b/app/public/static/collection_editor.js index b7ae343a..9df63949 100644 --- a/app/public/static/collection_editor.js +++ b/app/public/static/collection_editor.js @@ -167,7 +167,7 @@ function onPackageQueryUpdate() { } -window.onload = () => { +window.addEventListener("load", () => { document.querySelectorAll(".remove-package").forEach(button => { const card = button.parentNode.parentNode; const field = card.querySelector("input[name^=package_removed]"); @@ -189,4 +189,4 @@ window.onload = () => { $(".sortable").sortable({ update: updateOrder, }); -}; +}); diff --git a/app/public/static/quick_review_voting.js b/app/public/static/quick_review_voting.js new file mode 100644 index 00000000..7c3ac71a --- /dev/null +++ b/app/public/static/quick_review_voting.js @@ -0,0 +1,86 @@ +// @author rubenwardy +// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later + +"use strict"; + +function getVoteCount(button) { + const badge = button.querySelector(".badge"); + return badge ? parseInt(badge.textContent) : 0; +} + +function setVoteCount(button, count) { + let badge = button.querySelector(".badge"); + if (count == 0) { + if (badge) { + badge.remove(); + } + return; + } + if (!badge) { + badge = document.createElement("span") + badge.classList.add("badge"); + badge.classList.add("badge-light"); + badge.classList.add("badge-ml-1"); + button.appendChild(badge); + } + + badge.textContent = count.toString(); +} + + +async function submitForm(form, is_helpful) { + const data = new URLSearchParams(); + for (const pair of new FormData(form)) { + data.append(pair[0], pair[1]); + } + data.set("is_positive", is_helpful ? "yes" : "no"); + + const res = await fetch(form.getAttribute("action"), { + method: "post", + body: data, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + + if (!res.ok) { + console.error(await res.text()); + } +} + + +window.addEventListener("load", () => { + document.querySelectorAll(".review-helpful-vote").forEach((helpful_form) => { + const yes = helpful_form.querySelector("button[name='is_positive'][value='yes']"); + const no = helpful_form.querySelector("button[name='is_positive'][value='no']"); + + function setVote(is_helpful) { + const selected = is_helpful ? yes : no; + const not_selected = is_helpful ? no : yes; + + if (not_selected.classList.contains("btn-primary")) { + setVoteCount(not_selected, Math.max(getVoteCount(not_selected) - 1, 0)); + } + if (selected.classList.contains("btn-secondary")) { + setVoteCount(selected, getVoteCount(selected) + 1); + } + + selected.classList.add("btn-primary"); + selected.classList.remove("btn-secondary"); + not_selected.classList.add("btn-secondary"); + not_selected.classList.remove("btn-primary"); + + submitForm(helpful_form, is_helpful).catch(console.error); + } + + yes.addEventListener("click", (e) => { + setVote(true); + e.preventDefault(); + }); + + no.addEventListener("click", (e) => { + setVote(false) + e.preventDefault(); + }); + }); +}); diff --git a/app/templates/collections/create_edit.html b/app/templates/collections/create_edit.html index 3f73b865..60a00f46 100644 --- a/app/templates/collections/create_edit.html +++ b/app/templates/collections/create_edit.html @@ -10,7 +10,7 @@ {% block scriptextra %} - + {% endblock %} {% block content %} diff --git a/app/templates/index.html b/app/templates/index.html index c42fda9f..45d3716d 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -21,6 +21,7 @@ } } + {% endblock %} {% block content %} diff --git a/app/templates/macros/reviews.html b/app/templates/macros/reviews.html index a7d2441b..5b77fd29 100644 --- a/app/templates/macros/reviews.html +++ b/app/templates/macros/reviews.html @@ -1,6 +1,6 @@ {% macro render_review_vote(review, current_user, next_url) %} {% set (positive, negative, is_positive) = review.get_totals(current_user) %} -
+