basic support for the quest page

This commit is contained in:
iou1name 2018-08-13 13:17:51 -04:00
parent 1f0e122646
commit 20bab88d04
5 changed files with 371 additions and 212 deletions

View File

@ -1,7 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>{% block title %}{% endblock %} - Titivillus</title> <title>{% block title %}{% endblock %} - Titivillus</title>
<link rel="stylesheet" type="text/css" href="{{ static('base.css') }}"> <link rel="stylesheet" type="text/css" href="{{ static('base.css') }}">
<script> <script>

View File

@ -0,0 +1,156 @@
{% extends "base.html" %}
{% block title %}{{ quest.title }}{% endblock %}
{% block head %}
{#<script type="text/javascript" src="/static/socket.io.slim.js"></script>#}
<script>var quest_id = {{ quest.id }}; var page_num = {{ page_num }};</script>
{#<script type="text/javascript" src="/static/anonkunUser.js"></script>#}
{% if request.user == quest.owner %}
{#<script type="text/javascript" src="/static/anonkunQM.js"></script>#}
{% endif %}
{#<script>window.onload = load;</script>#}
{% endblock %}
{% block header %}
{% if request.user == quest.owner %}
<li><a href="{# url('edit_quest:index', quest_id=quest_id) #}">Edit Quest</a></li>
{% endif %}
<li>
<select onChange="window.location.href=this.value">
{# for page in pages %}
<option value="{{ url_for('.quest', quest_id=quest_id, page_num=page[1]) }}"{% if page[1] == page_num %} selected="yes"{% endif %}>{{ page[2] }}</option>
{% endfor #}
</select>
</li>
{% endblock %}
{% block content %}
<div id="questContainer">
<div id="questPane">
<center><h1>{{ quest.title }}</h1></center>
<div id="questPosts">
{% for post in posts %}
{% if post.post_type == "text" %}
<div class="questPost textPost">
{% elif post.post_type == "dice" %}
<div class="questPost dicePost{% if post == posts|last %} active_post{% endif %}">
{% elif post.post_type == "poll" %}
<div class="questPost pollPost{% if post == posts|last %} active_post{% endif %}">
{% endif %}
<div class="questPostMeta">
{{ post.timestamp.strftime('%Y-%m-%d %H:%M') }}
{% if request.user == quest.owner %}
{% if post.post_type == "text" %}
<br /><a href="javascript:void(0);" id="editPost-{{ post.id }}" onclick="edit_post({{ post.id }})">Edit</a>
<a href="javascript:void(0);" id="savePost-{{ post.id }}" onclick="save_post('{{ post.id }}')" style="display:none;">Save</a>
{% elif (post.post_type == "dice" or post.post_type == "poll") and post == posts|last %}
<br /><a href="javascript:void(0);" id="close_post_id-{{ post.id }}" onclick="close_post({{ post.id }})"{% if post.id != quest.open_post_id %} style="display:none;"{% endif %}>Close</a>
<a href="javascript:void(0);" id="open_post_id-{{ post.id }}" onclick="open_post({{ post.id }})"{% if post.id == quest.open_post_id %} style="display:none;"{% endif %}>Open</a>
{% endif %}
{% endif %}
</div>
<div class="questPostData" id="questPostData-{{ post.id }}">
{% if post.post_type == "text" %}
{% autoescape false %}
{{ post.post_text }}
{% endautoescape %}
{% elif post.post_type == "dice" %}
<h3>{{ post.post_text }} - {% if post.id == quest.open_post_id %}Open{% else %}Closed{% endif %}</h3>
{# for dice_roll in dice_rolls.get(post.id, []) %}
<div id="questRollId-{{ dice_roll[0] }}">
<b>Rolled {{ dice_roll[4] }} = {{ dice_roll[5] }} ({{ dice_roll[3] }}){% if post.id|dice_chal != 0 %} - {% if dice_roll[5] >= post.id|dice_chal %}Pass{% else %}Fail{% endif %}{% endif %}</b>
</div>
{% endfor #}
<h3>{{ post.post_test }} - {% if post.id == quest.open_post_id %}Open{% else %}Closed{% endif %}</h3>
<table class="poll" id="poll-{{ post.id }}">
{# for option in options.get(post.id, []) %}
<tr id="optionRow-{{ option[0] }}">
<td class="pollCheckBox">
<input type="checkbox" {% if ip_address in poll_votes.get(option[0], []) %}checked="true"{% endif %} id="pollInput-{{ option[0] }}" onchange="pollVote({{ post.id }}, {{ option[0] }})"{% if post.id != quest.open_post_id %} disabled{% endif %}/>
<label for="pollInput-{{ option[0] }}"></label>
</td>
<td class="option_text">{{ option[2] }}</td>
<td class="optionVotes">{{ poll_votes.get(option[0], [])|length }}</td>
</tr>
{% endfor #}
</table>
{# if post.id == quest.open_post_id and post.id|is_write_in %}
<div id="writeinContainer">
Write-in: <input type="text" id="writeinInput" placeholder="Custom choice..." maxlength="200" /><br />
<input type="submit" id="writeinSubmit" value="Submit" onclick="submitWritein({{ post.id }});"/>
</div>
{% endif #}
{% endif %}
</div>
</div><br />
{% endfor %}
</div>
{% if request.user == quest.owner %}
<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 id="msg-{{ message[0] }}" class="message">
<div class="messageHeader">
<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 class="messageContent">{{ message[4] }}</div>
</div>
<hr>
{% endfor #}
{% endautoescape %}
</div>
<div id="messageTextDiv"><textarea id="messageTextArea"></textarea></div>
</div>
</div>
<div id="preview" style="display:none;"></div>
{% endblock %}

209
quest/static/quest.css Normal file
View File

@ -0,0 +1,209 @@
img {
max-width:100%;
max-height:100%;
}
h3 {
margin-top: 0px;
margin-bottom: 0.5em;
}
#questContainer {
display: flex;
overflow: auto;
}
#questPane {
padding-left: 5%;
padding-right: 35%;
min-width: 0;
}
.questPost {
display: flex;
}
.questPostMeta {
white-space: nowrap;
padding-right: 15px;
}
.questPostData {
word-wrap: break-word;
min-width: 0;
width: 100%;
}
#QMPostPane {
display: flex;
}
#QMPostTabs {
display: inline-block;
list-style-type: none;
padding: 0;
margin: 0;
background-color: #f1f1f1;
height: 100%;
}
.QMPostTab {
display: block;
padding: 8px 16px;
text-decoration: none;
}
.QMPostTab:hover {
background-color: #555;
color: white;
}
.QMPostTab.active {
background-color: #555;
color: white;
}
.QMPostTabContent {
flex: auto;
padding: 0px 12px;
border: 1px solid #ccc;
border-left: none;
width: 100px;
}
#postTextArea {
max-width: 100%;
}
.tooltip {
border-bottom: 1px dotted black;
}
#QMPollPostForm a {
text-decoration: none;
}
.pollOption {
width: 100%;
margin: 0.1em;
}
.pollPost {
width: 100%;
}
.poll {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: 1px solid #ddd;
}
.optionVotes {
width: 4em;
text-align: center;
}
.poll td {
padding: 0.5em;
word-wrap: break-word;
border-bottom: 1px solid #ddd;
}
.pollCheckBox input {
display: none;
}
.pollCheckBox {
width: 1.5em;
}
.pollCheckBox label {
cursor: pointer;
background: #eee;
border: 1px solid #ddd;
padding: 0.2em;
}
.pollCheckBox label::after {
content: "\2713";
color: #bfbfbf;
opacity: 0.3;
}
.pollCheckBox label:hover::after {
opacity: 0.5;
}
.pollCheckBox input:checked + label::after {
opacity: 1;
color: black;
}
.pollCheckBox input:disabled + label {
opacity: 0.3;
}
#writeinInput {
width: 100%;
}
#chatPane {
height: 100%;
width: 30%;
right: 0;
position: fixed;
display: flex;
flex-direction: column;
}
#chatWindow {
border: 1px solid #ccc;
padding: 0.25em;
overflow: auto;
flex: 1;
}
.messageContent {
width: 100%;
word-wrap: break-word;
}
.msgSrvHr {
width: 95%;
margin-top: 0.2em;
margin-bottom: 0.2em;
margin-left: auto;
margin-right: auto;
border: 0;
border-bottom: 1px solid #ccc;
}
#messageTextDiv {
padding-bottom: 10px;
width: 100%;
display: flex;
flex-direction: column;
}
#messageTextArea {
resize: none;
box-sizing: border-box;
}
#preview {
display: block;
position: fixed;
background: white;
word-wrap: break-word;
border: 1px solid #ccc;
padding: 0.25em;
}
.greenText {
color: green;
}
.quotelink {
color: red;
}

View File

@ -5,6 +5,8 @@ Quest and quest accessory views.
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse
from .models import Quest
def index(request): def index(request):
""" """
/quest page index. Possibly not needed. /quest page index. Possibly not needed.
@ -17,4 +19,7 @@ def quest(request, quest_id, page_num=1):
""" """
Arbituary quest page view. Arbituary quest page view.
""" """
return HttpResponse(f"Quest_ID: {quest_id} Page_Num: {page_num}") quest = Quest.objects.get(id=quest_id)
posts = quest.post_set.all()
context = {'quest': quest, 'posts': posts, 'page_num': page_num}
return render(request, 'quest/quest.html', context)

View File

@ -1,13 +1,3 @@
img {
max-width:100%;
max-height:100%;
}
h3 {
margin-top: 0px;
margin-bottom: 0.5em;
}
.header { .header {
position: fixed; position: fixed;
top: 0; top: 0;
@ -30,203 +20,3 @@ h3 {
#headerHidden { #headerHidden {
width: auto; width: auto;
} }
#questContainer {
display: flex;
overflow: auto;
}
#questPane {
padding-left: 5%;
padding-right: 35%;
min-width: 0;
}
.questPost {
display: flex;
}
.questPostMeta {
white-space: nowrap;
padding-right: 15px;
}
.questPostData {
word-wrap: break-word;
min-width: 0;
width: 100%;
}
#QMPostPane {
display: flex;
}
#QMPostTabs {
display: inline-block;
list-style-type: none;
padding: 0;
margin: 0;
background-color: #f1f1f1;
height: 100%;
}
.QMPostTab {
display: block;
padding: 8px 16px;
text-decoration: none;
}
.QMPostTab:hover {
background-color: #555;
color: white;
}
.QMPostTab.active {
background-color: #555;
color: white;
}
.QMPostTabContent {
flex: auto;
padding: 0px 12px;
border: 1px solid #ccc;
border-left: none;
width: 100px;
}
#postTextArea {
max-width: 100%;
}
.tooltip {
border-bottom: 1px dotted black;
}
#QMPollPostForm a {
text-decoration: none;
}
.pollOption {
width: 100%;
margin: 0.1em;
}
.pollPost {
width: 100%;
}
.poll {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: 1px solid #ddd;
}
.optionVotes {
width: 4em;
text-align: center;
}
.poll td {
padding: 0.5em;
word-wrap: break-word;
border-bottom: 1px solid #ddd;
}
.pollCheckBox input {
display: none;
}
.pollCheckBox {
width: 1.5em;
}
.pollCheckBox label {
cursor: pointer;
background: #eee;
border: 1px solid #ddd;
padding: 0.2em;
}
.pollCheckBox label::after {
content: "\2713";
color: #bfbfbf;
opacity: 0.3;
}
.pollCheckBox label:hover::after {
opacity: 0.5;
}
.pollCheckBox input:checked + label::after {
opacity: 1;
color: black;
}
.pollCheckBox input:disabled + label {
opacity: 0.3;
}
#writeinInput {
width: 100%;
}
#chatPane {
height: 100%;
width: 30%;
right: 0;
position: fixed;
display: flex;
flex-direction: column;
}
#chatWindow {
border: 1px solid #ccc;
padding: 0.25em;
overflow: auto;
flex: 1;
}
.messageContent {
width: 100%;
word-wrap: break-word;
}
.msgSrvHr {
width: 95%;
margin-top: 0.2em;
margin-bottom: 0.2em;
margin-left: auto;
margin-right: auto;
border: 0;
border-bottom: 1px solid #ccc;
}
#messageTextDiv {
padding-bottom: 10px;
width: 100%;
display: flex;
flex-direction: column;
}
#messageTextArea {
resize: none;
box-sizing: border-box;
}
#preview {
display: block;
position: fixed;
background: white;
word-wrap: break-word;
border: 1px solid #ccc;
padding: 0.25em;
}
.greenText {
color: green;
}
.quotelink {
color: red;
}