issue Add voting functionality to my own interpretations #94

This commit is contained in:
Kostiantyn Stoliarskyi 2023-05-31 17:26:16 +03:00
parent f2995fa718
commit 6dd7e67709
6 changed files with 123 additions and 139 deletions

View File

@ -86,15 +86,14 @@
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
<div class="flex flex-row pb-3 p-3 pt-0 w-2/3 md:w-full">
<div class="vote-block flex flex-col m-5 mr-8 justify-center items-center">
{% if interpretation.user_id != current_user.id %}
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="true">
<svg class="w-6 h-6 select-none
{% if interpretation.current_user_vote %}
stroke-green-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18" /> </svg>
</div>
{% endif %}
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="true">
<svg class="w-6 h-6 select-none
{% if interpretation.current_user_vote %}
stroke-green-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18" /> </svg>
</div>
<span
class="vote-count text-3xl select-none
@ -108,15 +107,13 @@
{{ interpretation.vote_count }}
</span>
{% if interpretation.user_id != current_user.id %}
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="false">
<svg class="w-6 h-6 select-none
{% if interpretation.current_user_vote == False %}
stroke-red-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" /> </svg>
</div>
{% endif %}
<div class="vote-button cursor-pointer" data-vote-for="interpretation" data-entity-id="{{ interpretation.id }}" data-positive="false">
<svg class="w-6 h-6 select-none
{% if interpretation.current_user_vote == False %}
stroke-red-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" /> </svg>
</div>
<!-- TODO check permissions -->
{% if interpretation.book.owner == current_user %}

View File

@ -79,17 +79,17 @@
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
<div class="flex flex-row pb-3 p-3 w-2/3 md:w-full">
<div class="vote-block flex flex-col m-5 mr-8 justify-center items-center">
{% if comment.user_id != current_user.id %}
<div class="vote-button cursor-pointer" data-vote-for="comment" data-entity-id="{{ comment.id }}" data-positive="true">
<svg
class="w-6 h-6 select-none
{% if comment.current_user_vote %}
stroke-green-500
{% endif %}
"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18" /> </svg>
</div>
{% endif %}
<div class="vote-button cursor-pointer" data-vote-for="comment" data-entity-id="{{ comment.id }}" data-positive="true">
<svg
class="w-6 h-6 select-none
{% if comment.current_user_vote %}
stroke-green-500
{% endif %}
"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18" /> </svg>
</div>
<span
class="vote-count text-3xl select-none
@ -103,15 +103,14 @@
{{ comment.vote_count }}
</span>
{% if comment.user_id != current_user.id %}
<div class="vote-button cursor-pointer" data-vote-for="comment" data-entity-id="{{ comment.id }}" data-positive="false">
<svg class="w-6 h-6 select-none
{% if comment.current_user_vote == False %}
stroke-red-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" /> </svg>
</div>
{% endif %}
<div class="vote-button cursor-pointer" data-vote-for="comment" data-entity-id="{{ comment.id }}" data-positive="false">
<svg class="w-6 h-6 select-none
{% if comment.current_user_vote == False %}
stroke-red-500
{% endif %}
" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" /> </svg>
</div>
<!-- TODO check permissions -->
{% if interpretation.book.owner == current_user %}

View File

