tournaments v2: the whole thing compiles \o/
This commit is contained in:
parent
b98358e705
commit
dedc5616d0
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<td class="small">
|
||||
<span data-icon="p"> @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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -13,7 +13,5 @@
|
|||
@if(!tour.position.initial) {
|
||||
• thematic
|
||||
}
|
||||
@tour.startsAt.map { date =>
|
||||
• @momentFromNow(date)
|
||||
}
|
||||
• @momentFromNow(tour.startsAt)
|
||||
</span>
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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)),
|
||||
|
|
Loading…
Reference in a new issue