2020-01-25 09:31:11 -07:00
|
|
|
package lila.msg
|
|
|
|
|
|
|
|
import reactivemongo.api.bson._
|
2020-08-24 04:12:02 -06:00
|
|
|
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
|
2021-03-31 08:41:45 -06:00
|
|
|
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
|
2021-03-31 08:41:45 -06:00
|
|
|
)(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] =
|
2021-03-31 08:41:45 -06:00
|
|
|
if (me.kid) forKid(me, q)
|
|
|
|
else
|
|
|
|
searchThreads(me, q) zip searchFriends(me, q) zip searchUsers(me, q) map {
|
2021-04-09 00:59:24 -06:00
|
|
|
case ((threads, friends), users) =>
|
2021-03-31 08:41:45 -06:00
|
|
|
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]] =
|
2020-08-21 09:18:23 -06:00
|
|
|
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")
|
2020-08-24 04:12:02 -06:00
|
|
|
.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]] =
|
2021-03-31 08:41:45 -06:00
|
|
|
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]] =
|
2021-03-31 08:41:45 -06:00
|
|
|
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]
|
|
|
|
)
|
|
|
|
}
|