lila/modules/msg/src/main/MsgSearch.scala

81 lines
2.4 KiB
Scala
Raw Normal View History

2020-01-25 09:31:11 -07:00
package lila.msg
import reactivemongo.api.bson._
import reactivemongo.api.ReadPreference
2020-01-25 09:31:11 -07:00
import lila.common.LightUser
import lila.db.dsl._
2020-06-02 09:22:22 -06:00
import lila.user.User
import lila.common.Bus
import lila.hub.actorApi.clas.ClasMatesAndTeachers
import lila.hub.actorApi.user.KidId
2020-01-25 09:31:11 -07:00
final class MsgSearch(
colls: MsgColls,
2020-06-02 09:22:22 -06:00
userCache: lila.user.Cached,
2020-01-25 09:31:11 -07:00
lightUserApi: lila.user.LightUserApi,
relationApi: lila.relation.RelationApi
)(implicit ec: scala.concurrent.ExecutionContext, system: akka.actor.ActorSystem) {
2020-01-25 09:31:11 -07:00
import BsonHandlers._
def apply(me: User, q: String): Fu[MsgSearch.Result] =
if (me.kid) forKid(me, q)
else
searchThreads(me, q) zip searchFriends(me, q) zip searchUsers(me, q) map {
case ((threads, friends), users) =>
MsgSearch
.Result(
threads,
friends.filterNot(f => threads.exists(_.other(me) == f.id)) take 10,
users.filterNot(u => u.id == me.id || friends.exists(_.id == u.id)) take 10
)
}
private def forKid(me: User, q: String): Fu[MsgSearch.Result] = for {
threads <- searchThreads(me, q)
allMates <- Bus.ask[Set[User.ID]]("clas") { ClasMatesAndTeachers(KidId(me.id), _) }
lower = q.toLowerCase
mateIds = allMates.view.filter(_ startsWith lower).toList take 15
mates <- lightUserApi asyncMany mateIds
} yield MsgSearch.Result(threads, mates.flatten, Nil)
2020-01-25 09:31:11 -07:00
2020-01-27 00:02:41 -07:00
val empty = MsgSearch.Result(Nil, Nil, Nil)
2020-01-25 09:31:11 -07:00
private def searchThreads(me: User, q: String): Fu[List[MsgThread]] =
colls.thread
2020-01-25 09:31:11 -07:00
.find(
$doc(
"users" -> $doc(
$eq(me.id),
"$regex" -> BSONRegex(s"^$q", "")
2020-01-26 13:49:25 -07:00
),
"del" $ne me.id
2020-01-25 09:31:11 -07:00
)
)
.sort($sort desc "lastMsg.date")
.hint(
colls.thread hint $doc(
"users" -> 1,
"lastMsg.date" -> -1
)
)
.cursor[MsgThread](ReadPreference.secondaryPreferred)
2020-07-19 08:07:33 -06:00
.list(5)
2020-01-25 09:31:11 -07:00
2020-05-05 22:11:15 -06:00
private def searchFriends(me: User, q: String): Fu[List[LightUser]] =
relationApi.searchFollowedBy(me, q, 15) flatMap lightUserApi.asyncMany dmap (_.flatten)
2020-01-25 09:31:11 -07:00
2020-05-05 22:11:15 -06:00
private def searchUsers(me: User, q: String): Fu[List[LightUser]] =
userCache.userIdsLike(q) flatMap lightUserApi.asyncMany dmap (_.flatten)
2020-01-25 09:31:11 -07:00
}
object MsgSearch {
case class Result(
threads: List[MsgThread],
friends: List[LightUser],
users: List[LightUser]
)
}