DM and notification views

This commit is contained in:
Mouse Reeve 2021-01-12 11:07:29 -08:00
parent aa8b2c2f2b
commit b61544b5f5
10 changed files with 146 additions and 95 deletions

View file

@ -5,7 +5,7 @@
<div class="block"> <div class="block">
<h1 class="title">Notifications</h1> <h1 class="title">Notifications</h1>
<form name="clear" action="/clear-notifications" method="POST"> <form name="clear" action="/notifications" method="POST">
{% csrf_token %} {% csrf_token %}
<button class="button is-danger is-light" type="submit" class="secondary">Delete notifications</button> <button class="button is-danger is-light" type="submit" class="secondary">Delete notifications</button>
</form> </form>

View file

@ -75,26 +75,6 @@ class Views(TestCase):
self.assertFalse(views.is_api_request(request)) 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): def test_get_activity_feed(self):
''' loads statuses ''' ''' loads statuses '''
rat = models.User.objects.create_user( rat = models.User.objects.create_user(
@ -264,26 +244,6 @@ class Views(TestCase):
self.assertEqual(result.status_code, 200) 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): def test_user_page(self):
''' there are so many views, this just makes sure it LOADS ''' ''' there are so many views, this just makes sure it LOADS '''
request = self.factory.get('') request = self.factory.get('')

View 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)

View 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)

View file

@ -61,11 +61,16 @@ urlpatterns = [
re_path(r'^(?P<tab>home|local|federated)/?$', views.Feed.as_view()), re_path(r'^(?P<tab>home|local|federated)/?$', views.Feed.as_view()),
re_path(r'^discover/?$', views.Discover.as_view()), re_path(r'^discover/?$', views.Discover.as_view()),
re_path(r'^notifications/?$', vviews.notifications_page), re_path(r'^notifications/?$', views.Notifications.as_view()),
re_path(r'^direct-messages/?$', vviews.direct_messages_page),
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'^import-status/(\d+)/?$', vviews.import_status),
re_path(r'^user-edit/?$', vviews.edit_profile_page), re_path(r'^user-edit/?$', vviews.edit_profile_page),
# should return a ui view or activitypub json blob as requested # should return a ui view or activitypub json blob as requested
@ -101,8 +106,6 @@ urlpatterns = [
# internal action endpoints # internal action endpoints
re_path(r'^edit-profile/?$', actions.edit_profile), 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'^resolve-book/?$', actions.resolve_book),
re_path(r'^edit-book/(?P<book_id>\d+)/?$', actions.edit_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), 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'^accept-follow-request/?$', actions.accept_follow_request),
re_path(r'^delete-follow-request/?$', actions.delete_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) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View file

@ -559,13 +559,6 @@ def unfollow(request):
return redirect('/user/%s' % user_slug) 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 @login_required
@require_POST @require_POST
def accept_follow_request(request): def accept_follow_request(request):

View file

@ -3,3 +3,6 @@ from .authentication import Login, Register, Logout
from .password import PasswordResetRequest, PasswordReset, ChangePassword from .password import PasswordResetRequest, PasswordReset, ChangePassword
from .invite import ManageInvites, Invite from .invite import ManageInvites, Invite
from .landing import About, Home, Feed, Discover from .landing import About, Home, Feed, Discover
from .notifications import Notifications
from .direct_message import DirectMessage
from .import_datra import Import

View 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)

View 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')

View file

@ -64,31 +64,6 @@ def not_found_page(request, _):
request, 'notfound.html', {'title': 'Not found'}, status=404) 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( def get_activity_feed(
user, privacy, local_only=False, following_only=False, user, privacy, local_only=False, following_only=False,
queryset=models.Status.objects): 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 @csrf_exempt
@require_GET @require_GET
def user_page(request, username): def user_page(request, username):