diff --git a/app/controllers/Round.scala b/app/controllers/Round.scala index 2455142b06..764d2936ca 100644 --- a/app/controllers/Round.scala +++ b/app/controllers/Round.scala @@ -8,7 +8,7 @@ import lila.app._ import lila.chat.Chat import lila.common.HTTPRequest import lila.game.{ Pov, Game => GameModel, PgnDump } -import lila.tournament.{ TourMiniView, Tournament => Tour } +import lila.tournament.{ Tournament => Tour } import lila.user.{ User => UserModel } import views._ @@ -30,7 +30,7 @@ final class Round( else PreventTheft(pov) { pov.game.playableByAi ?? env.fishnet.player(pov.game) - myTour(pov.game.tournamentId, true) flatMap { + env.tournament.api.miniView(pov.game, true) flatMap { tour => gameC.preloadUsers(pov.game) zip (pov.game.simulId ?? env.simul.repo.find) zip @@ -155,7 +155,7 @@ final class Round( html = { if (pov.game.replayable) analyseC.replay(pov, userTv = userTv) else if (HTTPRequest.isHuman(ctx.req)) - myTour(pov.game.tournamentId, false) zip + env.tournament.api.miniView(pov.game, false) zip (pov.game.simulId ?? env.simul.repo.find) zip getWatcherChat(pov.game) zip (ctx.noBlind ?? env.game.crosstableApi.withMatchup(pov.game)) zip @@ -200,9 +200,6 @@ final class Round( ) map { NoCache(_) } } - private def myTour(tourId: Option[String], withTop: Boolean): Fu[Option[TourMiniView]] = - tourId ?? { env.tournament.api.miniView(_, withTop) } - private[controllers] def getWatcherChat( game: GameModel )(implicit ctx: Context): Fu[Option[lila.chat.UserChat.Mine]] = { @@ -258,7 +255,7 @@ final class Round( def sides(gameId: String, color: String) = Open { implicit ctx => OptionFuResult(proxyPov(gameId, color)) { pov => - (pov.game.tournamentId ?? env.tournament.tournamentRepo.byId) zip + env.tournament.api.withTeamVs(pov.game) zip (pov.game.simulId ?? env.simul.repo.find) zip env.game.gameRepo.initialFen(pov.game) zip env.game.crosstableApi.withMatchup(pov.game) zip diff --git a/app/templating/TeamHelper.scala b/app/templating/TeamHelper.scala index c990c7f5e0..e692a20585 100644 --- a/app/templating/TeamHelper.scala +++ b/app/templating/TeamHelper.scala @@ -13,7 +13,7 @@ trait TeamHelper { self: HasEnv => def teamIdToName(id: String): Frag = StringFrag(env.team.getTeamName(id).getOrElse(id)) - def teamLink(id: String, withIcon: Boolean = true): Frag = + def teamLink(id: String, withIcon: Boolean = true) = a( href := routes.Team.show(id), dataIcon := withIcon.option("f"), diff --git a/app/views/game/bits.scala b/app/views/game/bits.scala index 1791b7bf64..9a9af75573 100644 --- a/app/views/game/bits.scala +++ b/app/views/game/bits.scala @@ -40,7 +40,7 @@ object bits { def sides( pov: Pov, initialFen: Option[chess.format.FEN], - tour: Option[lila.tournament.Tournament], + tour: Option[lila.tournament.TourAndTeamVs], cross: Option[lila.game.Crosstable.WithMatchup], simul: Option[lila.simul.Simul], userTv: Option[lila.user.User] = None, diff --git a/app/views/game/side.scala b/app/views/game/side.scala index ce7e52be48..5141bcce71 100644 --- a/app/views/game/side.scala +++ b/app/views/game/side.scala @@ -16,7 +16,7 @@ object side { def apply( pov: lila.game.Pov, initialFen: Option[chess.format.FEN], - tour: Option[lila.tournament.Tournament], + tour: Option[lila.tournament.TourAndTeamVs], simul: Option[lila.simul.Simul], userTv: Option[lila.user.User] = None, bookmarked: Boolean @@ -28,7 +28,7 @@ object side { def meta( pov: lila.game.Pov, initialFen: Option[chess.format.FEN], - tour: Option[lila.tournament.Tournament], + tour: Option[lila.tournament.TourAndTeamVs], simul: Option[lila.simul.Simul], userTv: Option[lila.user.User] = None, bookmarked: Boolean @@ -88,8 +88,11 @@ object side { ), div(cls := "game__meta__players")( game.players.map { p => - div(cls := s"player color-icon is ${p.color.name} text")( - playerLink(p, withOnline = false, withDiff = true, withBerserk = true) + frag( + div(cls := s"player color-icon is ${p.color.name} text")( + playerLink(p, withOnline = false, withDiff = true, withBerserk = true) + ), + tour.flatMap(_.teamVs).map(_.teams(p.color)) map { teamLink(_, false)(cls := "team") } ) } ) @@ -124,8 +127,8 @@ object side { }, tour.map { t => st.section(cls := "game__tournament")( - a(cls := "text", dataIcon := "g", href := routes.Tournament.show(t.id))(t.fullName), - div(cls := "clock", dataTime := t.secondsToFinish)(div(cls := "time")(t.clockStatus)) + a(cls := "text", dataIcon := "g", href := routes.Tournament.show(t.tour.id))(t.tour.fullName), + div(cls := "clock", dataTime := t.tour.secondsToFinish)(div(cls := "time")(t.tour.clockStatus)) ) } orElse { game.tournamentId map { tourId => diff --git a/app/views/round/bits.scala b/app/views/round/bits.scala index 246e2c88da..72a47cbc91 100644 --- a/app/views/round/bits.scala +++ b/app/views/round/bits.scala @@ -128,7 +128,7 @@ object bits { )(implicit ctx: Context) = views.html.game.side( pov, (data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN), - tour.map(_.tour), + tour.map(_.tourAndTeamVs), simul = simul, userTv = userTv, bookmarked = bookmarked diff --git a/modules/tournament/src/main/PlayerRepo.scala b/modules/tournament/src/main/PlayerRepo.scala index 8bca3b9686..37f5bdb569 100644 --- a/modules/tournament/src/main/PlayerRepo.scala +++ b/modules/tournament/src/main/PlayerRepo.scala @@ -167,6 +167,16 @@ final class PlayerRepo(coll: Coll)(implicit ec: scala.concurrent.ExecutionContex } } + def teamVs(tourId: Tournament.ID, game: lila.game.Game): Fu[Option[TeamBattle.TeamVs]] = + game.twoUserIds ?? { + case (w, b) => + teamsOfPlayers(tourId, List(w, b)).dmap(_.toMap) map { m => + (m.get(w) |@| m.get(b)).tupled ?? { + case (wt, bt) => TeamBattle.TeamVs(chess.Color.Map(wt, bt)).some + } + } + } + def countActive(tourId: Tournament.ID): Fu[Int] = coll.countSel(selectTour(tourId) ++ selectActive) diff --git a/modules/tournament/src/main/TeamBattle.scala b/modules/tournament/src/main/TeamBattle.scala index 5530d36e39..65d6100703 100644 --- a/modules/tournament/src/main/TeamBattle.scala +++ b/modules/tournament/src/main/TeamBattle.scala @@ -17,6 +17,8 @@ object TeamBattle { def init(teamId: TeamID) = TeamBattle(Set(teamId), 5) + case class TeamVs(teams: chess.Color.Map[TeamID]) + case class RankedTeam( rank: Int, teamId: TeamID, diff --git a/modules/tournament/src/main/TournamentApi.scala b/modules/tournament/src/main/TournamentApi.scala index 6a336b1fe3..7ae582b50e 100644 --- a/modules/tournament/src/main/TournamentApi.scala +++ b/modules/tournament/src/main/TournamentApi.scala @@ -471,10 +471,22 @@ final class TournamentApi( def tournamentTop(tourId: Tournament.ID): Fu[TournamentTop] = tournamentTopCache get tourId - def miniView(tourId: Tournament.ID, withTop: Boolean): Fu[Option[TourMiniView]] = - tournamentRepo byId tourId flatMap { + def miniView(game: Game, withTop: Boolean): Fu[Option[TourMiniView]] = + withTeamVs(game) flatMap { + _ ?? { + case TourAndTeamVs(tour, teamVs) => + withTop ?? { tournamentTop(tour.id) map some } map { + TourMiniView(tour, _, teamVs).some + } + } + } + + def withTeamVs(game: Game): Fu[Option[TourAndTeamVs]] = + game.tournamentId ?? tournamentRepo.byId flatMap { _ ?? { tour => - withTop ?? { tournamentTop(tour.id) map some } map { TourMiniView(tour, _).some } + (tour.isTeamBattle ?? playerRepo.teamVs(tour.id, game)) map { + TourAndTeamVs(tour, _).some + } } } diff --git a/modules/tournament/src/main/model.scala b/modules/tournament/src/main/model.scala index 6e36355351..1d94a0a919 100644 --- a/modules/tournament/src/main/model.scala +++ b/modules/tournament/src/main/model.scala @@ -4,7 +4,15 @@ final class LeaderboardRepo(val coll: lila.db.dsl.Coll) case class TournamentTop(value: List[Player]) extends AnyVal -case class TourMiniView(tour: Tournament, top: Option[TournamentTop]) +case class TourMiniView( + tour: Tournament, + top: Option[TournamentTop], + teamVs: Option[TeamBattle.TeamVs] +) { + def tourAndTeamVs = TourAndTeamVs(tour, teamVs) +} + +case class TourAndTeamVs(tour: Tournament, teamVs: Option[TeamBattle.TeamVs]) case class MyInfo(rank: Int, withdraw: Boolean, gameId: Option[lila.game.Game.ID]) { def page = { diff --git a/ui/round/css/_side.scss b/ui/round/css/_side.scss index 51d972d1c3..e929652c68 100644 --- a/ui/round/css/_side.scss +++ b/ui/round/css/_side.scss @@ -3,6 +3,9 @@ .game__meta { flex: 0 0 auto; + &__players .team { + margin-left: 1.7em; + } } }