diff --git a/app/controllers/User.scala b/app/controllers/User.scala index e208010026..645731c617 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -21,6 +21,7 @@ object User extends LilaController { private def gamePaginator = Env.game.paginator private def forms = lila.user.DataForm private def relationApi = Env.relation.api + private def ratingChartApi = Env.history.ratingChartApi private def userGameSearch = Env.gameSearch.userGameSearch def tv(username: String) = Open { implicit ctx => @@ -192,7 +193,7 @@ object User extends LilaController { } def top200(perfKey: String) = Open { implicit ctx => - lila.rating.PerfType(perfKey).fold(notFound) { perfType => + PerfType(perfKey).fold(notFound) { perfType => env.cached top200Perf perfType.id map { users => Ok(html.user.top200(perfType, users)) } @@ -276,7 +277,7 @@ object User extends LilaController { def perfStat(username: String, perfKey: String) = Open { implicit ctx => OptionFuResult(UserRepo named username) { u => if ((u.disabled || (u.lame && !ctx.is(u))) && !isGranted(_.UserSpy)) notFound - else lila.rating.PerfType(perfKey).fold(notFound) { perfType => + else PerfType(perfKey).fold(notFound) { perfType => for { perfStat <- Env.perfStat.get(u, perfType) ranks <- Env.user.cached.ranking.getAll(u.id) @@ -286,7 +287,13 @@ object User extends LilaController { data = Env.perfStat.jsonView(u, perfStat, ranks get perfType.key, distribution) response <- negotiate( html = Ok(html.user.perfStat(u, ranks, perfType, data)).fuccess, - api = _ => Ok(data).fuccess) + api = _ => + getBool("graph").?? { + Env.history.ratingChartApi.singlePerf(u, perfType).map(_.some) + } map { + _.fold(data) { graph => data + ("graph" -> graph) } + } map { Ok(_) } + ) } yield response } } diff --git a/modules/history/src/main/HistoryApi.scala b/modules/history/src/main/HistoryApi.scala index 60e3ceaee5..41997bcc41 100644 --- a/modules/history/src/main/HistoryApi.scala +++ b/modules/history/src/main/HistoryApi.scala @@ -51,7 +51,7 @@ final class HistoryApi(coll: Coll) { ).void } - def daysBetween(from: DateTime, to: DateTime): Int = + private def daysBetween(from: DateTime, to: DateTime): Int = Days.daysBetween(from.withTimeAtStartOfDay, to.withTimeAtStartOfDay).getDays def get(userId: String): Fu[Option[History]] = coll.uno[History]($id(userId)) diff --git a/modules/history/src/main/RatingChartApi.scala b/modules/history/src/main/RatingChartApi.scala index c341d42a77..3588f79dc3 100644 --- a/modules/history/src/main/RatingChartApi.scala +++ b/modules/history/src/main/RatingChartApi.scala @@ -18,6 +18,11 @@ final class RatingChartApi( chart.nonEmpty option chart } + def singlePerf(user: User, perfType: PerfType): Fu[JsArray] = + historyApi.ratingsMap(user, perfType) map { + ratingsMapToJson(user, _) + } map JsArray.apply + private val cache = mongoCache[User, String]( prefix = "history:rating", f = (user: User) => build(user) map (~_), @@ -25,26 +30,24 @@ final class RatingChartApi( timeToLive = cacheTtl, keyToString = _.id) - private def build(user: User): Fu[Option[String]] = { - - def ratingsMapToJson(perfType: PerfType, ratingsMap: RatingsMap) = Json obj ( - "name" -> perfType.name, - "points" -> ratingsMap.map { - case (days, rating) => - val date = user.createdAt plusDays days - Json.arr(date.getYear, date.getMonthOfYear - 1, date.getDayOfMonth, rating) - } - ) + private def ratingsMapToJson(user: User, ratingsMap: RatingsMap) = ratingsMap.map { + case (days, rating) => + val date = user.createdAt plusDays days + Json.arr(date.getYear, date.getMonthOfYear - 1, date.getDayOfMonth, rating) + } + private def build(user: User): Fu[Option[String]] = historyApi get user.id map2 { (history: History) => Json stringify { Json.toJson { import lila.rating.PerfType._ List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde, RacingKings, Crazyhouse, Puzzle) map { pt => - ratingsMapToJson(pt, history(pt)) + Json.obj( + "name" -> pt.name, + "points" -> ratingsMapToJson(user, history(pt)) + ) } } } } - } }