Add support to dismiss notifications (#605)
This commit is contained in:
parent
1cc9c16b8c
commit
5f49f9b2bb
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.2.2 on 2023-07-09 17:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("activities", "0017_stator_next_change"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="timelineevent",
|
||||
name="dismissed",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -55,6 +55,7 @@ class TimelineEvent(models.Model):
|
|||
|
||||
published = models.DateTimeField(default=timezone.now)
|
||||
seen = models.BooleanField(default=False)
|
||||
dismissed = models.BooleanField(default=False)
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class TimelineService:
|
|||
def notifications(self, types: list[str]) -> models.QuerySet[TimelineEvent]:
|
||||
return (
|
||||
self.event_queryset()
|
||||
.filter(identity=self.identity, type__in=types)
|
||||
.filter(identity=self.identity, type__in=types, dismissed=False)
|
||||
.order_by("-created")
|
||||
)
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ urlpatterns = [
|
|||
path("v1/statuses/<id>/source", statuses.status_source),
|
||||
# Notifications
|
||||
path("v1/notifications", notifications.notifications),
|
||||
path("v1/notifications/clear", notifications.dismiss_notifications),
|
||||
path("v1/notifications/<id>", notifications.get_notification),
|
||||
path("v1/notifications/<id>/dismiss", notifications.dismiss_notification),
|
||||
# Polls
|
||||
path("v1/polls/<id>", polls.get_poll),
|
||||
path("v1/polls/<id>/votes", polls.vote_poll),
|
||||
|
|
|
@ -72,3 +72,29 @@ def get_notification(
|
|||
id=id,
|
||||
)
|
||||
return schemas.Notification.from_timeline_event(notification)
|
||||
|
||||
|
||||
@scope_required("write:notifications")
|
||||
@api_view.post
|
||||
def dismiss_notifications(request: HttpRequest) -> dict:
|
||||
TimelineService(request.identity).notifications(
|
||||
list(NOTIFICATION_TYPES.values())
|
||||
).update(dismissed=True)
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
@scope_required("write:notifications")
|
||||
@api_view.post
|
||||
def dismiss_notification(request: HttpRequest, id: str) -> dict:
|
||||
notification = get_object_or_404(
|
||||
TimelineService(request.identity).notifications(
|
||||
list(NOTIFICATION_TYPES.values())
|
||||
),
|
||||
id=id,
|
||||
)
|
||||
|
||||
notification.dismissed = True
|
||||
notification.save()
|
||||
|
||||
return {}
|
||||
|
|
|
@ -11,11 +11,10 @@ def test_notifications(api_client, identity, remote_identity):
|
|||
subject_identity=remote_identity,
|
||||
)
|
||||
|
||||
response = api_client.get("/api/v1/notifications").json()
|
||||
|
||||
assert len(response) == 1
|
||||
assert response[0]["type"] == "follow"
|
||||
assert response[0]["account"]["id"] == str(remote_identity.id)
|
||||
data = api_client.get("/api/v1/notifications").json()
|
||||
assert len(data) == 1
|
||||
assert data[0]["type"] == "follow"
|
||||
assert data[0]["account"]["id"] == str(remote_identity.id)
|
||||
|
||||
event.delete()
|
||||
|
||||
|
@ -28,8 +27,55 @@ def test_get_notification(api_client, identity, remote_identity):
|
|||
subject_identity=remote_identity,
|
||||
)
|
||||
|
||||
response = api_client.get(f"/api/v1/notifications/{event.id}").json()
|
||||
assert response["type"] == "follow"
|
||||
assert response["account"]["id"] == str(remote_identity.id)
|
||||
data = api_client.get(f"/api/v1/notifications/{event.id}").json()
|
||||
assert data["type"] == "follow"
|
||||
assert data["account"]["id"] == str(remote_identity.id)
|
||||
|
||||
event.delete()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dismiss_notifications(api_client, identity, identity2, remote_identity):
|
||||
TimelineEvent.objects.create(
|
||||
identity=identity,
|
||||
type=TimelineEvent.Types.followed,
|
||||
subject_identity=identity2,
|
||||
)
|
||||
TimelineEvent.objects.create(
|
||||
identity=identity,
|
||||
type=TimelineEvent.Types.followed,
|
||||
subject_identity=remote_identity,
|
||||
)
|
||||
|
||||
data = api_client.get("/api/v1/notifications").json()
|
||||
assert len(data) == 2
|
||||
|
||||
response = api_client.post("/api/v1/notifications/clear", {})
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {}
|
||||
|
||||
data = api_client.get("/api/v1/notifications").json()
|
||||
assert len(data) == 0
|
||||
|
||||
TimelineEvent.objects.filter(identity=identity).delete()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dismiss_notification(api_client, identity, remote_identity):
|
||||
event = TimelineEvent.objects.create(
|
||||
identity=identity,
|
||||
type=TimelineEvent.Types.followed,
|
||||
subject_identity=remote_identity,
|
||||
)
|
||||
|
||||
data = api_client.get("/api/v1/notifications").json()
|
||||
assert len(data) == 1
|
||||
|
||||
response = api_client.post(f"/api/v1/notifications/{event.id}/dismiss", {})
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {}
|
||||
|
||||
data = api_client.get("/api/v1/notifications").json()
|
||||
assert len(data) == 0
|
||||
|
||||
TimelineEvent.objects.filter(identity=identity).delete()
|
||||
|
|
Loading…
Reference in New Issue