diff --git a/bookwyrm/static/js/block_href.js b/bookwyrm/static/js/block_href.js new file mode 100644 index 00000000..fc20a6ab --- /dev/null +++ b/bookwyrm/static/js/block_href.js @@ -0,0 +1,21 @@ +/* exported BlockHref */ + +let BlockHref = new class { + constructor() { + document.querySelectorAll('[data-href]') + .forEach(t => t.addEventListener('click', this.followLink.bind(this))); + } + + /** + * Follow a fake link + * + * @param {Event} event + * @return {undefined} + */ + followLink(event) { + const url = event.currentTarget.dataset.href; + + window.location.href = url; + } +}(); + diff --git a/bookwyrm/templates/notifications.html b/bookwyrm/templates/notifications.html deleted file mode 100644 index ae5cd67b..00000000 --- a/bookwyrm/templates/notifications.html +++ /dev/null @@ -1,160 +0,0 @@ -{% extends 'layout.html' %} -{% load i18n %} -{% load bookwyrm_tags %} -{% load humanize %} - -{% block title %}{% trans "Notifications" %}{% endblock %} - -{% block content %} -
-
-

{% trans "Notifications" %}

-
- -
- {% csrf_token %} - -
-
- -
- -
- -
- {% for notification in notifications %} - {% related_status notification as related_status %} -
-
-
- {% if notification.notification_type == 'MENTION' %} - - {% elif notification.notification_type == 'REPLY' %} - - {% elif notification.notification_type == 'FOLLOW' or notification.notification_type == 'FOLLOW_REQUEST' %} - - {% elif notification.notification_type == 'BOOST' %} - - {% elif notification.notification_type == 'FAVORITE' %} - - {% elif notification.notification_type == 'IMPORT' %} - - {% elif notification.notification_type == 'ADD' %} - - {% elif notification.notification_type == 'REPORT' %} - - {% endif %} -
-
-
-

