2018-08-20 07:23:33 -04:00
|
|
|
/* House keeping */
|
2018-08-14 20:12:52 -04:00
|
|
|
var socket = new WebSocket('wss://' + document.domain + SCRIPT_NAME + '/ws/quest/' + quest_id + '/');
|
2018-08-15 17:41:51 -04:00
|
|
|
socket.oldSend = socket.send;
|
|
|
|
socket.send = function(event_title, data) {
|
|
|
|
data = JSON.stringify({event: event_title, data: data});
|
|
|
|
socket.oldSend.apply(this, [data]);
|
|
|
|
}
|
|
|
|
socket.events = {};
|
|
|
|
socket.onmessage = function(e) {
|
|
|
|
let data = JSON.parse(e.data);
|
|
|
|
let event = data.event;
|
|
|
|
data = data.data;
|
|
|
|
if (socket.events[event] === undefined) { return; }
|
|
|
|
socket.events[event](data);
|
|
|
|
}
|
2018-09-10 15:08:14 -04:00
|
|
|
socket.onclose = async function(e) {
|
|
|
|
console.log('WebSocket lost connection to server. Re-trying...');
|
|
|
|
let old_socket = socket;
|
|
|
|
while (true) {
|
|
|
|
await sleep(5000);
|
|
|
|
try {
|
|
|
|
socket = new WebSocket(this.url);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
console.log('WebSocket lost connection to server. Re-trying...');
|
|
|
|
// this still throws an error in the console for some reason
|
|
|
|
}
|
|
|
|
}
|
|
|
|
socket.oldSend = old_socket.oldSend;
|
|
|
|
socket.send = old_socket.send;
|
|
|
|
socket.events = old_socket.events;
|
|
|
|
socket.onmessage = old_socket.onmessage;
|
|
|
|
socket.onclose = old_socket.onclose;
|
|
|
|
}
|
2018-08-20 07:23:33 -04:00
|
|
|
function load() {
|
|
|
|
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
|
|
|
|
let mtarea = document.getElementById('messageTextArea');
|
|
|
|
mtarea.addEventListener('keypress', function(event) {
|
2018-08-24 21:51:03 -04:00
|
|
|
if (event.key === 'Enter' && !event.shiftKey) {
|
2018-08-20 07:23:33 -04:00
|
|
|
let text = mtarea.value.trim();
|
|
|
|
mtarea.value = '';
|
2018-08-24 21:51:03 -04:00
|
|
|
if (text === '') { return; }
|
2018-08-20 07:23:33 -04:00
|
|
|
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
|
|
|
|
socket.send('message', {message: text, quest_id: quest_id});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-08-15 17:41:51 -04:00
|
|
|
|
2018-08-24 17:45:18 -04:00
|
|
|
/* Websocket receive */
|
2018-08-15 17:41:51 -04:00
|
|
|
socket.events['message'] = function(data) {
|
2018-08-16 15:43:43 -04:00
|
|
|
let msg_str = '<div id="message-' + data.message_id + '" class="message">';
|
|
|
|
msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> ';
|
|
|
|
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');
|
|
|
|
mbox.innerHTML = mbox.innerHTML + msg_str;
|
|
|
|
if ((mbox.scrollTop + mbox.offsetHeight) >= (mbox.scrollHeight - mbox.clientHeight / 2)) {
|
|
|
|
mbox.scrollTop = mbox.scrollHeight;
|
|
|
|
}
|
|
|
|
}
|
2018-08-21 09:01:16 -04:00
|
|
|
socket.events['new_post'] = function(data) {
|
|
|
|
let qposts = document.getElementById('questPosts');
|
|
|
|
let post_str = '<div class="questPost ';
|
2018-08-24 21:51:03 -04:00
|
|
|
if (data.post_type === 'text') {
|
2018-08-21 09:01:16 -04:00
|
|
|
post_str += 'textPost">';
|
2018-08-24 21:51:03 -04:00
|
|
|
} else if (data.post_type === 'dice') {
|
2018-08-21 09:01:16 -04:00
|
|
|
post_str += 'dicePost active_post">';
|
2018-08-24 21:51:03 -04:00
|
|
|
} else if (data.post_type === 'poll') {
|
2018-08-21 09:01:16 -04:00
|
|
|
post_str += 'pollPost active_post">';
|
|
|
|
}
|
|
|
|
post_str += '<div class="questPostMeta">' + data.date;
|
|
|
|
post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">';
|
2018-08-24 21:51:03 -04:00
|
|
|
if (data.post_type === 'text') {
|
2018-08-23 07:40:28 -04:00
|
|
|
post_str += data.post_text;
|
2018-08-24 21:51:03 -04:00
|
|
|
} else if (data.post_type === 'dice') {
|
2018-08-23 07:40:28 -04:00
|
|
|
post_str += '<h3>' + data.post_text + ' - Open</h3>';
|
2018-08-24 21:51:03 -04:00
|
|
|
} else if (data.post_type === 'poll') {
|
2018-08-23 07:40:28 -04:00
|
|
|
post_str += '<h3>' + data.post_text + ' - Open</h3>';
|
2018-08-21 09:01:16 -04:00
|
|
|
post_str += '<table class="poll" id="poll-' + data.post_id + '">';
|
2018-09-03 17:59:41 -04:00
|
|
|
for (let i = 0; i < data.options.length; i++) {
|
|
|
|
post_str += '<tr id="optionRow-' + data.options[i] + '">';
|
|
|
|
post_str += '<td class="pollCheckBox"><input type="checkbox" id="pollInput-' + data.options[i][0] + '" onchange="vote(' + data.post_id + ',' + data.options[i][0] + ')"/>';
|
2018-08-21 09:01:16 -04:00
|
|
|
post_str += '<label for="pollInput-' + data.options[i][0] + '"></label></td>';
|
|
|
|
post_str += '<td class="option_text">' + data.options[i][1] + '</td>';
|
|
|
|
post_str += '<td class="optionVotes">0</td></tr>';
|
|
|
|
}
|
|
|
|
post_str += '</table>';
|
|
|
|
if (data.allow_writein) {
|
|
|
|
post_str += '<div id="writeinContainer">';
|
2018-09-05 08:41:53 -04:00
|
|
|
post_str += 'Write-in: <input type="text" id="writeinInput-' + data.post_id + '" placeholder="Custom choice..." maxlength="200" /><br />';
|
|
|
|
post_str += '<input type="submit" id="writeinSubmit-' + data.post_id + '" value="Submit" onclick="submitWritein(' + data.post_id + ');"/></div>';
|
2018-08-21 09:01:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
post_str += '</div></div><br />';
|
|
|
|
qposts.innerHTML = qposts.innerHTML + post_str;
|
|
|
|
};
|
2018-08-24 17:45:18 -04:00
|
|
|
socket.events['close_post'] = function(data) {
|
|
|
|
close_post(data.post_id);
|
|
|
|
}
|
|
|
|
socket.events['open_post'] = function(data) {
|
|
|
|
open_post(data.post_id);
|
|
|
|
}
|
|
|
|
socket.events['close_all_posts'] = function(data) {
|
2018-08-24 18:24:25 -04:00
|
|
|
let class_set = '';
|
2018-08-24 21:51:03 -04:00
|
|
|
if (data.post_type === 'dice') { class_set = 'dicePost activePost'; }
|
|
|
|
else if (data.post_type === 'poll') { class_set = 'pollPost activePost'; }
|
2018-08-24 18:24:25 -04:00
|
|
|
else { class_set = 'activePost'; }
|
|
|
|
let posts = document.getElementsByClassName(class_set);
|
2018-08-24 17:45:18 -04:00
|
|
|
for (let i = 0; i < posts.length; i++) {
|
2018-08-24 18:24:25 -04:00
|
|
|
close_post(posts[i].children[1].id.slice(14)); // retreive the id number at the end
|
2018-08-24 17:45:18 -04:00
|
|
|
}
|
|
|
|
}
|
2018-08-24 21:51:03 -04:00
|
|
|
socket.events['update_post'] = function(data) {
|
|
|
|
let post = document.getElementById('questPostData-' + data.post_id);
|
2018-09-05 08:41:53 -04:00
|
|
|
if (data.post_type === 'text') { // edit post
|
2018-08-24 21:51:03 -04:00
|
|
|
post.innerHTML = data.post_text;
|
2018-09-05 08:41:53 -04:00
|
|
|
} else if (data.post_type === 'dice') { // diceroll
|
2018-08-24 21:51:03 -04:00
|
|
|
post.innerHTML += '<b>' + data.post_text + '</b><br>';
|
2018-09-05 08:41:53 -04:00
|
|
|
} else if (data.post_type === 'poll') { // write-in
|
2018-08-24 21:51:03 -04:00
|
|
|
let row = post.children[1].insertRow(-1);
|
2018-09-05 08:41:53 -04:00
|
|
|
row.id = 'optionRow-' + data.option_id;
|
2018-08-24 21:51:03 -04:00
|
|
|
let cell = row.insertCell(0);
|
|
|
|
cell.className = 'pollCheckBox';
|
2018-09-05 08:41:53 -04:00
|
|
|
cell.innerHTML = '<input type="checkbox" id="pollInput-' + data.option_id + '" onchange="vote(' + data.post_id + ',' + data.option_id + ')"/>';
|
|
|
|
cell.innerHTML += '<label for="pollInput-' + data.option_id + '"></label>';
|
2018-08-24 21:51:03 -04:00
|
|
|
|
|
|
|
cell = row.insertCell(1);
|
|
|
|
cell.className = 'option_text';
|
|
|
|
cell.innerHTML = data.option_text;
|
|
|
|
|
|
|
|
cell = row.insertCell(2);
|
|
|
|
cell.className = "optionVotes";
|
|
|
|
cell.innerHTML = "0";
|
|
|
|
}
|
|
|
|
}
|
2018-09-03 17:59:41 -04:00
|
|
|
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});
|
|
|
|
}
|
2018-09-04 08:30:20 -04:00
|
|
|
function submitWritein(post_id) {
|
2018-09-05 08:41:53 -04:00
|
|
|
let writeinInput = document.getElementById('writeinInput-' + post_id);
|
2018-09-04 08:30:20 -04:00
|
|
|
if (!writeinInput) { return; }
|
|
|
|
let option_text = writeinInput.value;
|
|
|
|
writeinInput.value = '';
|
|
|
|
if (!option_text) { return; }
|
2018-09-05 08:41:53 -04:00
|
|
|
socket.send('write_in', {option_text: option_text, post_id: post_id});
|
2018-09-04 08:30:20 -04:00
|
|
|
}
|
2018-08-16 15:43:43 -04:00
|
|
|
|
2018-08-20 07:23:33 -04:00
|
|
|
/* Helpers */
|
2018-08-16 15:43:43 -04:00
|
|
|
function padToTwo(number) {
|
|
|
|
if (number<=99) { number = ("0"+number).slice(-2); }
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
function strftime(date) {
|
|
|
|
date = new Date(date * 1000);
|
|
|
|
let date_str = date.getFullYear() + '-' + padToTwo(date.getMonth()+1) + '-' + padToTwo(date.getDate()) + ' ';
|
|
|
|
date_str += padToTwo(date.getHours()) + ':' + padToTwo(date.getMinutes()) + ':' + padToTwo(date.getSeconds());
|
|
|
|
return date_str;
|
|
|
|
}
|
2018-09-03 17:59:41 -04:00
|
|
|
function sort_by_votes(a, b) {
|
|
|
|
return b.cells[2].textContent.localeCompare(a.cells[2].textContent);
|
|
|
|
}
|
2018-09-10 15:08:14 -04:00
|
|
|
function sleep(ms) {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
}
|
2018-08-16 15:43:43 -04:00
|
|
|
|
2018-08-24 17:45:18 -04:00
|
|
|
/* DOM editing */
|
2018-08-20 07:23:33 -04:00
|
|
|
function quote(message_id) {
|
|
|
|
let textbox = document.getElementById('messageTextArea');
|
|
|
|
textbox.value += '>>' + message_id + '\n';
|
|
|
|
textbox.focus();
|
|
|
|
}
|
2018-09-03 17:59:41 -04:00
|
|
|
function show_preview(event, message_id) {
|
2018-08-20 07:23:33 -04:00
|
|
|
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;
|
|
|
|
}
|
2018-09-03 17:59:41 -04:00
|
|
|
function clear_preview() {
|
2018-08-20 07:23:33 -04:00
|
|
|
document.getElementById('preview').innerHTML = '';
|
|
|
|
document.getElementById('preview').style.display = 'none';
|
|
|
|
}
|
2018-09-03 17:59:41 -04:00
|
|
|
function scroll_to_msg(message_id) {
|
2018-08-20 07:23:33 -04:00
|
|
|
let elem = document.getElementById('msg-' + message_id);
|
|
|
|
if (!elem) { return; }
|
|
|
|
elem.scrollIntoView();
|
2018-08-15 17:41:51 -04:00
|
|
|
}
|
2018-08-24 17:45:18 -04:00
|
|
|
function close_post(post_id) {
|
|
|
|
let post = document.getElementById('questPostData-' + post_id);
|
|
|
|
post.children[0].textContent = post.children[0].textContent.replace('Open', 'Closed');
|
|
|
|
if (post.parentElement.classList.contains('pollPost')) {
|
|
|
|
let table = document.getElementById('poll-' + post_id);
|
|
|
|
let boxes = table.getElementsByTagName('input');
|
|
|
|
for (let i = 0; i < boxes.length; i++) {
|
|
|
|
boxes[i].disabled = true;
|
|
|
|
}
|
2018-09-05 08:41:53 -04:00
|
|
|
let writein = document.getElementById('writeinContainer-' + post_id);
|
2018-08-24 17:45:18 -04:00
|
|
|
if (writein) {
|
|
|
|
writein.style.display = 'none';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function open_post(post_id) {
|
|
|
|
let post = document.getElementById('questPostData-' + post_id);
|
|
|
|
post.firstElementChild.textContent = post.firstElementChild.textContent.replace('Closed', 'Open');
|
2018-08-24 18:24:25 -04:00
|
|
|
post.parentElement.className += ' activePost';
|
2018-08-24 17:45:18 -04:00
|
|
|
if (post.parentElement.classList.contains('pollPost')) {
|
|
|
|
let table = document.getElementById('poll-' + post_id);
|
|
|
|
let boxes = table.getElementsByTagName('input');
|
|
|
|
for (let i = 0; i < boxes.length; i++) {
|
|
|
|
boxes[i].disabled = false;
|
|
|
|
}
|
2018-09-05 08:41:53 -04:00
|
|
|
let writein = document.getElementById('writeinContainer-' + post_id);
|
2018-08-24 17:45:18 -04:00
|
|
|
if (writein) {
|
|
|
|
writein.style.display = 'initial';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-20 13:09:24 -04:00
|
|
|
function toggle_chat() {
|
|
|
|
if (document.getElementById('chatPane').style.display == 'flex') {
|
|
|
|
document.getElementById('chatPane').style.display = 'none';
|
|
|
|
document.getElementById('questPane').style.width = '100%';
|
2018-09-21 09:30:40 -04:00
|
|
|
document.getElementById('toggleChat').firstChild.innerText = '←';
|
2018-09-20 13:09:24 -04:00
|
|
|
toggle_cookie('hide_chat', 'on');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
document.getElementById('chatPane').style.display = 'flex';
|
|
|
|
document.getElementById('questPane').style.width = '70%';
|
2018-09-21 09:30:40 -04:00
|
|
|
document.getElementById('toggleChat').firstChild.innerText = '→';
|
2018-09-20 13:09:24 -04:00
|
|
|
toggle_cookie('hide_chat', 'off');
|
|
|
|
}
|
|
|
|
}
|