121 lines
4.1 KiB
Scala
121 lines
4.1 KiB
Scala
package controllers
|
|
|
|
import play.api.libs.json.Json
|
|
import play.api.mvc._
|
|
import play.twirl.api.Html
|
|
|
|
import lila.api.Context
|
|
import lila.app._
|
|
import lila.relation.Related
|
|
import lila.user.{ User => UserModel, UserRepo }
|
|
import views._
|
|
|
|
object Relation extends LilaController {
|
|
|
|
private def env = Env.relation
|
|
|
|
private def renderActions(userId: String, mini: Boolean)(implicit ctx: Context) =
|
|
(ctx.userId ?? { env.api.relation(_, userId) }) zip
|
|
(ctx.isAuth ?? { Env.pref.api followable userId }) zip
|
|
(ctx.userId ?? { env.api.blocks(userId, _) }) flatMap {
|
|
case ((relation, followable), blocked) => negotiate(
|
|
html = fuccess(Ok(mini.fold(
|
|
html.relation.mini(userId, blocked = blocked, followable = followable, relation = relation),
|
|
html.relation.actions(userId, relation = relation, blocked = blocked, followable = followable)
|
|
))),
|
|
api = _ => fuccess(Ok(Json.obj(
|
|
"followable" -> followable,
|
|
"following" -> relation.exists(true ==),
|
|
"blocking" -> relation.exists(false ==)
|
|
)))
|
|
)
|
|
}
|
|
|
|
def follow(userId: String) = Auth { implicit ctx =>
|
|
me =>
|
|
env.api.follow(me.id, userId).nevermind >> renderActions(userId, getBool("mini"))
|
|
}
|
|
|
|
def unfollow(userId: String) = Auth { implicit ctx =>
|
|
me =>
|
|
env.api.unfollow(me.id, userId).nevermind >> renderActions(userId, getBool("mini"))
|
|
}
|
|
|
|
def block(userId: String) = Auth { implicit ctx =>
|
|
me =>
|
|
env.api.block(me.id, userId).nevermind >> renderActions(userId, getBool("mini"))
|
|
}
|
|
|
|
def unblock(userId: String) = Auth { implicit ctx =>
|
|
me =>
|
|
env.api.unblock(me.id, userId).nevermind >> renderActions(userId, getBool("mini"))
|
|
}
|
|
|
|
def following(username: String) = Open { implicit ctx =>
|
|
OptionFuOk(UserRepo named username) { user =>
|
|
env.api.following(user.id) flatMap followship flatMap { rels =>
|
|
env.api nbFollowers user.id map { followers =>
|
|
html.relation.following(user, rels, followers)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def followers(username: String) = Open { implicit ctx =>
|
|
OptionFuOk(UserRepo named username) { user =>
|
|
env.api.followers(user.id) flatMap followship flatMap { rels =>
|
|
env.api nbFollowing user.id map { following =>
|
|
html.relation.followers(user, rels, following)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def blocks = Auth { implicit ctx =>
|
|
me =>
|
|
env.api.blocking(me.id) flatMap followship map { rels =>
|
|
html.relation.blocks(me, rels)
|
|
}
|
|
}
|
|
|
|
private def followship(userIds: Set[String])(implicit ctx: Context): Fu[List[Related]] =
|
|
UserRepo byIds userIds flatMap { users =>
|
|
(ctx.isAuth ?? { Env.pref.api.followableIds(users map (_.id)) }) flatMap { followables =>
|
|
users.map { u =>
|
|
ctx.userId ?? { env.api.relation(_, u.id) } map { rel =>
|
|
lila.relation.Related(u, 0, followables(u.id), rel)
|
|
}
|
|
}.sequenceFu
|
|
}
|
|
}
|
|
|
|
def suggest(username: String) = Open { implicit ctx =>
|
|
OptionFuResult(UserRepo named username) { user =>
|
|
lila.game.BestOpponents(user.id, 50) flatMap { opponents =>
|
|
Env.pref.api.followableIds(opponents map (_._1.id)) zip
|
|
env.api.onlinePopularUsers(20) flatMap {
|
|
case (followables, popular) =>
|
|
popular.filterNot(user ==).foldLeft(opponents filter {
|
|
case (u, _) => followables contains u.id
|
|
}) {
|
|
case (xs, x) => xs.exists(_._1 == x).fold(xs, xs :+ (x, 0))
|
|
}.map {
|
|
case (u, nb) => env.api.relation(user.id, u.id) map {
|
|
lila.relation.Related(u, nb, true, _)
|
|
}
|
|
}.sequenceFu flatMap { rels =>
|
|
negotiate(
|
|
html = fuccess(Ok(html.relation.suggest(user, rels))),
|
|
api = _ => fuccess {
|
|
implicit val userWrites = play.api.libs.json.Writes[UserModel] { Env.user.jsonView(_, true) }
|
|
Ok(Json.obj(
|
|
"user" -> user,
|
|
"suggested" -> play.api.libs.json.JsArray(rels.map(_.toJson))))
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|