diff --git a/quest/consumers.py b/quest/consumers.py
index cd8799c..926b8ad 100644
--- a/quest/consumers.py
+++ b/quest/consumers.py
@@ -65,6 +65,14 @@ class QuestConsumer(WebsocketConsumer):
'message': data
}
)
+
+ def self_send(self, event, data={}):
+ """
+ Like `send`, except only sends events to the paired websocket
+ instead of the entire group.
+ """
+ data = json.dumps({'event': event, 'data': data})
+ self.dispatch_send({'message': data})
def dispatch_send(self, event):
"""
diff --git a/quest/events.py b/quest/events.py
index c6212f6..d5ef839 100644
--- a/quest/events.py
+++ b/quest/events.py
@@ -4,6 +4,7 @@ Individual functions for handling WebSocket events. Gets called by the
QuestConsumer object in consumers.py.
"""
# TODO: quest owner only events
+# TODO: try/except on database calls
import re
import time
import types
@@ -43,9 +44,9 @@ def message(socket, data):
for quote in quotes:
msg_id = quote.replace(">>", "")
msg = '' + quote + ''
+ msg += 'href="javascript:scroll_to_msg(\'' + msg_id + '\')" '
+ msg += 'onmousemove="show_preview(event, \'' + msg_id + '\')" '
+ msg += 'onmouseout="clear_preview()">' + quote + ''
message = message.replace(quote, msg)
# handle image
@@ -255,7 +256,7 @@ def poll_post(socket, data):
data['post_id'] = p.id
data['post_text'] = "Poll"
data['date'] = localtime(p.timestamp).strftime('%Y-%m-%d %H:%M')
- data['options'] = [o.text for o in options]
+ data['options'] = [(o.id, o.text) for o in options]
socket.send('new_post', data)
@@ -305,6 +306,49 @@ def open_post(socket, data):
socket.send('open_post', data)
+def vote(socket, data):
+ """
+ Called when a player votes in a poll.
+ """
+ quest_id = data.get('quest_id')
+ post_id = data.get('post_id')
+ option_id = data.get('option_id')
+ polarity = data.get('polarity')
+ ip_address = socket.scope['client'][0]
+ user = socket.scope['user']
+
+ if polarity == False:
+ v = PollVote.objects.get(ip_address=ip_address, option__id=option_id)
+ v.delete()
+ else:
+ p = Poll.objects.get(post_id=post_id)
+ if p.multi_choice == False:
+ votes = PollVote.objects.filter(
+ ip_address=ip_address,
+ option__poll=p
+ )
+ for vote in votes:
+ vote.delete()
+
+ data = {}
+ data['option_id'] = vote.option.id
+ data['polarity'] = False
+ socket.send('vote', data)
+ socket.self_send('set_option_box', data)
+ v = PollVote(
+ option=PollOption.objects.get(id=option_id),
+ ip_address=ip_address
+ )
+ if user.username:
+ v.user = user
+ v.save()
+
+ data = {}
+ data['option_id'] = option_id
+ data['polarity'] = polarity
+ socket.send('vote', data)
+
+
events = {}
for obj in dir():
if type(locals()[obj]) == types.FunctionType:
diff --git a/quest/jinja2/quest/quest.html b/quest/jinja2/quest/quest.html
index 90d2df8..bd93db4 100644
--- a/quest/jinja2/quest/quest.html
+++ b/quest/jinja2/quest/quest.html
@@ -68,14 +68,14 @@
{% elif post.post_type == "poll" %}
@@ -130,8 +130,8 @@
';
- post_str += '
';
- for (i = 0; i < data.options.length; i++) {
- post_str += '
';
- post_str += '';
+ for (let i = 0; i < data.options.length; i++) {
+ post_str += ' |
';
+ post_str += '';
post_str += ' | ';
post_str += '' + data.options[i][1] + ' | ';
post_str += '0 |
';
@@ -105,7 +103,7 @@ socket.events['update_post'] = function(data) {
let row = post.children[1].insertRow(-1);
let cell = row.insertCell(0);
cell.className = 'pollCheckBox';
- cell.innerHTML = '
';
+ cell.innerHTML = '
';
cell.innerHTML += '
';
cell = row.insertCell(1);
@@ -117,6 +115,31 @@ socket.events['update_post'] = function(data) {
cell.innerHTML = "0";
}
}
+socket.events['vote'] = function(data) {
+ let row = document.getElementById('optionRow-' + data.option_id);
+ if (data.polarity) {
+ row.cells[2].textContent = Number(row.cells[2].textContent) + 1;
+ } else {
+ row.cells[2].textContent = Number(row.cells[2].textContent) - 1;
+ }
+ let table = row.parentElement.parentElement;
+ arr = Array.prototype.slice.call(table.rows);
+ arr.sort(sort_by_votes);
+ let new_tbody = document.createElement('tbody');
+ for (let i = 0; i < arr.length; i++) {
+ new_tbody.appendChild(arr[i]);
+ }
+ table.replaceChild(new_tbody, table.children[0]);
+}
+socket.events['set_option_box'] = function(data) {
+ document.getElementById('pollInput-' + data.option_id).checked = data.polarity;
+}
+
+/* Websocket send */
+function vote(post_id, option_id) {
+ let polarity = document.getElementById('pollInput-' + option_id).checked;
+ socket.send('vote', {post_id: post_id, option_id: option_id, polarity: polarity, quest_id: quest_id});
+}
/* Helpers */
function padToTwo(number) {
@@ -129,6 +152,9 @@ function strftime(date) {
date_str += padToTwo(date.getHours()) + ':' + padToTwo(date.getMinutes()) + ':' + padToTwo(date.getSeconds());
return date_str;
}
+function sort_by_votes(a, b) {
+ return b.cells[2].textContent.localeCompare(a.cells[2].textContent);
+}
/* DOM editing */
function quote(message_id) {
@@ -136,7 +162,7 @@ function quote(message_id) {
textbox.value += '>>' + message_id + '\n';
textbox.focus();
}
-function showPreview(event, message_id) {
+function show_preview(event, message_id) {
let elem = document.getElementById('msg-' + message_id);
if (!elem) { return; }
let preview = document.getElementById('preview');
@@ -149,11 +175,11 @@ function showPreview(event, message_id) {
preview.style.left = x;
preview.style.maxWidth = maxWidth;
}
-function clearPreview() {
+function clear_preview() {
document.getElementById('preview').innerHTML = '';
document.getElementById('preview').style.display = 'none';
}
-function scrollToMsg(message_id) {
+function scroll_to_msg(message_id) {
let elem = document.getElementById('msg-' + message_id);
if (!elem) { return; }
elem.scrollIntoView();
diff --git a/quest/static/questQM.js b/quest/static/questQM.js
index b2a4698..c65d1a7 100644
--- a/quest/static/questQM.js
+++ b/quest/static/questQM.js
@@ -1,6 +1,5 @@
/* Websocket receive */
socket.events['new_post'] = function(data) {
- //deactivate_post();
let qposts = document.getElementById('questPosts');
let post_str = '
';
- post_str += '
';
for (i = 0; i < data.options.length; i++) {
post_str += '';
- post_str += '';
+ post_str += ' | ';
post_str += ' | ';
post_str += '' + data.options[i][1] + ' | ';
post_str += '0 |
';
diff --git a/quest/views.py b/quest/views.py
index fb58656..509fb01 100644
--- a/quest/views.py
+++ b/quest/views.py
@@ -25,5 +25,6 @@ def quest(request, quest_id, page_num=1):
dice_rolls = DiceRoll.objects.filter(dicecall__post__quest__id=quest_id)
poll_options = PollOption.objects.filter(poll__post__quest__id=quest_id)
poll_votes = PollVote.objects.filter(option__poll__post__quest__id=quest_id)
+ ip_address = request.META['REMOTE_ADDR']
context = locals()
return render(request, 'quest/quest.html', context)