diff --git a/app/controllers/GameMod.scala b/app/controllers/GameMod.scala index b6202d13a9..ed37a3f42f 100644 --- a/app/controllers/GameMod.scala +++ b/app/controllers/GameMod.scala @@ -20,7 +20,7 @@ final class GameMod(env: Env) extends LilaController(env) { val form = filterForm.bindFromRequest() val filter = form.fold(_ => emptyFilter, identity) env.tournament.leaderboardApi.recentByUser(user, 1) zip - guessSwisses(user) zip + env.activity.read.recentSwissRanks(user.id) zip env.game.gameRepo.recentPovsByUserFromSecondary(user, 100, toDbSelect(filter)) flatMap { case ((arenas, swisses), povs) => env.mod.assessApi.ofPovs(povs) map { games => diff --git a/app/views/mod/games.scala b/app/views/mod/games.scala index 72c2e2a4b2..3bb9a44577 100644 --- a/app/views/mod/games.scala +++ b/app/views/mod/games.scala @@ -25,7 +25,7 @@ object games { filterForm: Form[GameMod.Filter], games: List[(Pov, Option[PlayerAssessment])], arenas: Seq[TourEntry], - swisses: Seq[Swiss] + swisses: Seq[(Swiss.IdName, Int)] )(implicit ctx: Context ) = @@ -49,8 +49,16 @@ object games { t.tour.name() ).mkString(" / ") ), - pluralize("Recent arenas", arenas.size).some, + pluralize("recent arena", arenas.size).some, disabled = arenas.isEmpty + ), + form3.select( + filterForm("swiss"), + swisses.map { case (swiss, rank) => + swiss.id.value -> s"rank ${rank} / ${swiss.name}" + }, + s"${swisses.size} recent swiss".some, + disabled = swisses.isEmpty ) ) ) diff --git a/modules/activity/src/main/ActivityReadApi.scala b/modules/activity/src/main/ActivityReadApi.scala index 6612e9213c..202f6bdbb8 100644 --- a/modules/activity/src/main/ActivityReadApi.scala +++ b/modules/activity/src/main/ActivityReadApi.scala @@ -9,6 +9,7 @@ import lila.game.LightPov import lila.practice.PracticeStructure import lila.user.User import lila.tournament.LeaderboardApi +import lila.swiss.Swiss final class ActivityReadApi( coll: Coll, @@ -110,16 +111,7 @@ final class ActivityReadApi( swisses <- a.swisses .?? { swisses => - swissApi - .idNames(swisses.value.map(_.id)) - .map { - _.flatMap { idName => - swisses.value.find(_.id == idName.id) map { s => - (idName, s.rank) - } - } - } - .dmap(_.some.filter(_.nonEmpty)) + toSwissesView(swisses.value).dmap(_.some.filter(_.nonEmpty)) } } yield ActivityView( @@ -141,6 +133,27 @@ final class ActivityReadApi( stream = a.stream ) + def recentSwissRanks(userId: User.ID): Fu[List[(Swiss.IdName, Int)]] = + coll + .find(regexId(userId) ++ $doc(BSONHandlers.ActivityFields.swisses $exists true)) + .sort($sort desc "_id") + .cursor[Activity](ReadPreference.secondaryPreferred) + .list(10) + .flatMap { activities => + toSwissesView(activities.flatMap(_.swisses.??(_.value))) + } + + private def toSwissesView(swisses: List[activities.SwissRank]): Fu[List[(Swiss.IdName, Int)]] = + swissApi + .idNames(swisses.map(_.id)) + .map { + _.flatMap { idName => + swisses.find(_.id == idName.id) map { s => + (idName, s.rank) + } + } + } + private def addSignup(at: DateTime, recent: Vector[ActivityView]) = { val (found, views) = recent.foldLeft(false -> Vector.empty[ActivityView]) { case ((false, as), a) if a.interval contains at => (true, as :+ a.copy(signup = true)) diff --git a/ui/site/css/mod/_games.scss b/ui/site/css/mod/_games.scss index bc8ef9d6d8..3096495a39 100644 --- a/ui/site/css/mod/_games.scss +++ b/ui/site/css/mod/_games.scss @@ -24,3 +24,12 @@ cursor: pointer; } } + +.mod-games { + &__filter-form { + select { + max-width: 30ch; + margin-left: 1em; + } + } +}