From db3d179215f9a5ce28ffc938a26a508868fafe42 Mon Sep 17 00:00:00 2001 From: iou1name Date: Mon, 15 Oct 2018 13:12:48 -0400 Subject: [PATCH] notitications frontend functionality added, api app added, misc. --- {homepage/migrations => api}/__init__.py | 0 {set_session => api}/admin.py | 0 api/apps.py | 5 ++ {set_session => api}/tests.py | 0 api/urls.py | 16 +++++++ api/views.py | 60 ++++++++++++++++++++++++ homepage/models.py | 3 -- jinja2/base.html | 15 +++++- login/migrations/__init__.py | 0 login/models.py | 3 -- logout/migrations/__init__.py | 0 logout/models.py | 3 -- quest/jinja2/quest/quest_homepage.html | 3 +- quest/urls.py | 1 - quest/views.py | 20 ++++---- set_session/__init__.py | 0 set_session/apps.py | 5 -- set_session/migrations/__init__.py | 0 set_session/models.py | 3 -- set_session/urls.py | 12 ----- set_session/views.py | 21 --------- signup/migrations/__init__.py | 0 signup/models.py | 3 -- static/base.css | 20 ++++++++ static/base.js | 16 ++++++- titivillus/jinja2.py | 2 +- titivillus/urls.py | 2 +- todo | 1 + 28 files changed, 142 insertions(+), 72 deletions(-) rename {homepage/migrations => api}/__init__.py (100%) rename {set_session => api}/admin.py (100%) create mode 100644 api/apps.py rename {set_session => api}/tests.py (100%) create mode 100644 api/urls.py create mode 100644 api/views.py delete mode 100644 homepage/models.py delete mode 100644 login/migrations/__init__.py delete mode 100644 login/models.py delete mode 100644 logout/migrations/__init__.py delete mode 100644 logout/models.py delete mode 100644 set_session/__init__.py delete mode 100644 set_session/apps.py delete mode 100644 set_session/migrations/__init__.py delete mode 100644 set_session/models.py delete mode 100644 set_session/urls.py delete mode 100644 set_session/views.py delete mode 100644 signup/migrations/__init__.py delete mode 100644 signup/models.py diff --git a/homepage/migrations/__init__.py b/api/__init__.py similarity index 100% rename from homepage/migrations/__init__.py rename to api/__init__.py diff --git a/set_session/admin.py b/api/admin.py similarity index 100% rename from set_session/admin.py rename to api/admin.py diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..d87006d --- /dev/null +++ b/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = 'api' diff --git a/set_session/tests.py b/api/tests.py similarity index 100% rename from set_session/tests.py rename to api/tests.py diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..97abfc8 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +""" +API URL configuration. +""" +from django.urls import path + +from . import views + +app_name = 'api' +urlpatterns = [ + path('', views.index, name='index'), + path('set_session', views.set_session, name='set_session'), + path('subscribe', views.subscribe, name='subscribe'), + path('clear_notification', views.clear_notification, name='clear_notification'), +] + diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..d493df2 --- /dev/null +++ b/api/views.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" +API endpoints. +""" +from user_messages import api +from django.http import HttpResponse +from django.shortcuts import redirect +from django.views.decorators.http import require_POST + +from quest.models import Quest + +def index(request): + """An index page.""" + return HttpResponse('Hello.') + + +@require_POST +def set_session(request): + """ + API endpoint for setting certain values in the users session. + """ + for key, value in request.POST.items(): + if key not in ['hide_header', 'hide_chat']: + continue + if value == 'on': + request.session[key] = True + elif value == 'off': + request.session[key] = False + + return HttpResponse('true') + + +@require_POST +def subscribe(request): + """Endpoint for users to subscribe to a quest.""" + if not request.user.is_authenticated: + return redirect('login:index') + quest_id = request.POST.get('quest_id') + try: + quest = Quest.objects.get(id=quest_id) + except Quest.DoesNotExist: + return redirect('quest:quest', quest_id=quest_id, page_num='0') + request.user.subscriptions.add(quest) + return redirect('quest:quest', quest_id=quest.id, page_num='0') + + +@require_POST +def clear_notification(request): + """Endpoint for users to clear a message notification.""" + if not request.user.is_authenticated: + return redirect('login:index') + msg_id = request.POST.get('msg_id') + messages = api.get_messages(user=request.user) + message = [m for m in messages if str(m.id) == msg_id] + if message: + message = message[0] + else: + return HttpResponse('false') + message.delete() + return HttpResponse('true') diff --git a/homepage/models.py b/homepage/models.py deleted file mode 100644 index 71a8362..0000000 --- a/homepage/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/jinja2/base.html b/jinja2/base.html index 3a3e656..9bd7864 100644 --- a/jinja2/base.html +++ b/jinja2/base.html @@ -7,7 +7,7 @@ {% block head %}{% endblock %} @@ -19,7 +19,18 @@ Home {% if request.user.is_authenticated %} {{ request.user.username }} - {{ get_sub_msgs(request=request)|length }} + + +
+ {% for sub in get_sub_msgs(request=request) %} +
+ {{ sub.created_at.strftime('%Y-%m-%d') }} {{ sub }} + X +
+
+ {% endfor %} +
+
{% endif %} {% block header %}{% endblock %} diff --git a/login/migrations/__init__.py b/login/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/login/models.py b/login/models.py deleted file mode 100644 index 71a8362..0000000 --- a/login/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/logout/migrations/__init__.py b/logout/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/logout/models.py b/logout/models.py deleted file mode 100644 index 71a8362..0000000 --- a/logout/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/quest/jinja2/quest/quest_homepage.html b/quest/jinja2/quest/quest_homepage.html index 2d95b79..b5bbb56 100644 --- a/quest/jinja2/quest/quest_homepage.html +++ b/quest/jinja2/quest/quest_homepage.html @@ -38,8 +38,9 @@ {% endif %} {% if request.user.is_authenticated %} -
+ {{ csrf_input }} + Subscribe
{% endif %} diff --git a/quest/urls.py b/quest/urls.py index 19fd333..afae657 100644 --- a/quest/urls.py +++ b/quest/urls.py @@ -10,7 +10,6 @@ app_name = 'quest' urlpatterns = [ path('', views.index, name='index'), path('/new_tag', views.new_tag, name='new_tag'), - path('/subscribe', views.subscribe, name='subscribe'), path('/edit_quest', views.edit_quest, name='edit_quest'), path('//edit_quest', views.edit_quest, name='edit_quest'), path('', views.quest, name='quest'), diff --git a/quest/views.py b/quest/views.py index 0eb1deb..e54bc16 100644 --- a/quest/views.py +++ b/quest/views.py @@ -11,6 +11,8 @@ from django.contrib import messages from django.shortcuts import render, redirect from django.db.models import F from django.conf import settings +from django.urls import reverse +from django.http import HttpResponse from .models import Quest, DiceRoll, PollOption, PollVote, Page, Post from .forms import EditQuestForm, QuestForm, PostForm @@ -128,7 +130,13 @@ def edit_quest(request, quest_id, page_num='0'): subscriber, f"{quest.title} has gone live!", extra_tags='subscription', - deliver_once=False + meta={ + 'url': reverse( + 'quest:quest', + args=(quest.id, 0), + ), + }, + deliver_once=False, ) return redirect('quest:quest',quest_id=quest.id, page_num=page_num) else: @@ -187,13 +195,3 @@ def new_tag(request, quest_id): quest.tags.add(tag) return redirect('quest:quest', quest_id=quest_id, page_num='0') - - -@require_POST -def subscribe(request, quest_id): - """Endpoint for users to subscribe to a quest.""" - if not request.user.is_authenticated: - return redirect('login:index') - request.user.subscriptions.add(Quest.objects.get(id=quest_id)) - messages.success(request, "Subscribed") - return redirect('quest:quest', quest_id=quest_id, page_num='0') diff --git a/set_session/__init__.py b/set_session/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/set_session/apps.py b/set_session/apps.py deleted file mode 100644 index 6b37c76..0000000 --- a/set_session/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class SetSessionConfig(AppConfig): - name = 'set_session' diff --git a/set_session/migrations/__init__.py b/set_session/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/set_session/models.py b/set_session/models.py deleted file mode 100644 index 71a8362..0000000 --- a/set_session/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/set_session/urls.py b/set_session/urls.py deleted file mode 100644 index e8e5107..0000000 --- a/set_session/urls.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python3 -""" -set_session app URL configuration. -""" -from django.urls import path - -from . import views - -app_name = 'set_session' -urlpatterns = [ - path('', views.index, name='index'), -] diff --git a/set_session/views.py b/set_session/views.py deleted file mode 100644 index 24227a6..0000000 --- a/set_session/views.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 -""" -/set_session app views. -""" -from django.http import HttpResponse -from django.views.decorators.http import require_POST - -@require_POST -def index(request): - """ - A simple API endpoint for setting certain values in the users session. - """ - for key, value in request.POST.items(): - if key not in ['hide_header', 'hide_chat']: - continue - if value == 'on': - request.session[key] = True - elif value == 'off': - request.session[key] = False - - return HttpResponse('true') diff --git a/signup/migrations/__init__.py b/signup/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/signup/models.py b/signup/models.py deleted file mode 100644 index 71a8362..0000000 --- a/signup/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/static/base.css b/static/base.css index d57dd03..fde21d0 100644 --- a/static/base.css +++ b/static/base.css @@ -56,7 +56,27 @@ a:hover { } #subscriptions { + position: relative; + display: inline-block; +} + +#subbtn { + width: 1.5em; + height: 1.5em; background-color: orange; + border: none; +} + +#subscriptionsContent { + display: none; + position: absolute; + background-color: #FAFAFA; + border: 1px solid #ccc; + min-width: 25em; +} + +#subscriptions:hover #subscriptionsContent { + display: block; } #headerHidden { diff --git a/static/base.js b/static/base.js index e7b3c76..cf36df5 100644 --- a/static/base.js +++ b/static/base.js @@ -1,10 +1,10 @@ function toggle_cookie(cookie, state) { let xhr = new XMLHttpRequest(); - xhr.open('POST', set_session_url, true); + xhr.open('POST', api_url + '/set_session', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('X-CSRFToken', csrf_token); xhr.send(cookie + '=' + state); - } +} function toggle_header() { if (document.getElementById('header').style.display == 'flex') { document.getElementById('header').style.display = 'none'; @@ -17,3 +17,15 @@ function toggle_header() { toggle_cookie('hide_header', 'off'); } } +function clear_notification(msg_id) { + let xhr = new XMLHttpRequest(); + xhr.open('POST', api_url + '/clear_notification', true); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.setRequestHeader('X-CSRFToken', csrf_token); + xhr.send('msg_id=' + msg_id); + + let elem = document.getElementById('notification-' + msg_id); + elem.parentNode.removeChild(elem); + elem = document.getElementById('subbtn'); + elem.innerText = elem.innerText - 1; +} diff --git a/titivillus/jinja2.py b/titivillus/jinja2.py index 265c871..0bb22f9 100644 --- a/titivillus/jinja2.py +++ b/titivillus/jinja2.py @@ -14,7 +14,7 @@ def get_sub_msgs(**kwargs): sub_msgs = [] for message in messages: if 'subscription' in message.tags: - sub_msgs.append(messages) + sub_msgs.insert(0, message) return sub_msgs def environment(**options): diff --git a/titivillus/urls.py b/titivillus/urls.py index b7c3e40..2bc8805 100644 --- a/titivillus/urls.py +++ b/titivillus/urls.py @@ -9,7 +9,7 @@ urlpatterns = [ path('', include('homepage.urls')), path('admin/', admin.site.urls), path('quest/', include('quest.urls')), - path('set_session/', include('set_session.urls')), + path('api/', include('api.urls')), path('signup/', include('signup.urls')), path('login/', include('login.urls')), path('logout/', include('logout.urls')), diff --git a/todo b/todo index 1437da3..195aa8e 100644 --- a/todo +++ b/todo @@ -14,3 +14,4 @@ Poll vote highlights entire option Total voters per poll Chat archives Adjust quote preview postioning +Better API