forked from mirrors/bookwyrm
DM and notification views
This commit is contained in:
parent
aa8b2c2f2b
commit
b61544b5f5
10 changed files with 146 additions and 95 deletions
|
@ -5,7 +5,7 @@
|
|||
<div class="block">
|
||||
<h1 class="title">Notifications</h1>
|
||||
|
||||
<form name="clear" action="/clear-notifications" method="POST">
|
||||
<form name="clear" action="/notifications" method="POST">
|
||||
{% csrf_token %}
|
||||
<button class="button is-danger is-light" type="submit" class="secondary">Delete notifications</button>
|
||||
</form>
|
||||
|
|
|
@ -75,26 +75,6 @@ class Views(TestCase):
|
|||
self.assertFalse(views.is_api_request(request))
|
||||
|
||||
|
||||
def test_home_tab(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = views.home_tab(request, 'local')
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'feed.html')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
|
||||
def test_direct_messages_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = views.direct_messages_page(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'direct_messages.html')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
|
||||
def test_get_activity_feed(self):
|
||||
''' loads statuses '''
|
||||
rat = models.User.objects.create_user(
|
||||
|
@ -264,26 +244,6 @@ class Views(TestCase):
|
|||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
|
||||
def test_about_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = views.about_page(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'about.html')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
|
||||
def test_notifications_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = views.notifications_page(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'notifications.html')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
|
||||
def test_user_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
request = self.factory.get('')
|
||||
|
|
28
bookwyrm/tests/views/test_direct_message.py
Normal file
28
bookwyrm/tests/views/test_direct_message.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
''' test for app action functionality '''
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm import views
|
||||
|
||||
|
||||
class DirectMessageViews(TestCase):
|
||||
''' dms '''
|
||||
def setUp(self):
|
||||
''' we need basic test data and mocks '''
|
||||
self.factory = RequestFactory()
|
||||
self.local_user = models.User.objects.create_user(
|
||||
'mouse@local.com', 'mouse@mouse.mouse', 'password',
|
||||
local=True, localname='mouse')
|
||||
|
||||
|
||||
def test_direct_messages_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
view = views.DirectMessages.as_view()
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'direct_messages.html')
|
||||
self.assertEqual(result.status_code, 200)
|
41
bookwyrm/tests/views/test_notifications.py
Normal file
41
bookwyrm/tests/views/test_notifications.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
''' test for app action functionality '''
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm import views
|
||||
|
||||
|
||||
class NotificationViews(TestCase):
|
||||
''' notifications '''
|
||||
def setUp(self):
|
||||
''' we need basic test data and mocks '''
|
||||
self.factory = RequestFactory()
|
||||
self.local_user = models.User.objects.create_user(
|
||||
'mouse@local.com', 'mouse@mouse.mouse', 'password',
|
||||
local=True, localname='mouse')
|
||||
|
||||
def test_notifications_page(self):
|
||||
''' there are so many views, this just makes sure it LOADS '''
|
||||
view = views.Notifications.as_view()
|
||||
request = self.factory.get('')
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
self.assertEqual(result.template_name, 'notifications.html')
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_clear_notifications(self):
|
||||
''' erase notifications '''
|
||||
models.Notification.objects.create(
|
||||
user=self.local_user, notification_type='MENTION')
|
||||
models.Notification.objects.create(
|
||||
user=self.local_user, notification_type='MENTION', read=True)
|
||||
self.assertEqual(models.Notification.objects.count(), 2)
|
||||
view = views.Notifications.as_view()
|
||||
request = self.factory.post('')
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(models.Notification.objects.count(), 1)
|
|
@ -61,11 +61,16 @@ urlpatterns = [
|
|||
re_path(r'^(?P<tab>home|local|federated)/?$', views.Feed.as_view()),
|
||||
re_path(r'^discover/?$', views.Discover.as_view()),
|
||||
|
||||
re_path(r'^notifications/?$', vviews.notifications_page),
|
||||
re_path(r'^direct-messages/?$', vviews.direct_messages_page),
|
||||
re_path(r'^notifications/?$', views.Notifications.as_view()),
|
||||
|
||||
re_path(r'^import/?$', vviews.import_page),
|
||||
re_path(r'^direct-messages/?$', views.DirectMessage.as_view()),
|
||||
|
||||
re_path(r'^import/?$', views.Import.as_view()),
|
||||
re_path(r'^import/?$', actions.import_data),
|
||||
re_path(r'^retry-import/?$', actions.retry_import),
|
||||
re_path(r'^import-status/(\d+)/?$', vviews.import_status),
|
||||
|
||||
|
||||
re_path(r'^user-edit/?$', vviews.edit_profile_page),
|
||||
|
||||
# should return a ui view or activitypub json blob as requested
|
||||
|
@ -101,8 +106,6 @@ urlpatterns = [
|
|||
# internal action endpoints
|
||||
re_path(r'^edit-profile/?$', actions.edit_profile),
|
||||
|
||||
re_path(r'^import-data/?$', actions.import_data),
|
||||
re_path(r'^retry-import/?$', actions.retry_import),
|
||||
re_path(r'^resolve-book/?$', actions.resolve_book),
|
||||
re_path(r'^edit-book/(?P<book_id>\d+)/?$', actions.edit_book),
|
||||
re_path(r'^upload-cover/(?P<book_id>\d+)/?$', actions.upload_cover),
|
||||
|
@ -142,7 +145,6 @@ urlpatterns = [
|
|||
re_path(r'^accept-follow-request/?$', actions.accept_follow_request),
|
||||
re_path(r'^delete-follow-request/?$', actions.delete_follow_request),
|
||||
|
||||
re_path(r'^clear-notifications/?$', actions.clear_notifications),
|
||||
|
||||
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -559,13 +559,6 @@ def unfollow(request):
|
|||
return redirect('/user/%s' % user_slug)
|
||||
|
||||
|
||||
@login_required
|
||||
def clear_notifications(request):
|
||||
''' permanently delete notification for user '''
|
||||
request.user.notification_set.filter(read=True).delete()
|
||||
return redirect('/notifications')
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def accept_follow_request(request):
|
||||
|
|
|
@ -3,3 +3,6 @@ from .authentication import Login, Register, Logout
|
|||
from .password import PasswordResetRequest, PasswordReset, ChangePassword
|
||||
from .invite import ManageInvites, Invite
|
||||
from .landing import About, Home, Feed, Discover
|
||||
from .notifications import Notifications
|
||||
from .direct_message import DirectMessage
|
||||
from .import_datra import Import
|
||||
|
|
36
bookwyrm/views/direct_message.py
Normal file
36
bookwyrm/views/direct_message.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
''' non-interactive pages '''
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.paginator import Paginator
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
from bookwyrm.settings import PAGE_LENGTH
|
||||
from .helpers import get_activity_feed
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
class DirectMessage(View):
|
||||
''' dm view '''
|
||||
def get(self, request, page=1):
|
||||
''' like a feed but for dms only '''
|
||||
activities = get_activity_feed(request.user, 'direct')
|
||||
paginated = Paginator(activities, PAGE_LENGTH)
|
||||
activity_page = paginated.page(page)
|
||||
|
||||
prev_page = next_page = None
|
||||
if activity_page.has_next():
|
||||
next_page = '/direct-message/?page=%d#feed' % \
|
||||
activity_page.next_page_number()
|
||||
if activity_page.has_previous():
|
||||
prev_page = '/direct-messages/?page=%d#feed' % \
|
||||
activity_page.previous_page_number()
|
||||
data = {
|
||||
'title': 'Direct Messages',
|
||||
'user': request.user,
|
||||
'activities': activity_page.object_list,
|
||||
'next': next_page,
|
||||
'prev': prev_page,
|
||||
}
|
||||
return TemplateResponse(request, 'direct_messages.html', data)
|
29
bookwyrm/views/notifications.py
Normal file
29
bookwyrm/views/notifications.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
''' non-interactive pages '''
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.shortcuts import redirect
|
||||
from django.views import View
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
class Notifications(View):
|
||||
''' notifications view '''
|
||||
def get(self, request):
|
||||
''' people are interacting with you, get hyped '''
|
||||
notifications = request.user.notification_set.all() \
|
||||
.order_by('-created_date')
|
||||
unread = [n.id for n in notifications.filter(read=False)]
|
||||
data = {
|
||||
'title': 'Notifications',
|
||||
'notifications': notifications,
|
||||
'unread': unread,
|
||||
}
|
||||
notifications.update(read=True)
|
||||
return TemplateResponse(request, 'notifications.html', data)
|
||||
|
||||
def post(self, request):
|
||||
''' permanently delete notification for user '''
|
||||
request.user.notification_set.filter(read=True).delete()
|
||||
return redirect('/notifications')
|
|
@ -64,31 +64,6 @@ def not_found_page(request, _):
|
|||
request, 'notfound.html', {'title': 'Not found'}, status=404)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_GET
|
||||
def direct_messages_page(request, page=1):
|
||||
''' like a feed but for dms only '''
|
||||
activities = get_activity_feed(request.user, 'direct')
|
||||
paginated = Paginator(activities, PAGE_LENGTH)
|
||||
activity_page = paginated.page(page)
|
||||
|
||||
prev_page = next_page = None
|
||||
if activity_page.has_next():
|
||||
next_page = '/direct-message/?page=%d#feed' % \
|
||||
activity_page.next_page_number()
|
||||
if activity_page.has_previous():
|
||||
prev_page = '/direct-messages/?page=%d#feed' % \
|
||||
activity_page.previous_page_number()
|
||||
data = {
|
||||
'title': 'Direct Messages',
|
||||
'user': request.user,
|
||||
'activities': activity_page.object_list,
|
||||
'next': next_page,
|
||||
'prev': prev_page,
|
||||
}
|
||||
return TemplateResponse(request, 'direct_messages.html', data)
|
||||
|
||||
|
||||
def get_activity_feed(
|
||||
user, privacy, local_only=False, following_only=False,
|
||||
queryset=models.Status.objects):
|
||||
|
@ -216,22 +191,6 @@ def import_status(request, job_id):
|
|||
})
|
||||
|
||||
|
||||
@login_required
|
||||
@require_GET
|
||||
def notifications_page(request):
|
||||
''' list notitications '''
|
||||
notifications = request.user.notification_set.all() \
|
||||
.order_by('-created_date')
|
||||
unread = [n.id for n in notifications.filter(read=False)]
|
||||
data = {
|
||||
'title': 'Notifications',
|
||||
'notifications': notifications,
|
||||
'unread': unread,
|
||||
}
|
||||
notifications.update(read=True)
|
||||
return TemplateResponse(request, 'notifications.html', data)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_GET
|
||||
def user_page(request, username):
|
||||
|
|
Loading…
Reference in a new issue