tournaments v2: the whole thing compiles \o/

This commit is contained in:
Thibault Duplessis 2015-06-12 15:15:35 +02:00
parent b98358e705
commit dedc5616d0
12 changed files with 47 additions and 40 deletions

View file

@ -84,7 +84,7 @@ object Tournament extends LilaController {
def withdraw(id: String) = Auth { implicit ctx =>
me =>
OptionResult(repo byId id) { tour =>
env.api.withdraw(tour, me.id)
env.api.withdraw(tour.id, me.id)
if (HTTPRequest.isXhr(ctx.req)) Ok(Json.obj("ok" -> true)) as JSON
else Redirect(routes.Tournament.show(tour.id))
}

View file

@ -26,7 +26,7 @@
<td class="small">
<span data-icon="p">&nbsp;@tour.clock.show</span>
@if(tour.variant.exotic) { @tour.variant.shortName }
@if(tour.rated) {
@if(tour.mode.rated) {
<span class="trans_me">@trans.rated.en()</span>
}
</td>

View file

@ -2,20 +2,20 @@
<div class="game_tournament side_box no_padding scroll-shadow-soft">
<p class="top text" data-icon="g"><a href="@routes.Tournament.show(m.tour.id)">@m.tour.fullName</a></p>
<div class="clock" data-time="@m.tour.remainingSeconds">
<div class="clock" data-time="@m.tour.secondsToFinish">
<div class="time text" data-icon="p">@m.tour.clockStatus</div>
</div>
@if(withStanding) {
@m.standing.map { standing =>
<table class="slist standing">
<tbody>
@m.standing.map {
@standing.map {
case lila.tournament.RankedPlayer(rank, player) => {
<tr @if(ctx.userId.exists(player.id==)) { class="me" }>
<td class="name">
@if(player.withdraw) {
<span data-icon="b" title="@trans.withdraw()"></span>
} else {
@if(t.isFinished && rank == 1) {
@if(m.tour.isFinished && rank == 1) {
<span data-icon="g" title="@trans.winner()"></span>
} else {
<span class="rank">@rank</span>
@ -24,12 +24,9 @@
@userInfosLink(player.id, none, withOnline = false)
</td>
<td class="total">
<strong@if(onFire) { class="is-gold" data-icon="Q" }>@scoreSheet.total</strong>
<strong@if(player.fire) { class="is-gold" data-icon="Q" }>@player.score</strong>
</td>
</tr>
<tr><td class="around-bar" colspan="3"><div class="bar" data-value="@scoreSheet.total"></div></td></tr>
}
}
}
}
</tbody>

View file

@ -2,27 +2,23 @@
@joinButton(tour: Tournament) = {
@ctx.me.map { me =>
@if(tour isActive me) {
<span class="joined text" data-icon="E">JOINED</span>
} else {
<form class="inline" action="@routes.Tournament.join(tour.id)" method="POST">
<button data-icon="G" type="submit" class="submit button text">@trans.join()</button>
</form>
}
}
}
@iconTd(tour: tournament.Tournament) = {
@iconTd(tour: Tournament) = {
<td class="icon">
<span @if(tour.scheduled){class="is-gold"} data-icon="@tournamentIconChar(tour)"></span>
</td>
}
@tourTd(tour: tournament.Tournament) = {
@tourTd(tour: Tournament) = {
<td class="header">
<a href="@routes.Tournament.show(tour.id)">
<span class="name">
@tour.fullName @if(!tour.rated) {<em class="casual">@trans.casual()</em>}
@tour.fullName @if(!tour.mode.rated) {<em class="casual">@trans.casual()</em>}
</span>
@setup(tour)
</a>
@ -102,8 +98,8 @@
@tourTd(tour)
<td>@tour.durationString</td>
<td class="text" data-icon="r">@tour.nbPlayers</td>
<td>@tour.winner.map { player =>
@userInfosLink(player.id, player.rating.some, withOnline = false)
<td>@tour.winnerId.map { userId =>
@userIdLink(userId.some, withOnline = false)
}
</td>
</tr>

View file

@ -13,7 +13,5 @@
@if(!tour.position.initial) {
• thematic
}
@tour.startsAt.map { date =>
• @momentFromNow(date)
}
• @momentFromNow(tour.startsAt)
</span>

View file

@ -31,7 +31,7 @@ chessground = false) {
}></div>
@if(tour.isCreated) {
<div id="tournament_faq" class="none">
@faq(tour.rated.some, tour.system.some, tour.`private`.option(tour.id))
@faq(tour.mode.rated.some, tour.system.some, tour.`private`.option(tour.id))
</div>
}
}

View file

@ -32,8 +32,8 @@
<br /><br />
<strong>@tour.position.eco</strong> @tour.position.name
}
@tour.winner.filter(_ => tour.isFinished).map { winner =>
@tour.winnerId.map { userId =>
<br /><br />
@trans.winner(): @userInfosLink(winner.id, none)
@trans.winner(): @userIdLink(userId.some)
}
</div>

View file

@ -48,9 +48,11 @@ object BSONHandlers {
mode = r.intO("mode").fold[Mode](Mode.default)(Mode.orDefault),
`private` = r boolD "private",
schedule = r.getO[Schedule]("schedule"),
nbPlayers = r int "nbPlayers",
createdAt = r date "createdAt",
createdBy = r str "createdBy",
startsAt = r date "startsAt")
startsAt = r date "startsAt",
winnerId = r strO "winner")
def writes(w: BSON.Writer, o: Tournament) = BSONDocument(
"_id" -> o.id,
"name" -> o.name,
@ -63,9 +65,11 @@ object BSONHandlers {
"mode" -> o.mode.id,
"private" -> w.boolO(o.`private`),
"schedule" -> o.schedule,
"nbPlayers" -> o.nbPlayers,
"createdAt" -> w.date(o.createdAt),
"createdBy" -> w.str(o.createdBy),
"startsAt" -> w.date(o.startsAt))
"startsAt" -> w.date(o.startsAt),
"winner" -> o.winnerId)
}
implicit val playerBSONHandler = new BSON[Player] {

View file

@ -35,7 +35,6 @@ private[tournament] final class Organizer(
}
}
// def readyToFinish = (remainingSeconds == 0) || (!scheduled && nbActiveUsers < 2)
case StartedTournaments => TournamentRepo.started foreach {
_ foreach { tour =>
PlayerRepo activeUserIds tour.id map (_.toSet) foreach { activeUserIds =>

View file

@ -19,9 +19,11 @@ case class Tournament(
mode: Mode,
`private`: Boolean,
schedule: Option[Schedule],
nbPlayers: Int,
createdAt: DateTime,
createdBy: String,
startsAt: DateTime) {
startsAt: DateTime,
winnerId: Option[String] = None) {
def isCreated = status == Status.Created
def isStarted = status == Status.Started
@ -85,6 +87,7 @@ object Tournament {
minutes = minutes,
createdBy = createdBy.id,
createdAt = DateTime.now,
nbPlayers = 0,
variant = variant,
position = position,
mode = mode,
@ -101,6 +104,7 @@ object Tournament {
minutes = minutes,
createdBy = "lichess",
createdAt = DateTime.now,
nbPlayers = 0,
variant = sched.variant,
position = StartingPosition.initial,
mode = Mode.Rated,

View file

@ -48,12 +48,7 @@ private[tournament] final class TournamentApi(
system = System.Arena,
variant = variant,
position = StartingPosition.byEco(setup.position).ifTrue(variant.standard) | StartingPosition.initial)
TournamentRepo.insert(tour).void >>
PlayerRepo.join(tour.id, me, tour.perfLens) >>- {
withdrawAllBut(tour.id, me.id)
publish()
timeline ! (Propagate(TourJoin(me.id, tour.id, tour.fullName)) toFollowersOf me.id)
} inject tour
TournamentRepo.insert(tour) >>- join(tour.id, me) inject tour
}
private[tournament] def createScheduled(schedule: Schedule): Funit =
@ -93,14 +88,15 @@ private[tournament] final class TournamentApi(
_ <- TournamentRepo.setStatus(tour.id, Status.Finished)
_ <- PlayerRepo unWithdraw tour.id
_ <- PairingRepo removePlaying tour.id
finished <- TournamentRepo finishedById tour.id flatten s"Tour ${tour.id} missing"
winner <- PlayerRepo winner tour.id
_ <- winner.??(p => TournamentRepo.setWinnerId(tour.id, p.id))
} yield {
sendTo(finished.id, Reload)
sendTo(tour.id, Reload)
publish()
PlayerRepo withPoints finished.id foreach {
PlayerRepo withPoints tour.id foreach {
_ foreach { p => UserRepo.incToints(p.id, p.score) }
}
// awardTrophies(finished)
// awardTrophies(tour)
}
}
}
@ -117,7 +113,7 @@ private[tournament] final class TournamentApi(
def join(tourId: String, me: User) {
Sequencing(tourId)(TournamentRepo.enterableById) { tour =>
PlayerRepo.join(tour.id, me, tour.perfLens) >>- {
PlayerRepo.join(tour.id, me, tour.perfLens) >> updateNbPlayers(tour.id) >>- {
withdrawAllBut(tour.id, me.id)
sendTo(tour.id, Joining(me.id))
socketReload(tour.id)
@ -127,6 +123,9 @@ private[tournament] final class TournamentApi(
}
}
private def updateNbPlayers(tourId: String) =
PlayerRepo count tourId flatMap { TournamentRepo.setNbPlayers(tourId, _) }
private def withdrawAllBut(tourId: String, userId: String) {
TournamentRepo.allEnterable foreach {
_ filter (_.id != tourId) foreach { other =>

View file

@ -68,6 +68,16 @@ object TournamentRepo {
BSONDocument("$set" -> BSONDocument("status" -> status.id))
).void
def setNbPlayers(tourId: String, nb: Int) = coll.update(
selectId(tourId),
BSONDocument("$set" -> BSONDocument("nbPlayers" -> nb))
).void
def setWinnerId(tourId: String, userId: String) = coll.update(
selectId(tourId),
BSONDocument("$set" -> BSONDocument("winner" -> userId))
).void
private def allCreatedSelect = createdSelect ++ BSONDocument(
"$or" -> BSONArray(
BSONDocument("schedule" -> BSONDocument("$exists" -> false)),