show players' teams in team battle games

pull/6012/head
Thibault Duplessis 2020-02-10 13:53:48 -06:00
parent b069aa1456
commit 66690201bd
10 changed files with 55 additions and 20 deletions

View File

@ -8,7 +8,7 @@ import lila.app._
import lila.chat.Chat import lila.chat.Chat
import lila.common.HTTPRequest import lila.common.HTTPRequest
import lila.game.{ Pov, Game => GameModel, PgnDump } import lila.game.{ Pov, Game => GameModel, PgnDump }
import lila.tournament.{ TourMiniView, Tournament => Tour } import lila.tournament.{ Tournament => Tour }
import lila.user.{ User => UserModel } import lila.user.{ User => UserModel }
import views._ import views._
@ -30,7 +30,7 @@ final class Round(
else else
PreventTheft(pov) { PreventTheft(pov) {
pov.game.playableByAi ?? env.fishnet.player(pov.game) pov.game.playableByAi ?? env.fishnet.player(pov.game)
myTour(pov.game.tournamentId, true) flatMap { env.tournament.api.miniView(pov.game, true) flatMap {
tour => tour =>
gameC.preloadUsers(pov.game) zip gameC.preloadUsers(pov.game) zip
(pov.game.simulId ?? env.simul.repo.find) zip (pov.game.simulId ?? env.simul.repo.find) zip
@ -155,7 +155,7 @@ final class Round(
html = { html = {
if (pov.game.replayable) analyseC.replay(pov, userTv = userTv) if (pov.game.replayable) analyseC.replay(pov, userTv = userTv)
else if (HTTPRequest.isHuman(ctx.req)) 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 (pov.game.simulId ?? env.simul.repo.find) zip
getWatcherChat(pov.game) zip getWatcherChat(pov.game) zip
(ctx.noBlind ?? env.game.crosstableApi.withMatchup(pov.game)) zip (ctx.noBlind ?? env.game.crosstableApi.withMatchup(pov.game)) zip
@ -200,9 +200,6 @@ final class Round(
) map { NoCache(_) } ) map { NoCache(_) }
} }
private def myTour(tourId: Option[String], withTop: Boolean): Fu[Option[TourMiniView]] =
tourId ?? { env.tournament.api.miniView(_, withTop) }
private[controllers] def getWatcherChat( private[controllers] def getWatcherChat(
game: GameModel game: GameModel
)(implicit ctx: Context): Fu[Option[lila.chat.UserChat.Mine]] = { )(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 => def sides(gameId: String, color: String) = Open { implicit ctx =>
OptionFuResult(proxyPov(gameId, color)) { pov => 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 (pov.game.simulId ?? env.simul.repo.find) zip
env.game.gameRepo.initialFen(pov.game) zip env.game.gameRepo.initialFen(pov.game) zip
env.game.crosstableApi.withMatchup(pov.game) zip env.game.crosstableApi.withMatchup(pov.game) zip

View File

@ -13,7 +13,7 @@ trait TeamHelper { self: HasEnv =>
def teamIdToName(id: String): Frag = StringFrag(env.team.getTeamName(id).getOrElse(id)) 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( a(
href := routes.Team.show(id), href := routes.Team.show(id),
dataIcon := withIcon.option("f"), dataIcon := withIcon.option("f"),

View File

@ -40,7 +40,7 @@ object bits {
def sides( def sides(
pov: Pov, pov: Pov,
initialFen: Option[chess.format.FEN], initialFen: Option[chess.format.FEN],
tour: Option[lila.tournament.Tournament], tour: Option[lila.tournament.TourAndTeamVs],
cross: Option[lila.game.Crosstable.WithMatchup], cross: Option[lila.game.Crosstable.WithMatchup],
simul: Option[lila.simul.Simul], simul: Option[lila.simul.Simul],
userTv: Option[lila.user.User] = None, userTv: Option[lila.user.User] = None,

View File

@ -16,7 +16,7 @@ object side {
def apply( def apply(
pov: lila.game.Pov, pov: lila.game.Pov,
initialFen: Option[chess.format.FEN], initialFen: Option[chess.format.FEN],
tour: Option[lila.tournament.Tournament], tour: Option[lila.tournament.TourAndTeamVs],
simul: Option[lila.simul.Simul], simul: Option[lila.simul.Simul],
userTv: Option[lila.user.User] = None, userTv: Option[lila.user.User] = None,
bookmarked: Boolean bookmarked: Boolean
@ -28,7 +28,7 @@ object side {
def meta( def meta(
pov: lila.game.Pov, pov: lila.game.Pov,
initialFen: Option[chess.format.FEN], initialFen: Option[chess.format.FEN],
tour: Option[lila.tournament.Tournament], tour: Option[lila.tournament.TourAndTeamVs],
simul: Option[lila.simul.Simul], simul: Option[lila.simul.Simul],
userTv: Option[lila.user.User] = None, userTv: Option[lila.user.User] = None,
bookmarked: Boolean bookmarked: Boolean
@ -88,8 +88,11 @@ object side {
), ),
div(cls := "game__meta__players")( div(cls := "game__meta__players")(
game.players.map { p => game.players.map { p =>
div(cls := s"player color-icon is ${p.color.name} text")( frag(
playerLink(p, withOnline = false, withDiff = true, withBerserk = true) 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 => tour.map { t =>
st.section(cls := "game__tournament")( st.section(cls := "game__tournament")(
a(cls := "text", dataIcon := "g", href := routes.Tournament.show(t.id))(t.fullName), a(cls := "text", dataIcon := "g", href := routes.Tournament.show(t.tour.id))(t.tour.fullName),
div(cls := "clock", dataTime := t.secondsToFinish)(div(cls := "time")(t.clockStatus)) div(cls := "clock", dataTime := t.tour.secondsToFinish)(div(cls := "time")(t.tour.clockStatus))
) )
} orElse { } orElse {
game.tournamentId map { tourId => game.tournamentId map { tourId =>

View File

@ -128,7 +128,7 @@ object bits {
)(implicit ctx: Context) = views.html.game.side( )(implicit ctx: Context) = views.html.game.side(
pov, pov,
(data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN), (data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN),
tour.map(_.tour), tour.map(_.tourAndTeamVs),
simul = simul, simul = simul,
userTv = userTv, userTv = userTv,
bookmarked = bookmarked bookmarked = bookmarked

View File

@ -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] = def countActive(tourId: Tournament.ID): Fu[Int] =
coll.countSel(selectTour(tourId) ++ selectActive) coll.countSel(selectTour(tourId) ++ selectActive)

View File

@ -17,6 +17,8 @@ object TeamBattle {
def init(teamId: TeamID) = TeamBattle(Set(teamId), 5) def init(teamId: TeamID) = TeamBattle(Set(teamId), 5)
case class TeamVs(teams: chess.Color.Map[TeamID])
case class RankedTeam( case class RankedTeam(
rank: Int, rank: Int,
teamId: TeamID, teamId: TeamID,

View File

@ -471,10 +471,22 @@ final class TournamentApi(
def tournamentTop(tourId: Tournament.ID): Fu[TournamentTop] = def tournamentTop(tourId: Tournament.ID): Fu[TournamentTop] =
tournamentTopCache get tourId tournamentTopCache get tourId
def miniView(tourId: Tournament.ID, withTop: Boolean): Fu[Option[TourMiniView]] = def miniView(game: Game, withTop: Boolean): Fu[Option[TourMiniView]] =
tournamentRepo byId tourId flatMap { 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 => _ ?? { tour =>
withTop ?? { tournamentTop(tour.id) map some } map { TourMiniView(tour, _).some } (tour.isTeamBattle ?? playerRepo.teamVs(tour.id, game)) map {
TourAndTeamVs(tour, _).some
}
} }
} }

View File

@ -4,7 +4,15 @@ final class LeaderboardRepo(val coll: lila.db.dsl.Coll)
case class TournamentTop(value: List[Player]) extends AnyVal 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]) { case class MyInfo(rank: Int, withdraw: Boolean, gameId: Option[lila.game.Game.ID]) {
def page = { def page = {

View File

@ -3,6 +3,9 @@
.game__meta { .game__meta {
flex: 0 0 auto; flex: 0 0 auto;
&__players .team {
margin-left: 1.7em;
}
} }
} }