diff --git a/quest/forms.py b/quest/forms.py
index 12987a6..d236af9 100644
--- a/quest/forms.py
+++ b/quest/forms.py
@@ -42,3 +42,7 @@ class EditQuestForm(forms.Form):
Form for the /edit_quest page.
"""
anon_name = forms.CharField(max_length=20)
+ live = forms.BooleanField(required=False)
+ live_date = forms.DateField(required=False)
+ live_time = forms.TimeField(required=False)
+ timezone = forms.IntegerField()
diff --git a/quest/jinja2/quest/edit_quest.html b/quest/jinja2/quest/edit_quest.html
index 71b7a7c..65727ec 100644
--- a/quest/jinja2/quest/edit_quest.html
+++ b/quest/jinja2/quest/edit_quest.html
@@ -1,5 +1,10 @@
{% extends "base.html" %}
{% block title %}Edit {{ quest.title }}{% endblock %}
+{% block head %}
+
+{% endblock %}
{% block content %}
{{ quest.title }}
{% endblock %}
diff --git a/quest/jinja2/quest/quest.html b/quest/jinja2/quest/quest.html
index dd65b8a..dee37fe 100644
--- a/quest/jinja2/quest/quest.html
+++ b/quest/jinja2/quest/quest.html
@@ -37,6 +37,17 @@
{% endif %}
+ {% if quest.live %}
+
+ LIVE
+
+ {% else %}
+ {% if quest.live_time %}
+
+ Live in: ({{ localtime(quest.live_time).strftime('%Y-%m-%d %H:%M') }})
+
+ {% endif %}
+ {% endif %}
{% if request.session.get("hide_chat") == True %}←{% else %}→{% endif %}
{% endblock %}
{% block content %}
diff --git a/quest/migrations/0003_auto_20180928_0747.py b/quest/migrations/0003_auto_20180928_0747.py
new file mode 100644
index 0000000..5b89cdb
--- /dev/null
+++ b/quest/migrations/0003_auto_20180928_0747.py
@@ -0,0 +1,29 @@
+# Generated by Django 2.1.1 on 2018-09-28 11:47
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('quest', '0002_auto_20180925_0936'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='quest',
+ name='live',
+ field=models.BooleanField(default=False),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='quest',
+ name='live_time',
+ field=models.DateTimeField(blank=True, null=True),
+ ),
+ migrations.AlterField(
+ model_name='page',
+ name='appendix',
+ field=models.BooleanField(),
+ ),
+ ]
diff --git a/quest/models.py b/quest/models.py
index b43c856..bd958a7 100644
--- a/quest/models.py
+++ b/quest/models.py
@@ -15,6 +15,8 @@ class Quest(models.Model):
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
anon_name = models.CharField(max_length=20, default="Anonymous")
+ live = models.BooleanField()
+ live_time = models.DateTimeField(blank=True, null=True)
class Message(models.Model):
@@ -38,7 +40,7 @@ class Page(models.Model):
quest = models.ForeignKey(Quest, on_delete=models.CASCADE)
page_num = models.CharField(max_length=4)
title = models.CharField(max_length=200)
- appendix = models.BooleanField(default=False)
+ appendix = models.BooleanField()
def __str__(self):
return self.title
diff --git a/quest/static/quest.css b/quest/static/quest.css
index 61363b9..d9864d6 100644
--- a/quest/static/quest.css
+++ b/quest/static/quest.css
@@ -8,6 +8,12 @@ h3 {
margin-bottom: 0.5em;
}
+#live {
+ color: white;
+ background-color: red;
+ padding: 0.25em;
+}
+
#toggleChat {
margin-left: auto;
}
diff --git a/quest/static/quest.js b/quest/static/quest.js
index 1e29350..0fab0cc 100644
--- a/quest/static/quest.js
+++ b/quest/static/quest.js
@@ -44,6 +44,7 @@ function load() {
socket.send('message', {message: text});
}
});
+ live_countdown();
}
/* Websocket receive */
@@ -265,3 +266,16 @@ function toggle_chat() {
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);
+}
diff --git a/quest/urls.py b/quest/urls.py
index b1f03be..14d7db4 100644
--- a/quest/urls.py
+++ b/quest/urls.py
@@ -9,8 +9,8 @@ from . import views
app_name = 'quest'
urlpatterns = [
path('', views.index, name='index'),
- path('', views.quest, name='quest'),
- path('/', views.quest, name='quest'),
path('/edit_quest', views.edit_quest, name='edit_quest'),
path('//edit_quest', views.edit_quest, name='edit_quest'),
+ path('', views.quest, name='quest'),
+ path('/', views.quest, name='quest'),
]
diff --git a/quest/views.py b/quest/views.py
index bcf2378..7d80ed3 100644
--- a/quest/views.py
+++ b/quest/views.py
@@ -2,6 +2,8 @@
"""
Quest and quest accessory views.
"""
+from datetime import timedelta, datetime, timezone
+
from django.contrib import messages
from django.http import HttpResponse
from django.shortcuts import render, redirect
@@ -53,6 +55,21 @@ def edit_quest(request, quest_id, page_num=1):
form = EditQuestForm(request.POST)
if form.is_valid():
quest.anon_name = form.cleaned_data['anon_name']
+ quest.live = form.cleaned_data['live']
+
+ live_date = form.cleaned_data['live_date']
+ live_time = form.cleaned_data['live_time']
+ if live_date and live_time:
+ live_datetime = datetime.combine(
+ live_date,
+ live_time,
+ timezone.utc
+ )
+ tz_delta = timedelta(minutes=form.cleaned_data['timezone'])
+ live_datetime = live_datetime + tz_delta
+ quest.live_time = live_datetime
+ else:
+ quest.live_time = None
quest.save()
return redirect('quest:quest',quest_id=quest.id, page_num=page_num)
else:
diff --git a/static/base.css b/static/base.css
index cc17b26..6b0c37a 100644
--- a/static/base.css
+++ b/static/base.css
@@ -23,6 +23,12 @@ body {
.header span {
padding-right: 0.25em;
+ padding-left: 0.25em;
+}
+
+.header span span {
+ padding-right: 0;
+ padding-left: 0;
}
.header a {
diff --git a/todo b/todo
index 3c044d6..e13cd7e 100644
--- a/todo
+++ b/todo
@@ -1,5 +1,4 @@
New Features:
-Live indicator/countdown
Notifications
Banner images
Search page
@@ -10,13 +9,13 @@ Account managament/logout
Display profile link in header bar
Tagging system
Quote backlinks
+Quest homepage
Improvements:
More options for text posts (lists and so on)
More rigorous input checking in events.py
New post displays chat message
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