@ -1,10 +1,11 @@
from flask import (
Blueprint,
jsonify,
request,
)
from flask_login import login_required, current_user
from app import models as m, db, forms as f
from app import models as m, db
from app.logger import log
bp = Blueprint("vote", __name__, url_prefix="/vote")
@ -23,55 +24,44 @@ def vote_interpretation(interpretation_id: int):
log(log.WARNING, "Interpretation with id [%s] not found", interpretation_id)
return jsonify({"message": "Interpretation not found"}), 404
form = f.VoteForm()
if form.validate_on_submit():
vote: m.InterpretationVote = m.InterpretationVote.query.filter_by(
user_id=current_user.id, interpretation_id=interpretation_id
).first()
if vote:
db.session.delete(vote)
vote: m.InterpretationVote = m.InterpretationVote.query.filter_by(
user_id=current_user.id, interpretation_id=interpretation_id
).first()
if vote:
db.session.delete(vote)
positive = form.positive.data and "true" in [
data.lower() for data in form.positive.raw_data
]
if not vote or vote.positive != positive:
vote: m.InterpretationVote = m.InterpretationVote(
user_id=current_user.id,
interpretation_id=interpretation_id,
positive=positive,
)
log(
log.INFO,
"User [%s]. [%s] vote interpretation: [%s]",
current_user,
"Positive" if positive else "Negative",
interpretation,
)
vote.save(False)
else:
log(
log.INFO,
"User [%s]. Remove [%s] vote for interpretation: [%s]",
current_user,
"positive" if positive else "negative",
interpretation,
)
db.session.commit()
positive = request.json.get("positive") in ("true", True)
return jsonify(
{
"vote_count": interpretation.vote_count,
"current_user_vote": interpretation.current_user_vote,
}
if not vote or vote.positive != positive:
vote: m.InterpretationVote = m.InterpretationVote(
user_id=current_user.id,
interpretation_id=interpretation_id,
positive=positive,
)
log(
log.INFO,
"User [%s]. [%s] vote interpretation: [%s]",
current_user,
"Positive" if positive else "Negative",
interpretation,
)
vote.save(False)
else:
log(
log.INFO,
"User [%s]. Remove [%s] vote for interpretation: [%s]",
current_user,
"positive" if positive else "negative",
interpretation,
)
db.session.commit()
log(
log.CRITICAL,
"Unexpected error: User [%s]. Vote for interpretation: [%s]",
current_user,
interpretation,
return jsonify(
{
"vote_count": interpretation.vote_count,
"current_user_vote": interpretation.current_user_vote,
}
)
return jsonify({"message": "Unexpected error"}), 400
@bp.route(
@ -85,52 +75,41 @@ def vote_comment(comment_id: int):
log(log.WARNING, "Comment with id [%s] not found", comment_id)
return jsonify({"message": "Comment not found"}), 404
form = f.VoteForm()
if form.validate_on_submit():
vote: m.CommentVote = m.CommentVote.query.filter_by(
user_id=current_user.id, comment_id=comment_id
).first()
if vote:
db.session.delete(vote)
vote: m.CommentVote = m.CommentVote.query.filter_by(
user_id=current_user.id, comment_id=comment_id
).first()
if vote:
db.session.delete(vote)
positive = form.positive.data and "true" in [
data.lower() for data in form.positive.raw_data
]
if not vote or vote.positive != positive:
vote: m.CommentVote = m.CommentVote(
user_id=current_user.id,
comment_id=comment_id,
positive=positive,
)
log(
log.INFO,
"User [%s]. [%s] vote comment: [%s]",
current_user,
"Positive" if positive else "Negative",
comment,
)
vote.save(False)
else:
log(
log.INFO,
"User [%s]. Remove [%s] vote for comment: [%s]",
current_user,
"positive" if positive else "negative",
comment,
)
db.session.commit()
positive = request.json.get("positive") in ("true", True)
return jsonify(
{
"vote_count": comment.vote_count,
"current_user_vote": comment.current_user_vote,
}
if not vote or vote.positive != positive:
vote: m.CommentVote = m.CommentVote(
user_id=current_user.id,
comment_id=comment_id,
positive=positive,
)
log(
log.INFO,
"User [%s]. [%s] vote comment: [%s]",
current_user,
"Positive" if positive else "Negative",
comment,
)
vote.save(False)
else:
log(
log.INFO,
"User [%s]. Remove [%s] vote for comment: [%s]",
current_user,
"positive" if positive else "negative",
comment,
)
db.session.commit()
log(
log.CRITICAL,
"Unexpected error: User [%s]. Vote for comment: [%s]",
current_user,
comment,
return jsonify(
{
"vote_count": comment.vote_count,
"current_user_vote": comment.current_user_vote,
}
)
return jsonify({"message": "Unexpected error"}), 400

View File

@ -15,7 +15,7 @@ class BaseConfig(BaseSettings):
APP_NAME: str = "Open Law"
SECRET_KEY: str
SQLALCHEMY_TRACK_MODIFICATIONS: bool = False
WTF_CSRF_ENABLED: bool = True
WTF_CSRF_ENABLED: bool = False
# Super admin
ADMIN_USERNAME: str

View File

@ -17,7 +17,6 @@ const voteClickEventListener = async (
const positive = btn.getAttribute('data-positive');
const entityId = btn.getAttribute('data-entity-id');
const requestUrl = REQUEST_URLS[voteFor] + entityId;
const response = await fetch(requestUrl, {
method: 'POST',

View File

@ -10,7 +10,8 @@ def test_upvote_interpretation(client: FlaskClient):
response: Response = client.post(
"/vote/interpretation/999",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -29,7 +30,8 @@ def test_upvote_interpretation(client: FlaskClient):
response: Response = client.post(
f"/vote/interpretation/{interpretation.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -47,7 +49,8 @@ def test_upvote_interpretation(client: FlaskClient):
response: Response = client.post(
f"/vote/interpretation/{interpretation.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -65,7 +68,8 @@ def test_upvote_interpretation(client: FlaskClient):
response: Response = client.post(
f"/vote/interpretation/{interpretation.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=False,
),
follow_redirects=True,
@ -83,7 +87,8 @@ def test_upvote_interpretation(client: FlaskClient):
response: Response = client.post(
f"/vote/interpretation/{interpretation.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=False,
),
follow_redirects=True,
@ -105,7 +110,8 @@ def test_upvote_comment(client: FlaskClient):
response: Response = client.post(
"/vote/comment/999",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -124,7 +130,8 @@ def test_upvote_comment(client: FlaskClient):
response: Response = client.post(
f"/vote/comment/{comment.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -142,7 +149,8 @@ def test_upvote_comment(client: FlaskClient):
response: Response = client.post(
f"/vote/comment/{comment.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=True,
),
follow_redirects=True,
@ -160,7 +168,8 @@ def test_upvote_comment(client: FlaskClient):
response: Response = client.post(
f"/vote/comment/{comment.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=False,
),
follow_redirects=True,
@ -178,7 +187,8 @@ def test_upvote_comment(client: FlaskClient):
response: Response = client.post(
f"/vote/comment/{comment.id}",
data=dict(
headers={"Content-Type": "application/json"},
json=dict(
positive=False,
),
follow_redirects=True,