summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2016-06-02 19:44:44 +0200
committerschneefux <schneefux+commit@schneefux.xyz>2016-06-02 19:44:44 +0200
commit27c106730f8be6f2f09d1cd6bc554bae70fdc252 (patch)
tree5d7d66bf57ab85da18698ed48b07fca253a35913
parent5d1ed334512c4b0229f845cf8792080c79a8c792 (diff)
downloadjokevote-27c106730f8be6f2f09d1cd6bc554bae70fdc252.tar.gz
jokevote-27c106730f8be6f2f09d1cd6bc554bae70fdc252.zip
allow users to undo a vote
-rw-r--r--app.py19
-rw-r--r--templates/index.html38
2 files changed, 42 insertions, 15 deletions
diff --git a/app.py b/app.py
index 6ef447e..2a8aa6d 100644
--- a/app.py
+++ b/app.py
@@ -127,7 +127,9 @@ class dbProxy(object):
ret_joke = {
'id': joke['id'],
}
- ret_joke['locked'] = not self.c.execute("SELECT COUNT(*) FROM v1_votes WHERE joke=? AND user=?", (joke['id'], user)).fetchone()['COUNT(*)'] == 0
+ ret_joke['upvoted'] = not self.c.execute("SELECT COUNT(*) FROM v1_votes WHERE joke=? AND user=? AND type='up'", (joke['id'], user)).fetchone()['COUNT(*)'] == 0
+ ret_joke['downvoted'] = not self.c.execute("SELECT COUNT(*) FROM v1_votes WHERE joke=? AND user=? AND type='down'", (joke['id'], user)).fetchone()['COUNT(*)'] == 0
+ ret_joke['reported'] = not self.c.execute("SELECT COUNT(*) FROM v1_votes WHERE joke=? AND user=? AND type='report'", (joke['id'], user)).fetchone()['COUNT(*)'] == 0
ret_joke['mine'] = joke['user'] == user
if joke['format'] == 'markdown':
ret_joke['text'] = Markup(markdown.markdown(joke['text'], extensions=['markdown.extensions.nl2br'], output_format="html5", safe_mode="remove")) # TODO safe_mode deprecated
@@ -173,6 +175,11 @@ class dbProxy(object):
self.c.execute("INSERT INTO v1_votes(joke, user, type) VALUES(?, ?, ?)", (objectId, user, 'down' if down else 'up'))
self.conn.commit()
+ def unvoteJoke(self, objectId, ip):
+ user = self.userByIp(ip)
+ self.c.execute("DELETE FROM v1_votes WHERE joke=? AND user=?", (objectId, user))
+ self.conn.commit()
+
def reportJoke(self, objectId, ip):
user = self.userByIp(ip)
self.c.execute("INSERT INTO v1_votes(joke, user, type) VALUES(?, ?, 'report')", (objectId, user))
@@ -231,8 +238,9 @@ def vote():
objectId = int(request.form['id'])
page = request.form['redirpage']
ip = request.remote_addr
- if objectId not in db().getUserVotes(ip):
- db().voteJoke(objectId, request.form['vote'] == 'downvote', ip)
+ if objectId in db().getUserVotes(ip):
+ db().unvoteJoke(objectId, ip)
+ db().voteJoke(objectId, request.form['vote'] == 'downvote', ip)
return redirect('/page/' + page)
@app.route('/report', methods=['POST'])
@@ -240,8 +248,9 @@ def report():
objectId = int(request.form['id'])
page = request.form['redirpage']
ip = request.remote_addr
- if objectId not in db().getUserVotes(ip):
- db().reportJoke(objectId, ip)
+ if objectId in db().getUserVotes(ip):
+ db().unvoteJoke(objectId, ip)
+ db().reportJoke(objectId, ip)
return redirect('/page/' + page)
@app.route('/delete', methods=['POST'])
diff --git a/templates/index.html b/templates/index.html
index 866b1d3..d04f471 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -20,13 +20,17 @@
<form action="/vote" method="post" class="voteform">
<input type="hidden" name="id" value="{{ joke.id }}">
<input type="hidden" name="redirpage" value="{{ currentpage }}">
- <button class="upvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.locked %} disabled{% endif %} col s12" type="submit" name="vote" value="upvote"><i class="material-icons">thumb_up</i> <span class="btnval">{{ joke.upvotes }}</span></button>
- <button class="downvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.locked %} disabled{% endif %} col s12" type="submit" name="vote" value="downvote"><i class="material-icons">thumb_down</i> <span class="btnval">{{ joke.downvotes }}</span></button>
+ <button class="upvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.upvoted %} disabled{% endif %} col s12" type="submit" name="vote" value="upvote">
+ <i class="material-icons">thumb_up</i> <span class="btnval" data-original="{% if joke.upvoted %}{{ joke.upvotes-1 }}{% else %}{{ joke.upvotes }}{% endif %}">{{ joke.upvotes }}</span>
+ </button>
+ <button class="downvotebtn btn{% if joke.reports>0 %}-flat{% endif %}{% if joke.downvoted %} disabled{% endif %} col s12" type="submit" name="vote" value="downvote">
+ <i class="material-icons">thumb_down</i> <span class="btnval" data-original="{% if joke.downvoted %}{{ joke.downvotes-1 }}{% else %}{{ joke.downvotes }}{% endif %}">{{ joke.downvotes }}</span>
+ </button>
</form>
<form action="/report" method="post">
<input type="hidden" name="id" value="{{ joke.id }}">
<input type="hidden" name="redirpage" value="{{ currentpage }}">
- <button class="btn-flat{% if joke.locked %} disabled{% endif %} col s12" type="submit">
+ <button class="btn-flat col s12{% if joke.reported %} disabled{% endif %}" type="submit">
{% if joke.reports>0 %}
<div class="row">
<i class="material-icons col s6">report_problem</i>
@@ -79,23 +83,37 @@
</div>
<script type="text/javascript">
$(document).ready(function() {
- $('.upvotebtn').click(function(e) { submitAjaxer.call(this, e, 'vote', 'upvote'); });
- $('.downvotebtn').click(function(e) { submitAjaxer.call(this, e, 'vote', 'downvote'); });
+ $('.upvotebtn').click(function(e) { submitAjaxer.call(this, e, 'upvote'); });
+ $('.downvotebtn').click(function(e) { submitAjaxer.call(this, e, 'downvote'); });
- function submitAjaxer(e, name, value) {
+ function submitAjaxer(e, type) {
e.preventDefault();
- if ($(this).hasClass('disabled')) { return; }
var form = $(this).closest('form');
var joke = $(this).closest('.joke');
$.ajax({
url: form.attr('action'),
type: "POST",
- data: form.serialize() + '&' + name + '=' + value,
+ data: form.serialize() + '&vote=' + type,
success: function(data) {
- $('button', joke).addClass('disabled');
+ var upvotebtn = $('.upvotebtn .btnval', form).first();
+ var downvotebtn = $('.downvotebtn .btnval', form).first();
+ var upvotes = parseInt(upvotebtn.data('original'));
+ var downvotes = parseInt(downvotebtn.data('original'));
+ upvotebtn.text();
+ downvotebtn.text(downvotebtn.data('original'));
+ upvotebtn.parent().removeClass('disabled');
+ downvotebtn.parent().removeClass('disabled');
+ upvotebtn.text(upvotes);
+ downvotebtn.text(downvotes);
+ if (type == "upvote") {
+ upvotebtn.text(upvotes+1);
+ upvotebtn.parent().addClass('disabled');
+ } else if (type == "downvote") {
+ downvotebtn.text(downvotes+1);
+ downvotebtn.parent().addClass('disabled');
+ }
}
});
- $('.btnval', $(this)).text(parseInt($('.btnval', $(this)).text())+1);
}
});
</script>