diff --git a/app/Env.scala b/app/Env.scala index 58c49edac8..8968360b65 100644 --- a/app/Env.scala +++ b/app/Env.scala @@ -15,6 +15,12 @@ final class Env(config: Config, system: ActorSystem) { history = Env.lobby.history, featured = Env.game.featured) + lazy val userInfo = mashup.UserInfo( + countUsers = () ⇒ Env.user.countEnabled, + bookmarkApi = Env.bookmark.api, + eloCalculator = Env.round.eloCalculator, + relationApi = Env.relation.api) _ + system.actorOf(Props(new actor.Renderer), name = RendererName) system.actorOf(Props(new actor.Router( diff --git a/app/controllers/User.scala b/app/controllers/User.scala index adbbe4f882..ac5e1d19f2 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -15,10 +15,6 @@ object User extends LilaController { private def env = Env.user private def gamePaginator = Env.game.paginator private def forms = lila.user.DataForm - private lazy val makeUserInfo = mashup.UserInfo( - countUsers = () ⇒ env.countEnabled, - bookmarkApi = Env.bookmark.api, - eloCalculator = Env.round.eloCalculator) _ def show(username: String) = Open { implicit ctx ⇒ isXhr.fold(mini(username), filter(username, "all", 1)) @@ -36,14 +32,12 @@ object User extends LilaController { private def userShow(u: UserModel, filterName: String, page: Int)(implicit ctx: Context) = (u.enabled || isGranted(_.UserSpy)).fold({ for { - info ← makeUserInfo(u, ctx) + info ← Env.current.userInfo(u, ctx) filters = mashup.GameFilterMenu(info, ctx.me, filterName) pag ← (filters.query.fold(Env.bookmark.api.gamePaginatorByUser(u, page)) { query ⇒ gamePaginator.recentlyCreated(query, filters.cachedNb)(page) }) - nbFollowing ← Env.relation.api nbFollowing u.id - nbFollowers ← Env.relation.api nbFollowers u.id - } yield html.user.show(u, info, pag, nbFollowing, nbFollowers, filters) + } yield html.user.show(u, info, pag, filters) }, fuccess(html.user.disabled(u))) private def mini(username: String)(implicit ctx: Context) = @@ -70,7 +64,7 @@ object User extends LilaController { def opponents(username: String) = Open { implicit ctx ⇒ OptionFuOk(UserRepo named username) { user ⇒ - mashup.UserInfo.bestOpponents(user.id, 50) map { ops ⇒ + lila.game.BestOpponents(user.id, 50) map { ops ⇒ html.user.opponents(user, ops) } } diff --git a/app/mashup/UserInfo.scala b/app/mashup/UserInfo.scala index 0084edcf6c..7e9528e7cc 100644 --- a/app/mashup/UserInfo.scala +++ b/app/mashup/UserInfo.scala @@ -5,6 +5,7 @@ import chess.{ EloCalculator, Color } import lila.game.{ GameRepo, Game } import lila.user.{ User, UserRepo, Context, EloChart } import lila.bookmark.BookmarkApi +import lila.relation.RelationApi case class UserInfo( user: User, @@ -13,7 +14,9 @@ case class UserInfo( nbWithMe: Option[Int], nbBookmark: Int, eloWithMe: Option[List[(String, Int)]], - eloChart: Option[EloChart]) { + eloChart: Option[EloChart], + nbFollowing: Int, + nbFollowers: Int) { def nbRated = user.nbRatedGames @@ -27,43 +30,37 @@ object UserInfo { def apply( countUsers: () ⇒ Fu[Int], bookmarkApi: BookmarkApi, - eloCalculator: EloCalculator)(user: User, ctx: Context): Fu[UserInfo] = for { - rank ← (user.elo >= rankMinElo) ?? { + eloCalculator: EloCalculator, + relationApi: RelationApi)(user: User, ctx: Context): Fu[UserInfo] = + ((user.elo >= rankMinElo) ?? { UserRepo rank user flatMap { rank ⇒ countUsers() map { nbUsers ⇒ (rank -> nbUsers).some } } - } - nbPlaying ← (ctx is user) ?? { - GameRepo count (_ notFinished user.id) map (_.some) - } - nbWithMe ← ctx.me.filter(user!=) ?? { me ⇒ - GameRepo count (_.opponents(user, me)) map (_.some) - } - nbBookmark ← bookmarkApi countByUser user - eloChart ← EloChart(user) - eloWithMe = ctx.me.filter(user !=) map { me ⇒ - List( - "win" -> eloCalculator.diff(me, user, Color.White.some), - "draw" -> eloCalculator.diff(me, user, None), - "loss" -> eloCalculator.diff(me, user, Color.Black.some)) - } - } yield new UserInfo( - user = user, - rank = rank, - nbPlaying = ~nbPlaying, - nbWithMe = nbWithMe, - nbBookmark = nbBookmark, - eloWithMe = eloWithMe, - eloChart = eloChart) - - def bestOpponents(userId: String, limit: Int): Fu[List[(User, Int)]] = - GameRepo.bestOpponents(userId, limit) flatMap { opponents ⇒ - UserRepo enabledByIds opponents.map(_._1) map { users ⇒ - (users map { user ⇒ - opponents find (_._1 == user.id) map { opponent ⇒ - user -> opponent._2 - } - }).flatten sortBy (-_._2) + }) zip + ((ctx is user) ?? { + GameRepo count (_ notFinished user.id) map (_.some) + }) zip + (ctx.me.filter(user!=) ?? { me ⇒ + GameRepo count (_.opponents(user, me)) map (_.some) + }) zip + (bookmarkApi countByUser user) zip + EloChart(user) zip + relationApi.nbFollowing(user.id) zip + relationApi.nbFollowers(user.id) map { + case ((((((rank, nbPlaying), nbWithMe), nbBookmark), eloChart), nbFollowing), nbFollowers) ⇒ new UserInfo( + user = user, + rank = rank, + nbPlaying = ~nbPlaying, + nbWithMe = nbWithMe, + nbBookmark = nbBookmark, + eloWithMe = ctx.me.filter(user !=) map { me ⇒ + List( + "win" -> eloCalculator.diff(me, user, Color.White.some), + "draw" -> eloCalculator.diff(me, user, None), + "loss" -> eloCalculator.diff(me, user, Color.Black.some)) + }, + eloChart = eloChart, + nbFollowing = nbFollowing, + nbFollowers = nbFollowers) } - } } diff --git a/app/views/user/show.scala.html b/app/views/user/show.scala.html index 689f228034..f03df59c30 100644 --- a/app/views/user/show.scala.html +++ b/app/views/user/show.scala.html @@ -1,4 +1,4 @@ -@(u: User, info: lila.app.mashup.UserInfo, games: Paginator[Game], nbFollowing: Int, nbFollowers: Int, filters: lila.app.mashup.GameFilterMenu)(implicit ctx: Context) +@(u: User, info: lila.app.mashup.UserInfo, games: Paginator[Game], filters: lila.app.mashup.GameFilterMenu)(implicit ctx: Context) @title = @{ "%s : %s - page %d".format(u.username, userGameFilterTitle(info, filters.current), games.currentPage) } @@ -60,8 +60,8 @@ evenMoreCss = evenMoreCss) { }
- @trans.nbFollowing(nbFollowing) - @trans.nbFollowers(nbFollowers) + @trans.nbFollowing(info.nbFollowing) + @trans.nbFollowers(info.nbFollowers) @if(ctx.isAuth && !ctx.is(u)) { @relation.actions(u.id) } diff --git a/modules/game/src/main/BestOpponents.scala b/modules/game/src/main/BestOpponents.scala new file mode 100644 index 0000000000..8746763597 --- /dev/null +++ b/modules/game/src/main/BestOpponents.scala @@ -0,0 +1,17 @@ +package lila.game + +import lila.user.{ User, UserRepo } + +object BestOpponents { + + def apply(userId: String, limit: Int): Fu[List[(User, Int)]] = + GameRepo.bestOpponents(userId, limit) flatMap { opponents ⇒ + UserRepo enabledByIds opponents.map(_._1) map { users ⇒ + (users map { user ⇒ + opponents find (_._1 == user.id) map { opponent ⇒ + user -> opponent._2 + } + }).flatten sortBy (-_._2) + } + } +} diff --git a/todo b/todo index 11c86ab14a..b4e393d56a 100644 --- a/todo +++ b/todo @@ -66,7 +66,6 @@ from MoralIntentions email: - The possibility of team matches (with solutions for players who are in several teams), where the team leader has to choose the board order, where the team results are shown and where the team player (who has played all of the games of the match) with the highest Percentage Score gets crowned Player of the Match of team "A". safari has high bounce rate send message to sockets when a friendship is created or revoked -convert background board css to single image (needs gimp) correspondance chess http://en.lichess.org/forum/lichess-feedback/correspondence-chess#1 takeback/enpassant glitch http://en.lichess.org/forum/lichess-feedback/i-found-a-glitch#1 show teams in user mini