/* 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) { 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); } 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; } 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; } socket.send('message', {message: text}); } }); live_countdown(); } /* Websocket receive */ socket.events['message'] = function(data) { let msg_str = '
'; msg_str = '
' + ((data.name) ? data.name : anon_name) + ' '; msg_str += '' + strftime(data.date) + ' '; msg_str += 'No.' + data.message_id + '
'; msg_str += '
' + data.message + '

'; let mbox = document.getElementById('chatWindow'); mbox.innerHTML = mbox.innerHTML + msg_str; if ((mbox.scrollTop + mbox.offsetHeight) >= (mbox.scrollHeight - mbox.clientHeight)) { mbox.scrollTop = mbox.scrollHeight; } } socket.events['new_post'] = function(data) { let qposts = document.getElementById('questPosts'); let post_str = '
'; } else if (data.post_type === 'dice') { post_str += 'dicePost active_post">'; } else if (data.post_type === 'poll') { post_str += 'pollPost active_post">'; } post_str += '
' + data.date; post_str += '
'; if (data.post_type === 'text') { post_str += data.post_text; } else if (data.post_type === 'dice') { post_str += '

' + data.post_text + ' - Open

'; } else if (data.post_type === 'poll') { post_str += '

' + data.post_text + ' - Open

'; post_str += ''; for (let i = 0; i < data.options.length; i++) { post_str += ''; post_str += ''; post_str += ''; post_str += ''; } post_str += '
'; post_str += '' + data.options[i][1] + '0
'; if (data.allow_writein) { post_str += '
'; post_str += 'Write-in:
'; post_str += '
'; } } post_str += '

'; qposts.innerHTML = qposts.innerHTML + post_str; }; 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) { let class_set = ''; if (data.post_type === 'dice') { class_set = 'dicePost activePost'; } else if (data.post_type === 'poll') { class_set = 'pollPost activePost'; } else { class_set = 'activePost'; } let posts = document.getElementsByClassName(class_set); for (let i = 0; i < posts.length; i++) { close_post(posts[i].children[1].id.slice(14)); // retreive the id number at the end } } socket.events['update_post'] = function(data) { let post = document.getElementById('questPostData-' + data.post_id); if (data.post_type === 'text') { // edit post post.innerHTML = data.post_text; } else if (data.post_type === 'dice') { // diceroll post.innerHTML += '' + data.post_text + '
'; } else if (data.post_type === 'poll') { // write-in let row = post.children[1].insertRow(-1); row.id = 'optionRow-' + data.option_id; let cell = row.insertCell(0); cell.className = 'pollCheckBox'; cell.innerHTML = ''; cell.innerHTML += ''; cell = row.insertCell(1); cell.className = 'option_text'; cell.innerHTML = data.option_text; cell = row.insertCell(2); cell.className = "optionVotes"; 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; } socket.events['new_page'] = function(data) { if (page_num != data.page_num-1) { return; } let html_str = '
'; document.getElementById('questPane').innerHTML = document.getElementById('questPane').innerHTML + html_str; } /* 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}); } function submitWritein(post_id) { let writeinInput = document.getElementById('writeinInput-' + post_id); if (!writeinInput) { return; } let option_text = writeinInput.value; writeinInput.value = ''; if (!option_text) { return; } socket.send('write_in', {option_text: option_text, post_id: post_id}); } /* Helpers */ 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; } function sort_by_votes(a, b) { return b.cells[2].textContent.localeCompare(a.cells[2].textContent); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /* DOM editing */ function quote(message_id) { let textbox = document.getElementById('messageTextArea'); textbox.value += '>>' + message_id + '\n'; textbox.focus(); } function show_preview(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 clear_preview() { document.getElementById('preview').innerHTML = ''; document.getElementById('preview').style.display = 'none'; } function scroll_to_msg(message_id) { let elem = document.getElementById('msg-' + message_id); if (!elem) { return; } elem.scrollIntoView(); } 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; } let writein = document.getElementById('writeinContainer-' + post_id); 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'); post.parentElement.className += ' activePost'; 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; } let writein = document.getElementById('writeinContainer-' + post_id); if (writein) { writein.style.display = 'initial'; } } } function toggle_chat() { if (document.getElementById('chatPane').style.display == 'flex') { document.getElementById('chatPane').style.display = 'none'; document.getElementById('questPane').style.width = '100%'; document.getElementById('toggleChat').firstChild.innerText = '←'; toggle_cookie('hide_chat', 'on'); } else { document.getElementById('chatPane').style.display = 'flex'; document.getElementById('questPane').style.width = '70%'; document.getElementById('toggleChat').firstChild.innerText = '→'; toggle_cookie('hide_chat', 'off'); } } function live_countdown() { if (!document.getElementById('liveTime')) { return; } setInterval(function() { let delta = new Date(document.getElementById('liveTime').innerText) - new Date(); let days = parseInt(delta / (24*60*60*1000)); let hours = parseInt((delta % (24*60*60*1000)) / (60*60*1000)); let minutes = parseInt((delta % (60*60*1000)) / (60*1000)); let seconds = parseInt((delta % (60*1000)) / (1000)); let str = ((days) ? padToTwo(days) + ':' : '') + ((hours) ? padToTwo(hours) + ':' : '') + ((minutes) ? padToTwo(minutes) + ':' : '') + padToTwo(seconds); document.getElementById('liveCountdown').innerText = str; }, 1000); }