-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
NotificationRepo.scala
72 lines (48 loc) · 2.59 KB
/
NotificationRepo.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package lila.notify
import reactivemongo.api.bson.ElementProducer
import lila.db.dsl.{ *, given }
import lila.core.notify.UnreadCount
final private class NotificationRepo(colls: NotifyColls)(using Executor):
import BSONHandlers.given
private val coll = colls.notif
def insert(notification: Notification) =
coll.insert.one(notification).void
def insertMany(notifications: Iterable[Notification]): Funit =
coll.insert.many(notifications).void
def remove(notifies: UserId, selector: Bdoc): Funit =
coll.delete.one(userNotificationsQuery(notifies) ++ selector).void
def markAllRead(notifies: UserId): Funit =
markManyRead(unreadOnlyQuery(notifies)).void
def markAllRead(notifies: Iterable[UserId]): Funit =
markManyRead(unreadOnlyQuery(notifies)).void
def markManyRead(selector: Bdoc): Fu[Int] =
coll.update.one(selector, $set("read" -> true), multi = true).dmap(_.n)
def expireAndCount(userId: UserId): Fu[UnreadCount] = for
count <- UnreadCount.from(coll.countSel(unreadOnlyQuery(userId)))
expired <- (count > 0).so(markManyRead(expiredQuery(userId)))
yield count - expired
def hasRecent(note: Notification, criteria: ElementProducer, unreadSince: Duration): Fu[Boolean] =
hasFresh(note.notifies, note.content.key, criteria, matchRecentOrUnreadSince(unreadSince))
def hasRecentPrivateMessageFrom(to: UserId, from: UserId): Fu[Boolean] =
hasFresh(to, tpe = "privateMessage", criteria = "content.user" -> from.value, matchUnreadSince(3.days))
private def matchSince(since: Duration) =
$doc("createdAt".$gt(nowInstant.minus(since)))
private def matchUnreadSince(unreadSince: Duration) =
$doc("read" -> false, "createdAt".$gt(nowInstant.minus(unreadSince)))
private def matchRecentOrUnreadSince(since: Duration) =
$or(matchSince(10.minutes), matchUnreadSince(since))
private def hasFresh(
to: UserId,
tpe: String,
criteria: ElementProducer,
freshnessSelector: Bdoc
): Fu[Boolean] =
coll.exists($doc("notifies" -> to, "content.type" -> tpe, criteria) ++ freshnessSelector)
def exists(notifies: UserId, selector: Bdoc): Fu[Boolean] =
coll.exists(userNotificationsQuery(notifies) ++ selector)
val recentSort = $sort.desc("createdAt")
def userNotificationsQuery(userId: UserId) = $doc("notifies" -> userId)
private def unreadOnlyQuery(userId: UserId) = $doc("notifies" -> userId, "read" -> false)
private def unreadOnlyQuery(userIds: Iterable[UserId]) =
$doc("notifies".$in(userIds), "read" -> false)
private def expiredQuery(userId: UserId) = unreadOnlyQuery(userId) ++ $doc("expiresAt".$lt(nowInstant))