diff --git a/quest/events.py b/quest/events.py index 6d27439..eea96b3 100644 --- a/quest/events.py +++ b/quest/events.py @@ -3,6 +3,7 @@ Individual functions for handling WebSocket events. Gets called by the QuestConsumer object in consumers.py. """ +import re import time import types @@ -23,6 +24,23 @@ def message(socket, data): return tags = ["b", "code", "i", "s"] message = bleach.clean(message, tags=tags) + + lines = [] + for line in message.splitlines(): + if line.startswith(">") and not line.startswith(">>"): + line = '' + line + '' + lines.append(line) + message = "
".join(lines) + + quotes = re.findall(r">>\d+", message) + for quote in quotes: + msg_id = quote.replace(">>", "") + msg = '' + message = message.replace(quote, msg) + user = socket.scope['user'] m = Message( diff --git a/quest/jinja2/quest/quest.html b/quest/jinja2/quest/quest.html index f56aab5..ffb1d0b 100644 --- a/quest/jinja2/quest/quest.html +++ b/quest/jinja2/quest/quest.html @@ -145,7 +145,7 @@
{{ message.user.username or 'Anonymous' }} {{ localtime(message.timestamp).strftime('%Y-%m-%d %H:%M:%S') }} - No.{{ message.id }} + No.{{ message.id }}
{{ message.message }}
diff --git a/quest/static/quest.js b/quest/static/quest.js index 4d4d080..a859fcd 100644 --- a/quest/static/quest.js +++ b/quest/static/quest.js @@ -1,3 +1,4 @@ +/* House keeping */ var socket = new WebSocket('wss://' + document.domain + SCRIPT_NAME + '/ws/quest/' + quest_id + '/'); socket.oldSend = socket.send; socket.send = function(event_title, data) { @@ -12,7 +13,21 @@ socket.onmessage = function(e) { if (socket.events[event] === undefined) { return; } socket.events[event](data); } +function load() { + document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; + let mtarea = document.getElementById('messageTextArea'); + mtarea.addEventListener('keypress', function(event) { + if (event.key == 'Enter' && !event.shiftKey) { + let text = mtarea.value.trim(); + mtarea.value = ''; + if (text == '') { return; } + document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; + socket.send('message', {message: text, quest_id: quest_id}); + } + }); +} +/* Websocket events */ socket.events['message'] = function(data) { let msg_str = '
'; msg_str = '
' + data.name + ' '; @@ -27,6 +42,7 @@ socket.events['message'] = function(data) { } } +/* Helpers */ function padToTwo(number) { if (number<=99) { number = ("0"+number).slice(-2); } return number; @@ -38,16 +54,31 @@ function strftime(date) { return date_str; } -function load() { - document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; - let mtarea = document.getElementById('messageTextArea'); - mtarea.addEventListener('keypress', function(event) { - if (event.key == 'Enter' && !event.shiftKey) { - let text = mtarea.value.trim(); - mtarea.value = ''; - if (text == '') { return; } - document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight; - socket.send('message', {message: text, quest_id: quest_id}); - } - }); +/* User-facing */ +function quote(message_id) { + let textbox = document.getElementById('messageTextArea'); + textbox.value += '>>' + message_id + '\n'; + textbox.focus(); +} +function showPreview(event, message_id) { + let elem = document.getElementById('msg-' + message_id); + if (!elem) { return; } + let preview = document.getElementById('preview'); + preview.innerHTML = elem.innerHTML; + preview.style.display = ''; + let x = event.clientX + 20 + 'px'; + let y = event.clientY + 20 + 'px'; + let maxWidth = window.innerWidth - event.clientX - 80 + 'px'; + preview.style.top = y; + preview.style.left = x; + preview.style.maxWidth = maxWidth; +} +function clearPreview() { + document.getElementById('preview').innerHTML = ''; + document.getElementById('preview').style.display = 'none'; +} +function scrollToMsg(message_id) { + let elem = document.getElementById('msg-' + message_id); + if (!elem) { return; } + elem.scrollIntoView(); }