339 lines
15 KiB
HTML
339 lines
15 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ quest_title }}{% endblock %}
|
|
{% block head %}
|
|
<script type="text/javascript" src="/static/socket.io.slim.js"></script>
|
|
<script>
|
|
document.execCommand("defaultParagraphSeparator", false, "br");
|
|
var socket;
|
|
var tid = setInterval( function () {
|
|
if ( document.readyState !== 'complete' ) return;
|
|
clearInterval( tid );
|
|
|
|
document.getElementById('chatWindow').scrollTop = document.getElementById('chatWindow').scrollHeight;
|
|
socket = io.connect('https://' + document.domain + ':' + location.port);
|
|
socket.on('connect', function() {
|
|
socket.emit('joined', {room: {{ room_id }}});
|
|
});
|
|
socket.on('message', function(data) {
|
|
let msg_str = '<div class="messageHeader"><span class="messageName">' + data.name + '</span> ';
|
|
msg_str += '<span class="messageDate">' + strftime(data.date) + '</span></div>';
|
|
msg_str += '<div class="message">' + data.message + '</div><hr>';
|
|
|
|
let mbox = document.getElementById('chatWindow');
|
|
mbox.innerHTML = mbox.innerHTML + msg_str;
|
|
mbox.scrollTop = mbox.scrollHeight;
|
|
});
|
|
socket.on('new_post', function(data) {
|
|
deactivate_post();
|
|
let qposts = document.getElementById('questPosts');
|
|
let post_str = '<div class="questPost ';
|
|
if (data.post_type == 'text') {
|
|
post_str += 'textPost">';
|
|
} else if (data.post_type == 'dice') {
|
|
post_str += 'dicePost active_post">';
|
|
} else if (data.post_type == 'poll') {
|
|
post_str += 'pollPost active_post">';
|
|
}
|
|
post_str += '<div class="questPostMeta">' + strftime(data.date);
|
|
{% if session.get("user_id") == owner_id %}
|
|
if (data.post_type == 'text') {
|
|
post_str += '<br /><a href="javascript:void(0);" onclick="edit_post(\'' + data.post_id + '\')">Edit</a>';
|
|
post_str += '<a href="javascript:void(0);" id="savePost-' + data.post_id + '" onclick="save_post(\'' + data.post_id + '\')" style="display:none;">Save</a>';
|
|
} else if (data.post_type == 'dice' || data.post_type == 'poll') {
|
|
post_str += '<br /><a href="javascript:void(0);" id="close_post_id-' + data.post_id + '" onclick="close_post(' + data.post_id + ')">Close</a>';
|
|
post_str += '<a href="javascript:void(0);" id="open_post_id-' + data.post_id + '" onclick="open_post(' + data.post_id + ')" style="display:none;">Open</a>'
|
|
}
|
|
{% endif %}
|
|
post_str += '</div><div class="questPostData" id="questPostData-' + data.post_id + '">';
|
|
if (data.post_type == 'text') {
|
|
post_str += data.post;
|
|
} else if (data.post_type == 'dice') {
|
|
post_str += '<h3>' + data.post + ' - Open</h3>';
|
|
} else if (data.post_type == 'poll') {
|
|
post_str += '<h3>' + data.post + ' - Open</h3>';
|
|
post_str += '<table id="post-' + data.post_id + '">';
|
|
for (i = 0; i < data.options.length; i++) {
|
|
post_str += '<tr><td>' + data.options[i] + '</td></tr>';
|
|
}
|
|
post_str += '</table>';
|
|
}
|
|
post_str += '</div></div><br />';
|
|
qposts.innerHTML = qposts.innerHTML + post_str;
|
|
});
|
|
socket.on('update_post', function(data) {
|
|
let post_id = data.post_id;
|
|
let post = document.getElementById('questPostData-' + post_id);
|
|
if (data.post_type == 'text') {
|
|
post.innerHTML = data.post;
|
|
}
|
|
else if (data.post_type == 'dice') {
|
|
post.innerHTML += '<b>' + data.post + '</b><br />';
|
|
}
|
|
});
|
|
socket.on('close_post', function(data) {
|
|
let post = document.getElementById('questPostData-' + data.post_id);
|
|
post.children[0].textContent = post.children[0].textContent.replace('Open', 'Closed');
|
|
document.getElementById('close_post_id-' + data.post_id).style.display = 'none';
|
|
document.getElementById('open_post_id-' + data.post_id).style.display = 'initial';
|
|
if (post.parentElement.classList.contains('pollPost')) {
|
|
table = document.getElementById('poll-' + data.post_id);
|
|
table.getElementsByTagName("col")[0].style.visibility = 'collapse';
|
|
}
|
|
});
|
|
socket.on('open_post', function(data) {
|
|
let post = document.getElementById('questPostData-' + data.post_id);
|
|
post.firstElementChild.textContent = post.firstElementChild.textContent.replace('Closed', 'Open');
|
|
document.getElementById('close_post_id-' + data.post_id).style.display = 'initial';
|
|
document.getElementById('open_post_id-' + data.post_id).style.display = 'none';
|
|
if (post.parentElement.classList.contains('pollPost')) {
|
|
table = document.getElementById('poll-' + data.post_id);
|
|
table.getElementsByTagName("col")[0].style.visibility = '';
|
|
}
|
|
});
|
|
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.emit('message', {message: text, name: 'Anonymous', room: {{ room_id }}});
|
|
}
|
|
});
|
|
}, 100 );
|
|
</script>
|
|
<script>
|
|
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 pollVote(option_id) {
|
|
socket.emit('vote', {option_id: option_id, polarity: document.getElementById('pollInput-' + option_id).checked, room: {{ room_id }}});
|
|
}
|
|
</script>
|
|
{% if session.get("user_id") == owner_id %}
|
|
<script>
|
|
function makePost() {
|
|
let qparea = document.getElementById('postTextArea');
|
|
let text = qparea.value.trim();
|
|
qparea.value = '';
|
|
if (text == '') { return; }
|
|
socket.emit('new_post', {post: text, room: {{ room_id }}});
|
|
}
|
|
function edit_post(post_id) {
|
|
document.getElementById('questPostData-' + post_id).contentEditable = 'true';
|
|
document.execCommand("defaultParagraphSeparator", false, "br");
|
|
document.getElementById('questPostData-' + post_id).style.border = '1px solid #ccc';
|
|
document.getElementById('savePost-' + post_id).style.display = 'initial';
|
|
document.getElementById('editPost-' + post_id).style.display = 'none';
|
|
}
|
|
function save_post(post_id) {
|
|
document.getElementById('questPostData-' + post_id).contentEditable = 'false';
|
|
document.getElementById('questPostData-' + post_id).style.border = null;
|
|
let text = document.getElementById('questPostData-' + post_id).innerHTML;
|
|
socket.emit('update_post', {post_id: post_id, post: text, room: {{ room_id }}});
|
|
document.getElementById('savePost-' + post_id).style.display = 'none';
|
|
document.getElementById('editPost-' + post_id).style.display = 'initial';
|
|
}
|
|
function form_post(form_id, emit_msg) {
|
|
let formData = new FormData(document.getElementById(form_id));
|
|
let obj = {};
|
|
formData.forEach(function(value, key) {
|
|
obj[key] = value;
|
|
});
|
|
obj.room = {{ room_id }};
|
|
socket.emit(emit_msg, obj);
|
|
document.getElementById(form_id).reset();
|
|
}
|
|
function close_post(post_id) {
|
|
socket.emit('close_post', {post_id: post_id, room: {{ room_id }}});
|
|
}
|
|
function open_post(post_id) {
|
|
socket.emit('open_post', {post_id: post_id, room: {{ room_id }}});
|
|
}
|
|
function deactivate_post() {
|
|
let post = document.getElementsByClassName('active_post');
|
|
if (post.length == 0) { return; }
|
|
post = post[0];
|
|
post.children[1].children[0].textContent = post.children[1].children[0].textContent.replace('Open', 'Closed');
|
|
post.classList.remove("active_post");
|
|
post.children[0].children[2].outerHTML = "";
|
|
post.children[0].children[1].outerHTML = "";
|
|
}
|
|
function insertPollOption() {
|
|
let opts = document.getElementById('pollOptions');
|
|
let num = opts.children.length+1;
|
|
let temp = document.createElement('template');
|
|
temp.innerHTML = '<div><input type="text" name="pollOption-' + num + '" class="pollOption" placeholder="Option ' + num + '" maxlength="200" /></div>';
|
|
opts.appendChild(temp.content);
|
|
}
|
|
function removePollOption() {
|
|
let opts = document.getElementById('pollOptions');
|
|
if (opts.children.length == 0) { return; }
|
|
opts.children[opts.children.length-1].outerHTML = '';
|
|
}
|
|
</script>
|
|
<script>
|
|
function openPostTab(event, modeName) {
|
|
let i, QMPostTabContent, QMPostTab;
|
|
|
|
QMPostTabContent = document.getElementsByClassName("QMPostTabContent");
|
|
for (i = 0; i < QMPostTabContent.length; i++) {
|
|
QMPostTabContent[i].style.display = "none";
|
|
}
|
|
|
|
QMPostTab = document.getElementsByClassName("QMPostTab");
|
|
for (i = 0; i < QMPostTab.length; i++) {
|
|
QMPostTab[i].className = QMPostTab[i].className.replace(" active", "");
|
|
}
|
|
|
|
document.getElementById(modeName).style.display = "block";
|
|
event.currentTarget.className += " active";
|
|
}
|
|
</script>
|
|
{% endif %}
|
|
{% endblock %}
|
|
{% block header %}
|
|
{% if session.get("user_id") == owner_id %}
|
|
<li><a href="{{ url_for('.quest', quest_title=ident_title + '/edit_quest') }}">Edit Quest</a></li>
|
|
{% endif %}
|
|
{% endblock %}
|
|
{% block content %}
|
|
<div id="questContainer">
|
|
<div id="questPane">
|
|
<center><h1>{{ quest_title }}</h1></center>
|
|
<div id="questPosts">
|
|
{% for quest_post in quest_posts %}
|
|
{% if quest_post[2] == "text" %}
|
|
<div class="questPost textPost">
|
|
{% elif quest_post[2] == "dice" %}
|
|
<div class="questPost dicePost{% if quest_post == quest_posts|last %} active_post{% endif %}">
|
|
{% elif quest_post[2] == "poll" %}
|
|
<div class="questPost pollPost{% if quest_post == quest_posts|last %} active_post{% endif %}">
|
|
{% endif %}
|
|
<div class="questPostMeta">
|
|
{{ quest_post[4] | strftime }}
|
|
{% if session.get("user_id") == owner_id %}
|
|
{% if quest_post[2] == "text" %}
|
|
<br /><a href="javascript:void(0);" id="editPost-{{ quest_post[0] }}" onclick="edit_post({{ quest_post[0] }})">Edit</a>
|
|
<a href="javascript:void(0);" id="savePost-{{ quest_post[0] }}" onclick="save_post('{{ quest_post[0] }}')" style="display:none;">Save</a>
|
|
{% elif quest_post[2] == "dice" or quest_post[2] == "poll" and quest_post == quest_posts|last %}
|
|
{% if quest_post[0] == open_post_id %}
|
|
<br /><a href="javascript:void(0);" id="close_post_id-{{ quest_post[0] }}" onclick="close_post({{ quest_post[0] }})">Close</a>
|
|
<a href="javascript:void(0);" id="open_post_id-{{ quest_post[0] }}" onclick="open_post({{ quest_post[0] }})" style="display:none;">Open</a>
|
|
{% else %}
|
|
<br /><a href="javascript:void(0);" id="close_post_id-{{ quest_post[0] }}" onclick="close_post({{ quest_post[0] }})" style="display:none;">Close</a>
|
|
<a href="javascript:void(0);" id="open_post_id-{{ quest_post[0] }}" onclick="open_post({{ quest_post[0] }})">Open</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
<div class="questPostData" id="questPostData-{{ quest_post[0] }}">
|
|
{% if quest_post[2] == "text" %}
|
|
{% autoescape false %}
|
|
{{ quest_post[3] }}
|
|
{% endautoescape %}
|
|
{% elif quest_post[2] == "dice" %}
|
|
<h3>{{ quest_post[3] }} - {% if quest_post[0] == open_post_id %}Open{% else %}Closed{% endif %}</h3>
|
|
{% for dice_roll in dice_rolls[quest_post[0]] %}
|
|
<div id="questRollId-{{ dice_roll[0] }}">
|
|
<b>Rolled {{ dice_roll[4] }} = {{ dice_roll[5] }} ({{ dice_roll[3] }}){% if quest_post[0]|dice_chal != 0 %} - {% if dice_roll[5] >= quest_post[0]|dice_chal %}Pass{% else %} Fail{% endif %}{% endif %}</b>
|
|
</div>
|
|
{% endfor %}
|
|
{% elif quest_post[2] == "poll" %}
|
|
<h3>{{ quest_post[3] }} - {% if quest_post[0] == open_post_id %}Open{% else %}Closed{% endif %}</h3>
|
|
<table class="poll" id="poll-{{ quest_post[0] }}">
|
|
<col{% if quest_post[0] != open_post_id %} style="visibility: collapse;"{% endif %}/>
|
|
<col/>
|
|
<col/>
|
|
{% for option in options[quest_post[0]] %}
|
|
<tr>
|
|
<td class="pollCheckBox">
|
|
<input type="checkbox" id="pollInput-{{ option[0] }}" onchange="pollVote({{ option[0] }})"/>
|
|
<label for="pollInput-{{ option[0] }}"></label>
|
|
</td>
|
|
<td class="option_text">{{ option[2] }}</td>
|
|
<td class="optionVotes">{{ option[0]|num_votes }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
{% endif %}
|
|
</div>
|
|
</div><br />
|
|
{% endfor %}
|
|
</div>
|
|
{% if session.get("user_id") == owner_id %}
|
|
<div id="QMPostPane">
|
|
<div>
|
|
<ul id="QMPostTabs">
|
|
<li><a class="QMPostTab active" href="javascript:void(0);" onclick="openPostTab(event, 'QMPostText')">Text</a></li>
|
|
<li><a class="QMPostTab" href="javascript:void(0);" onclick="openPostTab(event, 'QMPostDice')">Dice</a></li>
|
|
<li><a class="QMPostTab" href="javascript:void(0);" onclick="openPostTab(event, 'QMPostPoll')">Poll</a></li>
|
|
</ul>
|
|
</div>
|
|
<div id="QMPostText" class="QMPostTabContent" style="display:initial;">
|
|
<textarea id="postTextArea"></textarea><br />
|
|
<input type="submit" name="newPost" value="Post" onclick="makePost();"/>
|
|
</div>
|
|
<div id="QMPostDice" class="QMPostTabContent" style="display:none;">
|
|
Dice for the dice god.<br />
|
|
<form id="QMDicePostForm" action="javascript:void(0);" onsubmit="form_post('QMDicePostForm', 'dice_post');">
|
|
Dice: <input type="number" name="diceNum" min="1" max="99" required/>
|
|
d <input type="number" name="diceSides" min="1" max="99" required/>
|
|
±<input type="number" name="diceMod" min="-999" max="999"/>
|
|
<input type="checkbox" name="diceStrict"/>
|
|
<span class="tooltip" title="Only take matching rolls.">Strict</span><br />
|
|
<input type="checkbox" onclick="document.getElementById('diceChal').disabled=!this.checked;"/>
|
|
<span class="tooltip" title="Dice challenge">DC:</span>
|
|
<input type="number" name="diceChal" id="diceChal" min="1" max="99" disabled/><br />
|
|
<input type="checkbox" onclick="document.getElementById('diceRollsTaken').disabled=!this.checked;"/>
|
|
<span class="tooltip" title="Automatically close the dice call after this many rolls have been made.">Rolls Taken:</span>
|
|
<input type="number" name="diceRollsTaken" id="diceRollsTaken" min="1" max="99" disabled/><br />
|
|
<input type="submit" name="submit" value="Roll 'em"/>
|
|
</form>
|
|
</div>
|
|
<div id="QMPostPoll" class="QMPostTabContent" style="display:none;">
|
|
The polls are rigged.
|
|
<form id="QMPollPostForm" action="javascript:void(0);" onsubmit="form_post('QMPollPostForm', 'poll_post');">
|
|
<a href="javascript:void(0);" id="pollInsertNewOption" onclick="insertPollOption()">[+]</a>
|
|
<a href="javascript:void(0);" onclick="removePollOption()">[-]</a>
|
|
<div id="pollOptions">
|
|
<div><input type="text" name="pollOption-1" class="pollOption" placeholder="Option 1" maxlength="200" /></div>
|
|
<div><input type="text" name="pollOption-2" class="pollOption" placeholder="Option 2" maxlength="200" /></div>
|
|
</div>
|
|
<hr>
|
|
<input type="checkbox" name="pollAllowMultipleChoices" />Allow multiple choices<br />
|
|
<input type="checkbox" name="pollAllowUserOptions" />Allow user-created options<br />
|
|
<input type="submit" name="submit" value="Submit" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<br />
|
|
<br />
|
|
<div id="chatPane">
|
|
<h1>Chat</h1>
|
|
<div id="chatWindow">
|
|
{% autoescape false %}
|
|
{% for message in messages %}
|
|
<div class="message">
|
|
<div class="messageHeader">
|
|
<span class="messageName">Anonymous</span> <span class="messageDate">{{ message[3] | strftime }}</span>
|
|
</div>
|
|
<div class="messageMessage">{{ message[4] }}</div>
|
|
</div>
|
|
<hr>
|
|
{% endfor %}
|
|
{% endautoescape %}
|
|
</div>
|
|
<div id="messageTextDiv"><textarea id="messageTextArea"></textarea></div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|