Compare commits

...

1 Commits

Author SHA1 Message Date
d08d8ca4d5 added message ids, quoting, quotelink scrolling/previews 2018-07-21 23:00:08 -04:00
8 changed files with 139 additions and 28 deletions

View File

@ -90,16 +90,12 @@ def verify_username(username):
return False return False
def log_chat_message(data): def log_chat_message(message, date, room_id, user_id):
""" """
Logs chat messages into the database. Logs chat messages into the database.
'data' should be a dict containing: message, date, room_id, name, and 'data' should be a dict containing: message, date, room_id, name, and
user_id (optional). user_id (optional).
""" """
message = data["message"]
date = data["date"]
room_id = data["room"]
user_id = data.get("user_id")
_DB.execute( _DB.execute(
"INSERT INTO `chat_messages` (" \ "INSERT INTO `chat_messages` (" \
+ "`message`, `room_id`, `date`, `name_id`) VALUES (" \ + "`message`, `room_id`, `date`, `name_id`) VALUES (" \

View File

@ -53,39 +53,52 @@ def message(data):
""" """
Sent by a client when the user entered a new message. Sent by a client when the user entered a new message.
""" """
room = int(data["room"]) room = data["room"]
message = data["message"] message = data["message"]
name = data["name"] name = data["name"]
user_id = data.get("user_id") user_id = data.get("user_id")
data = {}
date = int(time.time())
data["date"] = date
data["name"] = name
data["user_id"] = user_id
data["room"] = room
message = message.strip() message = message.strip()
if not message: if not message:
return return
tags = ["b", "code", "i", "s"] tags = ["b", "code", "i", "s"]
message = bleach.clean(message, tags=tags) message = bleach.clean(message, tags=tags)
lines = [] lines = []
for line in message.splitlines(): for line in message.splitlines():
if line.startswith(">"): if line.startswith(">") and not line.startswith(">>"):
line = '<span class="greenText">' + line + '</span>' line = '<span class="greenText">' + line + '</span>'
lines.append(line) lines.append(line)
message = "<br />".join(lines) message = "<br />".join(lines)
quotes = re.findall(r"&gt;&gt;\d+", message)
for quote in quotes:
msg_id = quote.replace("&gt;&gt;", "")
msg = '<a class="quotelink" '
msg += 'href="javascript:scrollToMsg(\'' + msg_id + '\')" '
msg += 'onmousemove="showPreview(event, \'' + msg_id + '\')" '
msg += 'onmouseout="clearPreview()">' + quote + '</a>'
message = message.replace(quote, msg)
message = tools.handle_img(message) message = tools.handle_img(message)
data["message"] = message
roll_msg = "" roll_msg = ""
if message.startswith("/dice") or message.startswith("/roll"): if message.startswith("/dice") or message.startswith("/roll"):
roll_msg = handle_dice(data) roll_msg = handle_dice(data)
if roll_msg: if roll_msg:
data["message"] += '<hr class="msgSrvHr" /><b>' + roll_msg + "</b>" roll_msg += '<hr class="msgSrvHr" /><b>' + roll_msg + "</b>"
message_id = db.log_chat_message(data) date = int(time.time())
message_id = db.log_chat_message(message, date, room, user_id)
if roll_msg:
message += roll_msg
data = {}
data["date"] = date
data["name"] = name
data["user_id"] = user_id
data["message"] = message
data["message_id"] = message_id
emit("message", data, room=room) emit("message", data, room=room)
if roll_msg: if roll_msg:

View File

@ -183,7 +183,7 @@ h3 {
flex: 1; flex: 1;
} }
.message { .messageContent {
width: 100%; width: 100%;
word-wrap: break-word; word-wrap: break-word;
} }
@ -210,6 +210,19 @@ h3 {
box-sizing: border-box; box-sizing: border-box;
} }
#preview {
display: block;
position: fixed;
background: white;
word-wrap: break-word;
border: 1px solid #ccc;
padding: 0.25em;
}
.greenText { .greenText {
color: green; color: green;
} }
.quotelink {
color: red;
}

View File

