diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py
index 5907159f..133f5a2a 100644
--- a/app/blueprints/packages/reviews.py
+++ b/app/blueprints/packages/reviews.py
@@ -16,7 +16,8 @@
from collections import namedtuple
-from flask import render_template, request, redirect, flash, url_for, abort
+import typing
+from flask import render_template, request, redirect, flash, url_for, abort, jsonify
from flask_babel import gettext, lazy_gettext
from flask_login import current_user, login_required
from flask_wtf import FlaskForm
@@ -27,7 +28,7 @@ from app.models import db, PackageReview, Thread, ThreadReply, NotificationType,
Permission, AuditSeverity, PackageState
from app.tasks.webhooktasks import post_discord_webhook
from app.utils import is_package_page, add_notification, get_int_or_abort, is_yes, is_safe_url, rank_required, \
- add_audit_log, has_blocked_domains
+ add_audit_log, has_blocked_domains, should_return_json
from . import bp
@@ -178,18 +179,16 @@ def delete_review(package, reviewer):
return redirect(thread.get_view_url())
-def handle_review_vote(package: Package, review_id: int):
+def handle_review_vote(package: Package, review_id: int) -> typing.Optional[str]:
if current_user in package.maintainers:
- flash(gettext("You can't vote on the reviews on your own package!"), "danger")
- return
+ return gettext("You can't vote on the reviews on your own package!")
review: PackageReview = PackageReview.query.get(review_id)
if review is None or review.package != package:
abort(404)
if review.author == current_user:
- flash(gettext("You can't vote on your own reviews!"), "danger")
- return
+ return gettext("You can't vote on your own reviews!")
is_positive = is_yes(request.form["is_positive"])
@@ -213,7 +212,15 @@ def handle_review_vote(package: Package, review_id: int):
@login_required
@is_package_page
def review_vote(package, review_id):
- handle_review_vote(package, review_id)
+ msg = handle_review_vote(package, review_id)
+ if should_return_json():
+ if msg:
+ return jsonify({"success": False, "error": msg}), 403
+ else:
+ return jsonify({"success": True})
+
+ if msg:
+ flash(msg, "danger")
next_url = request.args.get("r")
if next_url and is_safe_url(next_url):
diff --git a/app/public/static/js/quick_review_voting.js b/app/public/static/js/quick_review_voting.js
index 5ad364dd..970bad07 100644
--- a/app/public/static/js/quick_review_voting.js
+++ b/app/public/static/js/quick_review_voting.js
@@ -41,11 +41,24 @@ async function submitForm(form, is_helpful) {
body: data,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
+ "Accept": "application/json",
},
});
if (!res.ok) {
- console.error(await res.text());
+ const json = await res.json();
+ alert(json.error ?? "Unknown server error");
+ }
+}
+
+
+function setButtonSelected(ele, isSelected) {
+ if (isSelected) {
+ ele.classList.add("btn-primary");
+ ele.classList.remove("btn-secondary");
+ } else {
+ ele.classList.add("btn-secondary");
+ ele.classList.remove("btn-primary");
}
}
@@ -61,15 +74,16 @@ window.addEventListener("load", () => {
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);
+ setButtonSelected(not_selected, false);
}
- selected.classList.add("btn-primary");
- selected.classList.remove("btn-secondary");
- not_selected.classList.add("btn-secondary");
- not_selected.classList.remove("btn-primary");
+ if (selected.classList.contains("btn-secondary")) {
+ setVoteCount(selected, getVoteCount(selected) + 1);
+ setButtonSelected(selected, true);
+ } else if (selected.classList.contains("btn-primary")) {
+ setVoteCount(selected, Math.max(getVoteCount(selected) - 1, 0));
+ setButtonSelected(selected, false);
+ }
submitForm(helpful_form, is_helpful).catch(console.error);
}
diff --git a/app/templates/index.html b/app/templates/index.html
index e8238efc..89fa4665 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -22,7 +22,7 @@
}
{% if current_user.is_authenticated %}
-
+
{% endif %}
{% endblock %}
diff --git a/app/templates/packages/reviews_list.html b/app/templates/packages/reviews_list.html
index aee08f64..1975dd7f 100644
--- a/app/templates/packages/reviews_list.html
+++ b/app/templates/packages/reviews_list.html
@@ -6,7 +6,7 @@
{% block scriptextra %}
{% if current_user.is_authenticated %}
-
+
{% endif %}
{% endblock %}
diff --git a/app/templates/packages/view.html b/app/templates/packages/view.html
index 1ebc773c..ff7b49f0 100644
--- a/app/templates/packages/view.html
+++ b/app/templates/packages/view.html
@@ -21,7 +21,7 @@
{% if current_user.is_authenticated %}
-
+
{% endif %}
{% endblock %}
diff --git a/app/templates/threads/view.html b/app/templates/threads/view.html
index 5d8114e8..391552a2 100644
--- a/app/templates/threads/view.html
+++ b/app/templates/threads/view.html
@@ -27,7 +27,7 @@
{% block scriptextra %}
{% if current_user.is_authenticated %}
-
+
{% endif %}
{% endblock %}
diff --git a/app/templates/users/profile.html b/app/templates/users/profile.html
index cdb7f1fc..469799ea 100644
--- a/app/templates/users/profile.html
+++ b/app/templates/users/profile.html
@@ -10,7 +10,7 @@
{% block scriptextra %}
{% if current_user.is_authenticated %}
-
+
{% endif %}
{% endblock %}