team battle WIP
parent
cecbfa198d
commit
8ee9227f15
|
@ -110,7 +110,7 @@ object Tournament extends LilaController {
|
|||
shieldOwner <- env.shieldApi currentOwner tour
|
||||
} yield Ok(html.tournament.show(tour, verdicts, json, chat, streamers, shieldOwner))).mon(_.http.response.tournament.show.website)
|
||||
}, api = _ => tourOption.fold(notFoundJson("No such tournament")) { tour =>
|
||||
get("playerInfo").?? { env.api.playerInfo(tour.id, _) } zip
|
||||
get("playerInfo").?? { env.api.playerInfo(tour, _) } zip
|
||||
getBool("socketVersion").??(env version tour.id map some) flatMap {
|
||||
case (playerInfoExt, socketVersion) =>
|
||||
val partial = getBool("partial")
|
||||
|
@ -152,10 +152,30 @@ object Tournament extends LilaController {
|
|||
}
|
||||
}
|
||||
|
||||
def player(id: String, userId: String) = Open { implicit ctx =>
|
||||
JsonOk {
|
||||
env.api.playerInfo(id, userId) flatMap {
|
||||
_ ?? env.jsonView.playerInfoExtended
|
||||
def player(tourId: String, userId: String) = Open { implicit ctx =>
|
||||
TournamentRepo byId tourId flatMap {
|
||||
_ ?? { tour =>
|
||||
JsonOk {
|
||||
env.api.playerInfo(tour, userId) flatMap {
|
||||
_ ?? { env.jsonView.playerInfoExtended(tour, _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def team(tourId: String, teamId: String) = Open { implicit ctx =>
|
||||
TournamentRepo byId tourId flatMap {
|
||||
_ ?? { tour =>
|
||||
Env.team.api light teamId flatMap {
|
||||
_ ?? { team =>
|
||||
JsonOk {
|
||||
env.api.teamInfo(tour, team) flatMap {
|
||||
_ ?? { env.jsonView.teamInfo(tour, _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,6 +225,7 @@ GET /tournament/$id<\w{8}>/socket/v:apiVersion controllers.Tournament.websocke
|
|||
POST /tournament/$id<\w{8}>/join controllers.Tournament.join(id: String)
|
||||
POST /tournament/$id<\w{8}>/withdraw controllers.Tournament.pause(id: String)
|
||||
GET /tournament/$id<\w{8}>/player/:user controllers.Tournament.player(id: String, user: String)
|
||||
GET /tournament/$id<\w{8}>/team/:team controllers.Tournament.team(id: String, team: String)
|
||||
POST /tournament/$id<\w{8}>/terminate controllers.Tournament.terminate(id: String)
|
||||
GET /tournament/help controllers.Tournament.help(system: Option[String] ?= None)
|
||||
GET /tournament/limited-invitation controllers.Tournament.limitedInvitation
|
||||
|
|
|
@ -3,7 +3,8 @@ package lila.hub
|
|||
package object lightTeam {
|
||||
type TeamId = String
|
||||
type TeamName = String
|
||||
case class LightTeam(id: TeamId, name: TeamName) {
|
||||
case class LightTeam(_id: TeamId, name: TeamName) {
|
||||
def id = _id
|
||||
def pair = id -> name
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package lila.team
|
||||
|
||||
import lila.hub.lightTeam.LightTeam
|
||||
|
||||
private object BSONHandlers {
|
||||
|
||||
import lila.db.dsl.BSONJodaDateTimeHandler
|
||||
implicit val TeamBSONHandler = reactivemongo.bson.Macros.handler[Team]
|
||||
implicit val RequestBSONHandler = reactivemongo.bson.Macros.handler[Request]
|
||||
implicit val MemberBSONHandler = reactivemongo.bson.Macros.handler[Member]
|
||||
implicit val LightTeamBSONHandler = reactivemongo.bson.Macros.handler[LightTeam]
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ final class TeamApi(
|
|||
|
||||
def team(id: Team.ID) = coll.team.byId[Team](id)
|
||||
|
||||
def light(id: Team.ID) = coll.team.byId[LightTeam](id, $doc("name" -> true))
|
||||
|
||||
def request(id: Team.ID) = coll.request.byId[Request](id)
|
||||
|
||||
def create(setup: TeamSetup, me: User): Option[Fu[Team]] = me.canTeam option {
|
||||
|
|
|
@ -55,7 +55,7 @@ final class JsonView(
|
|||
case _ => standing(tour, 1)
|
||||
}
|
||||
playerInfoJson <- playerInfoExt ?? { pie =>
|
||||
playerInfoExtended(pie).map(_.some)
|
||||
playerInfoExtended(tour, pie).map(_.some)
|
||||
}
|
||||
verdicts <- full ?? {
|
||||
me match {
|
||||
|
@ -149,11 +149,11 @@ final class JsonView(
|
|||
}
|
||||
}
|
||||
|
||||
def playerInfoExtended(info: PlayerInfoExt): Fu[JsObject] = for {
|
||||
ranking <- cached ranking info.tour
|
||||
sheet <- cached.sheet(info.tour, info.user.id)
|
||||
def playerInfoExtended(tour: Tournament, info: PlayerInfoExt): Fu[JsObject] = for {
|
||||
ranking <- cached ranking tour
|
||||
sheet <- cached.sheet(tour, info.user.id)
|
||||
} yield info match {
|
||||
case PlayerInfoExt(tour, user, player, povs) =>
|
||||
case PlayerInfoExt(user, player, povs) =>
|
||||
val isPlaying = povs.headOption.??(_.game.playable)
|
||||
val povScores: List[(LightPov, Option[Score])] = povs zip {
|
||||
(isPlaying ?? List(none[Score])) ::: sheet.scores.map(some)
|
||||
|
@ -382,6 +382,7 @@ final class JsonView(
|
|||
"rank" -> rt.rank,
|
||||
"id" -> rt.teamId,
|
||||
"score" -> rt.score,
|
||||
"nb" -> rt.nbPlayers,
|
||||
"players" -> rt.topPlayers.map { p =>
|
||||
Json.obj(
|
||||
"user" -> lightUserApi.sync(p.userId),
|
||||
|
|
|
@ -48,11 +48,15 @@ object PlayerRepo {
|
|||
Match(selectTour(tourId)),
|
||||
List(
|
||||
Sort(Descending("m")),
|
||||
GroupField("t")("m" -> Push($doc(
|
||||
"u" -> "$uid",
|
||||
"m" -> "$m"
|
||||
))),
|
||||
GroupField("t")(
|
||||
"nb" -> SumValue(1),
|
||||
"m" -> Push($doc(
|
||||
"u" -> "$uid",
|
||||
"m" -> "$m"
|
||||
))
|
||||
),
|
||||
Project($doc(
|
||||
"nb" -> true,
|
||||
"p" -> $doc(
|
||||
"$slice" -> $arr("$m", battle.nbTopPlayers)
|
||||
)
|
||||
|
@ -61,16 +65,17 @@ object PlayerRepo {
|
|||
maxDocs = 10
|
||||
).map {
|
||||
_.flatMap { doc =>
|
||||
doc.getAs[TeamId]("_id") flatMap { teamId =>
|
||||
doc.getAs[List[Bdoc]]("p") map {
|
||||
_.flatMap {
|
||||
case p: Bdoc => for {
|
||||
id <- p.getAs[User.ID]("u")
|
||||
magic <- p.getAs[Int]("m")
|
||||
} yield TopPlayer(id, magic)
|
||||
}
|
||||
} map { RankedTeam(0, teamId, _) }
|
||||
}
|
||||
for {
|
||||
teamId <- doc.getAs[TeamId]("_id")
|
||||
nbPlayers <- doc.getAs[Int]("nb")
|
||||
topPlayersBson <- doc.getAs[List[Bdoc]]("p")
|
||||
topPlayers = topPlayersBson.flatMap {
|
||||
case p: Bdoc => for {
|
||||
id <- p.getAs[User.ID]("u")
|
||||
magic <- p.getAs[Int]("m")
|
||||
} yield TopPlayer(id, magic)
|
||||
}
|
||||
} yield RankedTeam(0, teamId, nbPlayers, topPlayers)
|
||||
}.sortBy(-_.magicScore).zipWithIndex map {
|
||||
case (rt, pos) => rt.copy(rank = pos + 1)
|
||||
}
|
||||
|
@ -78,7 +83,7 @@ object PlayerRepo {
|
|||
if (ranked.size == battle.teams.size) ranked
|
||||
else ranked ::: battle.teams.foldLeft(List.empty[RankedTeam]) {
|
||||
case (missing, team) if !ranked.exists(_.teamId == team) =>
|
||||
RankedTeam(missing.headOption.fold(ranked.size)(_.rank) + 1, team, Nil) :: missing
|
||||
RankedTeam(missing.headOption.fold(ranked.size)(_.rank) + 1, team, 0, Nil) :: missing
|
||||
case (acc, _) => acc
|
||||
}.reverse
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ object TeamBattle {
|
|||
case class RankedTeam(
|
||||
rank: Int,
|
||||
teamId: TeamId,
|
||||
nbPlayers: Int,
|
||||
topPlayers: List[TopPlayer]
|
||||
) {
|
||||
def magicScore = topPlayers.foldLeft(0)(_ + _.magicScore)
|
||||
|
|
|
@ -457,23 +457,28 @@ final class TournamentApi(
|
|||
VisibleTournaments(created, started, finished)
|
||||
}
|
||||
|
||||
def playerInfo(tourId: Tournament.ID, userId: User.ID): Fu[Option[PlayerInfoExt]] =
|
||||
def playerInfo(tour: Tournament, userId: User.ID): Fu[Option[PlayerInfoExt]] =
|
||||
UserRepo named userId flatMap {
|
||||
_ ?? { user =>
|
||||
TournamentRepo byId tourId flatMap {
|
||||
_ ?? { tour =>
|
||||
PlayerRepo.find(tour.id, user.id) flatMap {
|
||||
_ ?? { player =>
|
||||
playerPovs(tour, user.id, 50) map { povs =>
|
||||
PlayerInfoExt(tour, user, player, povs).some
|
||||
}
|
||||
}
|
||||
PlayerRepo.find(tour.id, user.id) flatMap {
|
||||
_ ?? { player =>
|
||||
playerPovs(tour, user.id, 50) map { povs =>
|
||||
PlayerInfoExt(user, player, povs).some
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def teamInfo(tour: Tournament, team: LightTeam): Fu[Option[PlayerInfoExt]] =
|
||||
PlayerRepo.find(tour.id, user.id) flatMap {
|
||||
_ ?? { player =>
|
||||
playerPovs(tour, user.id, 50) map { povs =>
|
||||
PlayerInfoExt(user, player, povs).some
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def allCurrentLeadersInStandard: Fu[Map[Tournament, TournamentTop]] =
|
||||
TournamentRepo.standardPublicStartedFromSecondary.flatMap { tours =>
|
||||
tours.map { tour =>
|
||||
|
|
|
@ -22,7 +22,6 @@ case class VisibleTournaments(
|
|||
}
|
||||
|
||||
case class PlayerInfoExt(
|
||||
tour: Tournament,
|
||||
user: lila.user.User,
|
||||
player: Player,
|
||||
recentPovs: List[lila.game.LightPov]
|
||||
|
|
|
@ -116,7 +116,8 @@ lichess.powertip = (() => {
|
|||
}).data('powertip', ' ').on({
|
||||
powerTipRender: onPowertipPreRender('powerTip', (url) => {
|
||||
const u = url.substr(3);
|
||||
$('#powerTip').html('<div class="upt__info"><div class="upt__info__top"><span class="user-link offline">' + $(el).html() + '</span></div></div><div class="upt__actions btn-rack">' +
|
||||
const name = $(el).data('name') || $(el).html();
|
||||
$('#powerTip').html('<div class="upt__info"><div class="upt__info__top"><span class="user-link offline">' + name + '</span></div></div><div class="upt__actions btn-rack">' +
|
||||
uptA('/@/' + u + '/tv', '1') +
|
||||
uptA('/inbox/new?user=' + u, 'c') +
|
||||
uptA('/?user=' + u + '#friend', 'U') +
|
||||
|
|
|
@ -18,6 +18,7 @@ export default class TournamentController {
|
|||
focusOnMe: boolean;
|
||||
joinSpinner: boolean = false;
|
||||
playerInfo: PlayerInfo = {};
|
||||
teamInfo: TeamInfo = {};
|
||||
disableClicks: boolean = true;
|
||||
searching: boolean = false;
|
||||
joinWithTeamSelector: boolean = false;
|
||||
|
|
|
@ -28,6 +28,7 @@ export interface RankedTeam {
|
|||
id: string;
|
||||
rank: number;
|
||||
score: number;
|
||||
nb: number;
|
||||
players: TeamPlayer[];
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,10 @@ function teamTr(ctrl: TournamentController, battle: TeamBattle, team: RankedTeam
|
|||
players.push(h('score.ulpt.user-link', {
|
||||
key: p.user.name,
|
||||
class: { top: i === 0 },
|
||||
attrs: { 'data-href': '/@/' + p.user.name },
|
||||
attrs: {
|
||||
'data-href': '/@/' + p.user.name,
|
||||
'data-name': p.user.name
|
||||
},
|
||||
hook: {
|
||||
destroy: vnode => $.powerTip.destroy(vnode.elm as HTMLElement),
|
||||
...bind('click', _ => ctrl.jumpToPageOf(p.user.name), ctrl.redraw)
|
||||
|
@ -67,7 +70,10 @@ function teamTr(ctrl: TournamentController, battle: TeamBattle, team: RankedTeam
|
|||
hook: bind('click', _ => {}, ctrl.redraw)
|
||||
}, [
|
||||
h('td.rank', '' + team.rank),
|
||||
h('td.team', battle.teams[team.id]),
|
||||
h('td.team', [
|
||||
battle.teams[team.id],
|
||||
' (' + team.nb + ')'
|
||||
]),
|
||||
h('td.players', players),
|
||||
h('td.total', [
|
||||
h('strong', '' + team.score)
|
||||
|
|
Loading…
Reference in New Issue