@ -10,9 +10,11 @@ var tid = setInterval( function () {
socket.emit('joined', {room: room_id}); socket.emit('joined', {room: room_id});
}); });
socket.on('message', function(data) { socket.on('message', function(data) {
let msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> '; let msg_str = '<div id="msg-' + data.message_id + '" class="message">';
msg_str += '<span class="messageDate">' + strftime(data.date) + '</span></div>'; msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> ';
msg_str += '<div class="message">' + data.message + '</div><hr>'; msg_str += '<span class="messageDate">' + strftime(data.date) + '</span> ';
msg_str += '<span class="messageID">No.<a href="javascript:quote(' + data.message_id + ')">' + data.message_id + '</a></span></div>';
msg_str += '<div class="messageContent">' + data.message + '</div></div><hr>';
let mbox = document.getElementById('chatWindow'); let mbox = document.getElementById('chatWindow');
mbox.innerHTML = mbox.innerHTML + msg_str; mbox.innerHTML = mbox.innerHTML + msg_str;
@ -170,6 +172,33 @@ function submitWritein(post_id) {
if (!option_text) { return; } if (!option_text) { return; }
socket.emit('write_in', {option_text: option_text, post_id: post_id, room: room_id}); socket.emit('write_in', {option_text: option_text, post_id: post_id, room: room_id});
} }
function quote(message_id) {
let textbox = document.getElementById('messageTextArea');
textbox.value += '>>' + message_id + '\n';
textbox.focus();
}
function scrollToMsg(message_id) {
let elem = document.getElementById('msg-' + message_id);
if (!elem) { return; }
elem.scrollIntoView();
}
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 deactivate_post() { function deactivate_post() {
let post = document.getElementsByClassName('active_post'); let post = document.getElementsByClassName('active_post');
if (post.length == 0) { return; } if (post.length == 0) { return; }

View File

@ -10,9 +10,11 @@ var tid = setInterval( function () {
socket.emit('joined', {room: room_id}); socket.emit('joined', {room: room_id});
}); });
socket.on('message', function(data) { socket.on('message', function(data) {
let msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> '; let msg_str = '<div id="msg-' + data.message_id + '" class="message">';
msg_str += '<span class="messageDate">' + strftime(data.date) + '</span></div>'; msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> ';
msg_str += '<div class="message">' + data.message + '</div><hr>'; msg_str += '<span class="messageDate">' + strftime(data.date) + '</span> ';
msg_str += '<span class="messageID">No.<a href="javascript:quote(' + data.message_id + ')">' + data.message_id + '</a></span></div>';
msg_str += '<div class="messageContent">' + data.message + '</div></div><hr>';
let mbox = document.getElementById('chatWindow'); let mbox = document.getElementById('chatWindow');
mbox.innerHTML = mbox.innerHTML + msg_str; mbox.innerHTML = mbox.innerHTML + msg_str;
@ -156,6 +158,33 @@ function submitWritein(post_id) {
if (!option_text) { return; } if (!option_text) { return; }
socket.emit('write_in', {option_text: option_text, post_id: post_id, room: room_id}); socket.emit('write_in', {option_text: option_text, post_id: post_id, room: room_id});
} }
function quote(message_id) {
let textbox = document.getElementById('messageTextArea');
textbox.value += '>>' + message_id + '\n';
textbox.focus();
}
function scrollToMsg(message_id) {
let elem = document.getElementById('msg-' + message_id);
if (!elem) { return; }
elem.scrollIntoView();
}
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 deactivate_post() { function deactivate_post() {
let post = document.getElementsByClassName('active_post'); let post = document.getElementsByClassName('active_post');
if (post.length == 0) { return; } if (post.length == 0) { return; }

View File

@ -139,11 +139,13 @@
<div id="chatWindow"> <div id="chatWindow">
{% autoescape false %} {% autoescape false %}
{% for message in messages %} {% for message in messages %}
<div class="message"> <div id="msg-{{ message[0] }}" class="message">
<div class="messageHeader"> <div class="messageHeader">
<span class="messageName">Anonymous</span> <span class="messageDate">{{ message[3] | strftime }}</span> <span class="messageName">Anonymous</span>
<span class="messageDate">{{ message[3] | strftime }}</span>
<span class="messageID">No.<a href="javascript:quote('{{ message[0] }}')">{{ message[0] }}</a></span>
</div> </div>
<div class="messageMessage">{{ message[4] }}</div> <div class="messageContent">{{ message[4] }}</div>
</div> </div>
<hr> <hr>
{% endfor %} {% endfor %}
@ -152,4 +154,5 @@
<div id="messageTextDiv"><textarea id="messageTextArea"></textarea></div> <div id="messageTextDiv"><textarea id="messageTextArea"></textarea></div>
</div> </div>
</div> </div>
<div id="preview"></div>
{% endblock %} {% endblock %}

29
todo Normal file
View File

@ -0,0 +1,29 @@
New Features:
Pages/appendixes
Live indicator/countdown
Notifications
Anonymous names
Banner images
Search page
Front page to show new quests
Webm posting
Chat message quoting
(you) counter
Enable namefagging
Account managament/logout
Display profile link in header bar
Tagging system
Improvements:
Revamp post editing
More options for text posts (lists and so on)
More rigorous input checking in events.py
New post displays chat message
New chat message doesn't take chat window to the bottom if it was scrolled up
Record email on signup
Change urls
Poll vote highlights entire option
Poll vote doesn't disappear checkbox
Total voters per poll
Chat archives
Only last 100 (50?) chat messages are loaded on page load

View File

@ -208,5 +208,4 @@ def index():
""" """
The index page. The index page.
""" """
print(request.remote_addr)
return render_template("index.html") return render_template("index.html")