109 lines
3.2 KiB
Python
109 lines
3.2 KiB
Python
import strawberry
|
|
from sqlalchemy import and_
|
|
from orm.author import Author
|
|
from services.auth import login_required
|
|
from services.db import local_session
|
|
|
|
|
|
@strawberry.type
|
|
class NotificationSeen:
|
|
notification: int # notification id
|
|
viewer: int # author id
|
|
|
|
|
|
@strawberry.type
|
|
class Notification:
|
|
id: int
|
|
action: str # create update delete join follow etc.
|
|
entity: str # REACTION SHOUT
|
|
created_at: int
|
|
seen: list[NotificationSeen]
|
|
data: str # JSON data
|
|
occurrences: int
|
|
|
|
|
|
@strawberry.type
|
|
class NotificationsQueryResult:
|
|
notifications: list[Notification]
|
|
unread: int
|
|
|
|
|
|
@strawberry.type
|
|
class NotificationSeenResult:
|
|
error: str
|
|
|
|
|
|
def notification_seen_by_viewer(viewer_id, notification_id, session):
|
|
seen = (
|
|
session.query(NotificationSeen)
|
|
.filter(NotificationSeen.viewer == viewer_id, NotificationSeen.notification == notification_id)
|
|
.first()
|
|
)
|
|
|
|
return seen is not None
|
|
|
|
|
|
@strawberry.type
|
|
class Query:
|
|
@login_required
|
|
@strawberry.field
|
|
async def load_notifications(self, info, limit: int = 50, offset: int = 0) -> dict:
|
|
"""непрочитанные уведомления"""
|
|
user_id = info.context["user_id"]
|
|
|
|
with local_session() as session:
|
|
author = session.query(Author).filter(Author.user == user_id).first()
|
|
|
|
nslist = (
|
|
session.query(Notification)
|
|
.outerjoin(
|
|
NotificationSeen,
|
|
and_(NotificationSeen.viewer == author.id, NotificationSeen.notification == Notification.id),
|
|
)
|
|
.limit(limit)
|
|
.offset(offset)
|
|
.all()
|
|
)
|
|
|
|
for notification in nslist:
|
|
notification.seen_by_viewer = notification_seen_by_viewer(author.id, notification.id, session)
|
|
|
|
unread = sum(1 for n in nslist if not n.seen_by_viewer)
|
|
|
|
return {"notifications": nslist, "unread": unread}
|
|
|
|
|
|
@strawberry.type
|
|
class Mutation:
|
|
@strawberry.mutation
|
|
@login_required
|
|
async def mark_notification_as_read(self, info, notification_id: int) -> NotificationSeenResult:
|
|
user_id = info.context["user_id"]
|
|
try:
|
|
with local_session() as session:
|
|
author = session.query(Author).filter(Author.user == user_id).first()
|
|
ns = NotificationSeen({"notification": notification_id, "viewer": author.id})
|
|
session.add(ns)
|
|
session.commit()
|
|
except Exception as e:
|
|
session.rollback()
|
|
print(f"[mark_notification_as_read] error: {str(e)}")
|
|
return {}
|
|
|
|
@strawberry.mutation
|
|
@login_required
|
|
async def mark_all_notifications_as_read(self, info) -> NotificationSeenResult:
|
|
user_id = info.context["user_id"]
|
|
|
|
with local_session() as session:
|
|
try:
|
|
author = session.query(Author).filter(Author.user == user_id).first()
|
|
_nslist = session.quuery(NotificationSeen).filter(NotificationSeen.viewer == author.id).all()
|
|
except Exception as e:
|
|
session.rollback()
|
|
print(f"[mark_all_notifications_as_read] error: {str(e)}")
|
|
return {}
|
|
|
|
|
|
schema = strawberry.Schema(query=Query, mutation=Mutation)
|