summaryrefslogtreecommitdiff
path: root/forum/forum.ur
diff options
context:
space:
mode:
Diffstat (limited to 'forum/forum.ur')
-rw-r--r--forum/forum.ur27
1 files changed, 22 insertions, 5 deletions
diff --git a/forum/forum.ur b/forum/forum.ur
index 3081e7d..23bbbd5 100644
--- a/forum/forum.ur
+++ b/forum/forum.ur
@@ -70,16 +70,32 @@ fun recordVote (value : Score.score) (entryId : int) _formData : transaction pag
in the first place. *)
let val author = Author.nameError authorOpt
in
- alreadyVoted <- hasRows (SELECT Vote.Value FROM vote
- WHERE Vote.QuestionId = {[entryId]}
- AND Vote.Author = {[author]});
- unless alreadyVoted (dml (INSERT INTO vote (QuestionId, Author, Value)
- VALUES ({[entryId]}, {[author]}, {[value]})));
+ existingVote <- oneOrNoRows1 (SELECT Vote.Value FROM vote
+ WHERE Vote.QuestionId = {[entryId]}
+ AND Vote.Author = {[author]});
+ (* This mimics Reddit's upvote/downvote behavior, which is a bizarrely
+ complex state machine that is nonetheless totally intuitive, especially
+ when you're using an AJAXy interface. TODO: Write an AJAXy
+ interface. *)
+ (case existingVote of
+ None => dml (INSERT INTO vote (QuestionId, Author, Value)
+ VALUES ({[entryId]}, {[author]}, {[value]}))
+ | Some v =>
+ if v.Value = value
+ then dml (DELETE FROM vote
+ WHERE QuestionId = {[entryId]}
+ AND Author = {[author]})
+ else dml (UPDATE vote
+ SET Value = {[value]}
+ WHERE QuestionId = {[entryId]}
+ AND Author = {[author]}));
detail entryId
end
and upvote entryId _formData = recordVote Score.insightful entryId _formData
+and downvote entryId _formData = recordVote Score.inane entryId _formData
+
(***************************** Single questions ******************************)
@@ -111,6 +127,7 @@ and detail (id : int) : transaction page =
{Author.whenIdentified authorOpt
<xml>
<form class={voting}><submit action={upvote id} value="⬆" /></form>
+ <form class={voting}><submit action={downvote id} value="⬇" /></form>
</xml>}
<div>{answerBlock}</div>