- {# DESCRIPTION #} - {% if notification.related_user %} - - {% include 'snippets/avatar.html' with user=notification.related_user %} - {{ notification.related_user.display_name }} - - {% if notification.notification_type == 'FAVORITE' %} - {% if related_status.status_type == 'Review' %} - {% blocktrans with book_title=related_status.book.title related_path=related_status.local_path %}favorited your review of {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Comment' %} - {% blocktrans with book_title=related_status.book.title related_path=related_status.local_path %}favorited your comment on {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Quotation' %} - {% blocktrans with book_title=related_status.book.title related_path=related_status.local_path %}favorited your quote from {{ book_title }}{% endblocktrans %} - {% else %} - {% blocktrans with related_path=related_status.local_path %}favorited your status{% endblocktrans %} - {% endif %} - - {% elif notification.notification_type == 'MENTION' %} - {% if related_status.status_type == 'Review' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}mentioned you in a review of {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Comment' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}mentioned you in a comment on {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Quotation' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}mentioned you in a quote from {{ book_title }}{% endblocktrans %} - {% else %} - {% blocktrans with related_path=related_status.local_path %}mentioned you in a status{% endblocktrans %} - {% endif %} - - {% elif notification.notification_type == 'REPLY' %} - {% if related_status.status_type == 'Review' %} - {% blocktrans with related_path=related_status.local_path parent_path=related_status.reply_parent.local_path book_title=related_status.reply_parent.book.title %}replied to your review of {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Comment' %} - {% blocktrans with related_path=related_status.local_path parent_path=related_status.reply_parent.local_path book_title=related_status.reply_parent.book.title %}replied to your comment on {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Quotation' %} - {% blocktrans with related_path=related_status.local_path parent_path=related_status.reply_parent.local_path book_title=related_status.reply_parent.book.title %}replied to your quote from {{ book_title }}{% endblocktrans %} - {% else %} - {% blocktrans with related_path=related_status.local_path parent_path=related_status.reply_parent.local_path %}replied to your status{% endblocktrans %} - {% endif %} - - {% elif notification.notification_type == 'FOLLOW' %} - {% trans "followed you" %} - {% include 'snippets/follow_button.html' with user=notification.related_user %} - {% elif notification.notification_type == 'FOLLOW_REQUEST' %} - {% trans "sent you a follow request" %} -

- {% include 'snippets/follow_request_buttons.html' with user=notification.related_user %} -
- {% elif notification.notification_type == 'BOOST' %} - {% if related_status.status_type == 'Review' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your review of {{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Comment' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your comment on{{ book_title }}{% endblocktrans %} - {% elif related_status.status_type == 'Quotation' %} - {% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your quote from {{ book_title }}{% endblocktrans %} - {% else %} - {% blocktrans with related_path=related_status.local_path %}boosted your status{% endblocktrans %} - {% endif %} - {% elif notification.notification_type == 'ADD' %} - {% if notification.related_list_item.approved %} - {% blocktrans with book_path=notification.related_list_item.book.local_path book_title=notification.related_list_item.book.title list_path=notification.related_list_item.book_list.local_path list_name=notification.related_list_item.book_list.name %} added {{ book_title }} to your list "{{ list_name }}"{% endblocktrans %} - {% else %} - {% blocktrans with book_path=notification.related_list_item.book.local_path book_title=notification.related_list_item.book.title list_path=notification.related_list_item.book_list.local_path list_name=notification.related_list_item.book_list.name %} suggested adding {{ book_title }} to your list "{{ list_name }}"{% endblocktrans %} - {% endif %} - {% endif %} - {% elif notification.related_import %} - {% url 'import-status' notification.related_import.id as url %} - {% blocktrans %}Your import completed.{% endblocktrans %} - {% elif notification.related_report %} - {% url 'settings-report' notification.related_report.id as path %} - {% blocktrans with related_id=path %}A new report needs moderation.{% endblocktrans %} - {% endif %} -

-
- {% if related_status %} -
- {# PREVIEW #} -
-
-
- {% include 'snippets/status_preview.html' with status=related_status %} -
-
- {{ related_status.published_date|timesince }} - {% include 'snippets/privacy-icons.html' with item=related_status %} -
-
-
-
- {% endif %} -
-
-
- {% endfor %} - - {% if not notifications %} -

{% trans "You're all caught up!" %}

- {% endif %} -
-{% endblock %} diff --git a/bookwyrm/templates/notifications/item.html b/bookwyrm/templates/notifications/item.html new file mode 100644 index 00000000..348d8950 --- /dev/null +++ b/bookwyrm/templates/notifications/item.html @@ -0,0 +1,20 @@ +{# load the right template #} +{% if notification.notification_type == 'MENTION' %} + {% include 'notifications/items/mention.html' %} +{% elif notification.notification_type == 'REPLY' %} + {% include 'notifications/items/reply.html' %} +{% elif notification.notification_type == 'BOOST' %} + {% include 'notifications/items/boost.html' %} +{% elif notification.notification_type == 'FAVORITE' %} + {% include 'notifications/items/fav.html' %} +{% elif notification.notification_type == 'FOLLOW' %} + {% include 'notifications/items/follow.html' %} +{% elif notification.notification_type == 'FOLLOW_REQUEST' %} + {% include 'notifications/items/follow_request.html' %} +{% elif notification.notification_type == 'IMPORT' %} + {% include 'notifications/items/import.html' %} +{% elif notification.notification_type == 'ADD' %} + {% include 'notifications/items/add.html' %} +{% elif notification.notification_type == 'REPORT' %} + {% include 'notifications/items/report.html' %} +{% endif %} diff --git a/bookwyrm/templates/notifications/items/add.html b/bookwyrm/templates/notifications/items/add.html new file mode 100644 index 00000000..0e653aeb --- /dev/null +++ b/bookwyrm/templates/notifications/items/add.html @@ -0,0 +1,42 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} +{% if notification.related_list_item.approved %} + {{ notification.related_list_item.book_list.local_path }} +{% else %} + {% url 'list-curate' notification.related_list_item.book_list.id %} +{% endif %} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} +{% with book_path=notification.related_list_item.book.local_path %} +{% with book_title=notification.related_list_item.book|book_title %} +{% with list_name=notification.related_list_item.book_list.name %} + + {% if notification.related_list_item.approved %} + {% blocktrans trimmed with list_path=notification.related_list_item.book_list.local_path %} + + added {{ book_title }} to your list "{{ list_name }}" + + {% endblocktrans %} + {% else %} + {% url 'list-curate' notification.related_list_item.book_list.id as list_path %} + {% blocktrans trimmed with list_path=list_path %} + + suggested adding {{ book_title }} to your list "{{ list_name }}" + + {% endblocktrans %} + {% endif %} + +{% endwith %} +{% endwith %} +{% endwith %} +{% endblock %} + diff --git a/bookwyrm/templates/notifications/items/boost.html b/bookwyrm/templates/notifications/items/boost.html new file mode 100644 index 00000000..5f8962b3 --- /dev/null +++ b/bookwyrm/templates/notifications/items/boost.html @@ -0,0 +1,61 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} + {{ notification.related_status.local_path }} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% with related_status.book|book_title as book_title %} + {% with related_status.local_path as related_path %} + + {% if related_status.status_type == 'Review' %} + {% blocktrans trimmed %} + + boosted your review of {{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Comment' %} + {% blocktrans trimmed %} + + boosted your comment on{{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Quotation' %} + {% blocktrans trimmed %} + + boosted your quote from {{ book_title }} + + {% endblocktrans %} + {% else %} + {% blocktrans trimmed %} + + boosted your status + + {% endblocktrans %} + {% endif %} + + {% endwith %} + {% endwith %} +{% endblock %} + + +{% block preview %} +
+
+
+ {% include 'snippets/status_preview.html' with status=related_status %} +
+
+ {{ related_status.published_date|timesince }} + {% include 'snippets/privacy-icons.html' with item=related_status %} +
+
+
+{% endblock %} diff --git a/bookwyrm/templates/notifications/items/fav.html b/bookwyrm/templates/notifications/items/fav.html new file mode 100644 index 00000000..d430598e --- /dev/null +++ b/bookwyrm/templates/notifications/items/fav.html @@ -0,0 +1,61 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} + {{ notification.related_status.local_path }} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% with related_status.book|book_title as book_title %} + {% with related_status.local_path as related_path %} + + {% if related_status.status_type == 'Review' %} + {% blocktrans trimmed %} + + favorited your review of {{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Comment' %} + {% blocktrans trimmed %} + + favorited your comment on{{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Quotation' %} + {% blocktrans trimmed %} + + favorited your quote from {{ book_title }} + + {% endblocktrans %} + {% else %} + {% blocktrans trimmed %} + + favorited your status + + {% endblocktrans %} + {% endif %} + + {% endwith %} + {% endwith %} +{% endblock %} + + +{% block preview %} +
+
+
+ {% include 'snippets/status_preview.html' with status=related_status %} +
+
+ {{ related_status.published_date|timesince }} + {% include 'snippets/privacy-icons.html' with item=related_status %} +
+
+
+{% endblock %} diff --git a/bookwyrm/templates/notifications/items/follow.html b/bookwyrm/templates/notifications/items/follow.html new file mode 100644 index 00000000..7220d5d1 --- /dev/null +++ b/bookwyrm/templates/notifications/items/follow.html @@ -0,0 +1,17 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} + {{ notification.related_user.local_path }} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% trans "followed you" %} + {% include 'snippets/follow_button.html' with user=notification.related_user %} +{% endblock %} diff --git a/bookwyrm/templates/notifications/items/follow_request.html b/bookwyrm/templates/notifications/items/follow_request.html new file mode 100644 index 00000000..febb0a50 --- /dev/null +++ b/bookwyrm/templates/notifications/items/follow_request.html @@ -0,0 +1,15 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% trans "sent you a follow request" %} +
+ {% include 'snippets/follow_request_buttons.html' with user=notification.related_user %} +
+{% endblock %} diff --git a/bookwyrm/templates/notifications/items/import.html b/bookwyrm/templates/notifications/items/import.html new file mode 100644 index 00000000..f3c8b5c0 --- /dev/null +++ b/bookwyrm/templates/notifications/items/import.html @@ -0,0 +1,15 @@ +{% extends 'notifications/items/item_layout.html' %} +{% load i18n %} + +{% block primary_link %}{% spaceless %} +{% url 'import-status' notification.related_import.id %} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% url 'import-status' notification.related_import.id as url %} + {% blocktrans %}Your import completed.{% endblocktrans %} +{% endblock %} diff --git a/bookwyrm/templates/notifications/items/item_layout.html b/bookwyrm/templates/notifications/items/item_layout.html new file mode 100644 index 00000000..382978d4 --- /dev/null +++ b/bookwyrm/templates/notifications/items/item_layout.html @@ -0,0 +1,29 @@ +{% load humanize %} +{% load bookwyrm_tags %} +{% related_status notification as related_status %} +
+
+
+ {% block icon %}{% endblock %} +
+
+
+

+ {% if notification.related_user %} + + {% include 'snippets/avatar.html' with user=notification.related_user %} + {{ notification.related_user.display_name }} + + {% endif %} + {% block description %}{% endblock %} +

+
+ {% if related_status %} +
+ {% block preview %}{% endblock %} +
+ {% endif %} +
+
+
+ diff --git a/bookwyrm/templates/notifications/items/mention.html b/bookwyrm/templates/notifications/items/mention.html new file mode 100644 index 00000000..cda77163 --- /dev/null +++ b/bookwyrm/templates/notifications/items/mention.html @@ -0,0 +1,62 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} + {{ notification.related_status.local_path }} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + + +{% block description %} + {% with related_status.book|book_title as book_title %} + {% with related_status.local_path as related_path %} + + {% if related_status.status_type == 'Review' %} + {% blocktrans trimmed %} + + mentioned you in a review of {{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Comment' %} + {% blocktrans trimmed %} + + mentioned you in a comment on {{ book_title }} + + {% endblocktrans %} + {% elif related_status.status_type == 'Quotation' %} + {% blocktrans trimmed %} + + mentioned you in a quote from {{ book_title }} + + {% endblocktrans %} + {% else %} + {% blocktrans trimmed %} + + mentioned you in a status + + {% endblocktrans %} + {% endif %} + + {% endwith %} + {% endwith %} +{% endblock %} + + +{% block preview %} +
+
+
+ {% include 'snippets/status_preview.html' with status=related_status %} +
+
+ {{ related_status.published_date|timesince }} + {% include 'snippets/privacy-icons.html' with item=related_status %} +
+
+
+{% endblock %} diff --git a/bookwyrm/templates/notifications/items/reply.html b/bookwyrm/templates/notifications/items/reply.html new file mode 100644 index 00000000..883bbbb5 --- /dev/null +++ b/bookwyrm/templates/notifications/items/reply.html @@ -0,0 +1,65 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} +{% load utilities %} + +{% block primary_link %}{% spaceless %} + {{ notification.related_status.local_path }} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + + +{% block description %} + {% with related_status.reply_parent.book|book_title as book_title %} + {% with related_status.local_path as related_path %} + {% with related_status.reply_parent.local_path as parent_path %} + + {% if related_status.reply_parent.status_type == 'Review' %} + {% blocktrans trimmed %} + + replied to your review of {{ book_title }} + + {% endblocktrans %} + {% elif related_status.reply_parent.status_type == 'Comment' %} + {% blocktrans trimmed %} + + replied to your comment on {{ book_title }} + + {% endblocktrans %} + {% elif related_status.reply_parent.status_type == 'Quotation' %} + {% blocktrans trimmed %} + + replied to your quote from {{ book_title }} + + {% endblocktrans %} + {% else %} + {% blocktrans trimmed %} + + replied to your status + + {% endblocktrans %} + {% endif %} + + {% endwith %} + {% endwith %} + {% endwith %} +{% endblock %} + + + +{% block preview %} +
+
+
+ {% include 'snippets/status_preview.html' with status=related_status %} +
+
+ {{ related_status.published_date|timesince }} + {% include 'snippets/privacy-icons.html' with item=related_status %} +
+
+
+{% endblock %} diff --git a/bookwyrm/templates/notifications/items/report.html b/bookwyrm/templates/notifications/items/report.html new file mode 100644 index 00000000..f537b525 --- /dev/null +++ b/bookwyrm/templates/notifications/items/report.html @@ -0,0 +1,16 @@ +{% extends 'notifications/items/item_layout.html' %} + +{% load i18n %} + +{% block primary_link %}{% spaceless %} + {% url 'settings-report' notification.related_report.id %} +{% endspaceless %}{% endblock %} + +{% block icon %} + +{% endblock %} + +{% block description %} + {% url 'settings-report' notification.related_report.id as path %} + {% blocktrans %}A new report needs moderation.{% endblocktrans %} +{% endblock %} diff --git a/bookwyrm/templates/notifications/notifications_page.html b/bookwyrm/templates/notifications/notifications_page.html new file mode 100644 index 00000000..dc6acbdb --- /dev/null +++ b/bookwyrm/templates/notifications/notifications_page.html @@ -0,0 +1,52 @@ +{% extends 'layout.html' %} +{% load i18n %} +{% load static %} + +{% block title %}{% trans "Notifications" %}{% endblock %} + +{% block content %} +
+
+

{% trans "Notifications" %}

+
+ +
+ {% csrf_token %} + {% spaceless %} + + {% endspaceless %} +
+
+ +
+ +
+ +
+ {% for notification in notifications %} + {% include 'notifications/item.html' %} + {% endfor %} + + {% if not notifications %} +

{% trans "You're all caught up!" %}

+ {% endif %} +
+{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/bookwyrm/tests/views/test_notifications.py b/bookwyrm/tests/views/test_notifications.py index d97616ce..dd28a811 100644 --- a/bookwyrm/tests/views/test_notifications.py +++ b/bookwyrm/tests/views/test_notifications.py @@ -6,6 +6,7 @@ from django.test.client import RequestFactory from bookwyrm import models from bookwyrm import views +from bookwyrm.tests.validate_html import validate_html class NotificationViews(TestCase): @@ -24,16 +25,53 @@ class NotificationViews(TestCase): local=True, localname="mouse", ) + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + self.status = models.Status.objects.create( + content="hi", + user=self.local_user, + ) models.SiteSettings.objects.create() - def test_notifications_page(self): + def test_notifications_page_empty(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) - result.render() + validate_html(result.render()) + self.assertEqual(result.status_code, 200) + + def test_notifications_page_notifications(self): + """there are so many views, this just makes sure it LOADS""" + models.Notification.objects.create( + user=self.local_user, + notification_type="FAVORITE", + related_status=self.status, + ) + models.Notification.objects.create( + user=self.local_user, + notification_type="BOOST", + related_status=self.status, + ) + models.Notification.objects.create( + user=self.local_user, + notification_type="MENTION", + related_status=self.status, + ) + self.status.reply_parent = self.status + self.status.save(broadcast=False) + models.Notification.objects.create( + user=self.local_user, + notification_type="REPLY", + related_status=self.status, + ) + view = views.Notifications.as_view() + request = self.factory.get("") + request.user = self.local_user + result = view(request) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_clear_notifications(self): diff --git a/bookwyrm/views/notifications.py b/bookwyrm/views/notifications.py index d6897f39..0a7a6200 100644 --- a/bookwyrm/views/notifications.py +++ b/bookwyrm/views/notifications.py @@ -13,7 +13,20 @@ class Notifications(View): def get(self, request, notification_type=None): """people are interacting with you, get hyped""" - notifications = request.user.notification_set.all().order_by("-created_date") + notifications = ( + request.user.notification_set.all() + .order_by("-created_date") + .select_related( + "related_status", + "related_status__reply_parent", + "related_import", + "related_report", + "related_user", + "related_book", + "related_list_item", + "related_list_item__book", + ) + ) if notification_type == "mentions": notifications = notifications.filter( notification_type__in=["REPLY", "MENTION", "TAG"] @@ -24,7 +37,7 @@ class Notifications(View): "unread": unread, } notifications.update(read=True) - return TemplateResponse(request, "notifications.html", data) + return TemplateResponse(request, "notifications/notifications_page.html", data) def post(self, request): """permanently delete notification for user"""