tournament app

pull/83/head
Thibault Duplessis 2013-05-12 12:02:45 -03:00
parent e9dde5d2d4
commit 7fe25a2a61
40 changed files with 203 additions and 253 deletions

View File

@ -100,8 +100,8 @@ private[controllers] trait LilaController
})
}
// protected def NoEngine[A <: Result](a: A)(implicit ctx: Context): Result =
// ctx.me.fold(false)(_.engine).fold(Forbidden(views.html.site.noEngine()), a)
protected def NoEngine[A <: Result](a: Fu[A])(implicit ctx: Context): Fu[Result] =
ctx.me.zmap(_.engine).fold(Forbidden(views.html.site.noEngine()).fuccess, a)
protected def JsonOk[A: Writes](fua: Fu[A]) = fua map { a
Ok(Json toJson a) as JSON
@ -114,13 +114,6 @@ private[controllers] trait LilaController
protected def JsOk(fua: Fu[String], headers: (String, String)*) =
fua map { a Ok(a) as JAVASCRIPT withHeaders (headers: _*) }
// protected def ValidOk(valid: Valid[Unit]): Result = valid.fold(
// e BadRequest(e.shows),
// _ Ok("ok")
// )
// protected def ValidFuk(valid: Fu[Valid[Unit]]): Result = ValidOk(valid.unsafePerformFu)
protected def FormResult[A](form: Form[A])(op: A Fu[Result])(implicit req: Request[_]): Fu[Result] =
form.bindFromRequest.fold(
form fuccess(BadRequest(form.errors mkString "\n")),
@ -140,18 +133,10 @@ private[controllers] trait LilaController
protected def OptionFuOk[A, B: Writeable: ContentTypeOf](fua: Fu[Option[A]])(op: A Fu[B])(implicit ctx: Context) =
fua flatMap { _.fold(notFound(ctx))(a op(a) map { Ok(_) }) }
// protected def FuptionFuResult[A](fua: Fu[Option[A]])(op: A Fu[Result])(implicit ctx: Context) =
// fua flatMap { _.fold(io(notFound(ctx)))(op) } unsafePerformFu
// protected def FuptionRedirect[A](fua: Fu[Option[A]])(op: A Call)(implicit ctx: Context) =
// fua map {
// _.fold(notFound(ctx))(a Redirect(op(a)))
// } unsafePerformFu
// protected def FuptionFuRedirect[A](fua: Fu[Option[A]])(op: A Fu[Call])(implicit ctx: Context) =
// (fua flatMap {
// _.fold(io(notFound(ctx)))(a op(a) map { b Redirect(b) })
// }: Fu[Result]).unsafePerformFu
protected def OptionFuRedirect[A](fua: Fu[Option[A]])(op: A Fu[Call])(implicit ctx: Context) =
fua flatMap {
_.fold(notFound(ctx))(a op(a) map { b Redirect(b) })
}
protected def OptionFuRedirectUrl[A](fua: Fu[Option[A]])(op: A Fu[String])(implicit ctx: Context) =
fua flatMap {
@ -167,10 +152,6 @@ private[controllers] trait LilaController
protected def notFound(implicit ctx: Context): Fu[Result] =
Lobby handleNotFound ctx
// protected def todo = Open { implicit ctx
// NotImplemented(views.html.site.todo())
// }
protected def isGranted(permission: Permission.type Permission)(implicit ctx: Context): Boolean =
isGranted(permission(Permission))

View File

@ -13,7 +13,6 @@ import play.api.libs.json.Json
object Lobby extends LilaController with Results {
// private def openTours = Env.tournament.repo.created
private def openTours = fuccess(List[Created]())
def home = Open { implicit ctx

View File

@ -2,170 +2,151 @@ package controllers
import lila.app._
import views._
import lila.game.Pov
// import lila.tournament.{ Created, Started, Finished }
import lila.tournament.{ Tournament Tourney }
import lila.user.Context
import lila.game.{ Pov, GameRepo }
import lila.tournament.{ TournamentRepo, Created, Started, Finished, Tournament Tourney }
import lila.user.{ UserRepo, Context }
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.iteratee._
import play.api.libs.concurrent._
import play.api.templates.Html
import play.api.libs.json.JsValue
object Tournament extends LilaController {
// private def repo = env.tournament.repo
// private def forms = env.tournament.forms
// private def api = env.tournament.api
// private def socket = env.tournament.socket
// private def messenger = env.tournament.messenger
// private def userRepo = env.user.userRepo
// private def gameRepo = env.game.gameRepo
private def env = Env.tournament
private def repo = TournamentRepo
val home = TODO
// Open { implicit ctx
// Async {
// futureTournaments zip userRepo.sortedByToints(10).toFuture map {
// case (((created, started), finished), leaderboard)
// Ok(html.tournament.home(created, started, finished, leaderboard))
// }
// }
// }
val home = Open { implicit ctx
tournaments zip UserRepo.allSortToints(10) map {
case (((created, started), finished), leaderboard)
Ok(html.tournament.home(created, started, finished, leaderboard))
}
}
// val faq = Open { implicit ctx Ok(html.tournament.faqPage()) }
val faq = Open { implicit ctx Ok(html.tournament.faqPage()).fuccess }
// val homeReload = Open { implicit ctx
// Async {
// futureTournaments map {
// case ((created, started), finished)
// Ok(html.tournament.homeInner(created, started, finished))
// }
// }
// }
val homeReload = Open { implicit ctx
tournaments map {
case ((created, started), finished)
Ok(html.tournament.homeInner(created, started, finished))
}
}
// private def futureTournaments =
// repo.created.toFuture zip repo.started.toFuture zip repo.finished(20).toFuture
private def tournaments =
repo.created zip repo.started zip repo.finished(20)
def show(id: String) = TODO
// Open { implicit ctx
// IOResult(for {
// t repo byId id
// res t match {
// case Some(tour: Created) showCreated(tour) map { Ok(_) }
// case Some(tour: Started) showStarted(tour) map { Ok(_) }
// case Some(tour: Finished) showFinished(tour) map { Ok(_) }
// case _ io(NotFound(html.tournament.notFound()))
// }
// } yield res)
// }
def show(id: String) = Open { implicit ctx
repo byId id flatMap {
_ match {
case Some(tour: Created) showCreated(tour) map { Ok(_) }
case Some(tour: Started) showStarted(tour) map { Ok(_) }
case Some(tour: Finished) showFinished(tour) map { Ok(_) }
case _ NotFound(html.tournament.notFound()).fuccess
}
}
}
// private def showCreated(tour: Created)(implicit ctx: Context) = for {
// roomHtml messenger render tour
// } yield html.tournament.show.created(
// tour = tour,
// roomHtml = Html(roomHtml),
// version = version(tour.id))
private def showCreated(tour: Created)(implicit ctx: Context) =
env.version(tour.id) zip (env.messenger getMessages tour.id) map {
case (version, messages)
html.tournament.show.created(tour, messages, version)
}
// private def showStarted(tour: Started)(implicit ctx: Context) = for {
// roomHtml messenger render tour
// games gameRepo games (tour recentGameIds 4)
// pov tour.userCurrentPov(ctx.me).fold(io(none[Pov]))(gameRepo.pov)
// } yield html.tournament.show.started(
// tour = tour,
// roomHtml = Html(roomHtml),
// version = version(tour.id),
// games = games,
// pov = pov)
private def showStarted(tour: Started)(implicit ctx: Context) =
env.version(tour.id) zip
(env.messenger getMessages tour.id) zip
GameRepo.games(tour recentGameIds 4) zip
tour.userCurrentPov(ctx.me).zmap(GameRepo.pov) map {
case (((version, messages), games), pov)
html.tournament.show.started(tour, messages, version, games, pov)
}
// private def showFinished(tour: Finished)(implicit ctx: Context) = for {
// roomHtml messenger render tour
// games gameRepo games (tour recentGameIds 4)
// } yield html.tournament.show.finished(
// tour = tour,
// roomHtml = Html(roomHtml),
// version = version(tour.id),
// games = games)
private def showFinished(tour: Finished)(implicit ctx: Context) =
env.version(tour.id) zip
(env.messenger getMessages tour.id) zip
GameRepo.games(tour recentGameIds 4) map {
case ((version, messages), games)
html.tournament.show.finished(tour, messages, version, games)
}
// def join(id: String) = AuthBody { implicit ctx
// implicit me
// NoEngine {
// IOptionIORedirect(repo createdById id) { tour
// api.join(tour, me).fold(
// err putStrLn(err.shows) map (_ routes.Tournament.home()),
// res res map (_ routes.Tournament.show(tour.id))
// )
// }
// }
// }
def join(id: String) = AuthBody { implicit ctx
implicit me
NoEngine {
OptionFuRedirect(repo createdById id) { tour
env.api.join(tour, me).fold(
err {
logwarn(err.toString)
routes.Tournament.home()
},
_ routes.Tournament.show(tour.id)
)
}
}
}
// def withdraw(id: String) = Auth { implicit ctx
// implicit me
// IOptionIORedirect(repo byId id) { tour
// api.withdraw(tour, me.id) inject routes.Tournament.show(tour.id)
// }
// }
def withdraw(id: String) = Auth { implicit ctx
implicit me
OptionFuRedirect(repo byId id) { tour
env.api.withdraw(tour, me.id) inject routes.Tournament.show(tour.id)
}
}
// def earlyStart(id: String) = Auth { implicit ctx
// implicit me
// IOptionIORedirect(repo.createdByIdAndCreator(id, me.id)) { tour
// ~api.earlyStart(tour) inject routes.Tournament.show(tour.id)
// }
// }
def earlyStart(id: String) = Auth { implicit ctx
implicit me
OptionFuRedirect(repo.createdByIdAndCreator(id, me.id)) { tour
~env.api.earlyStart(tour) inject routes.Tournament.show(tour.id)
}
}
// def reload(id: String) = Open { implicit ctx
// IOptionIOk(repo byId id) {
// case tour: Created reloadCreated(tour)
// case tour: Started reloadStarted(tour)
// case tour: Finished reloadFinished(tour)
// }
// }
def reload(id: String) = Open { implicit ctx
OptionFuOk(repo byId id) {
case tour: Created reloadCreated(tour)
case tour: Started reloadStarted(tour)
case tour: Finished reloadFinished(tour)
}
}
// private def reloadCreated(tour: Created)(implicit ctx: Context) = io {
// val inner = html.tournament.show.createdInner(tour)
// html.tournament.show.inner(none)(inner)
// }
private def reloadCreated(tour: Created)(implicit ctx: Context) = fuccess {
html.tournament.show.inner(none)(html.tournament.show.createdInner(tour))
}
// private def reloadStarted(tour: Started)(implicit ctx: Context) = for {
// games gameRepo games (tour recentGameIds 4)
// pov tour.userCurrentPov(ctx.me).fold(io(none[Pov]))(gameRepo.pov)
// } yield {
// val pairings = html.tournament.pairings(tour)
// val inner = html.tournament.show.startedInner(tour, games, pov)
// html.tournament.show.inner(pairings.some)(inner)
// }
private def reloadStarted(tour: Started)(implicit ctx: Context) =
GameRepo.games(tour recentGameIds 4) zip
tour.userCurrentPov(ctx.me).zmap(GameRepo.pov) map {
case (games, pov) {
val pairings = html.tournament.pairings(tour)
val inner = html.tournament.show.startedInner(tour, games, pov)
html.tournament.show.inner(pairings.some)(inner)
}
}
// private def reloadFinished(tour: Finished)(implicit ctx: Context) =
// gameRepo games (tour recentGameIds 4) map { games
// val pairings = html.tournament.pairings(tour)
// val inner = html.tournament.show.finishedInner(tour, games)
// html.tournament.show.inner(pairings.some)(inner)
// }
private def reloadFinished(tour: Finished)(implicit ctx: Context) =
GameRepo games (tour recentGameIds 4) map { games
val pairings = html.tournament.pairings(tour)
val inner = html.tournament.show.finishedInner(tour, games)
html.tournament.show.inner(pairings.some)(inner)
}
// def form = Auth { implicit ctx
// me
// NoEngine {
// Ok(html.tournament.form(forms.create, forms))
// }
// }
def form = Auth { implicit ctx
me
NoEngine {
Ok(html.tournament.form(env.forms.create, env.forms)).fuccess
}
}
// def create = AuthBody { implicit ctx
// implicit me
// NoEngine {
// IOResult {
// implicit val req = ctx.body
// forms.create.bindFromRequest.fold(
// err io(BadRequest(html.tournament.form(err, forms))),
// setup api.createTournament(setup, me) map { tour
// Redirect(routes.Tournament.show(tour.id))
// })
// }
// }
// }
def create = AuthBody { implicit ctx
implicit me
NoEngine {
implicit val req = ctx.body
env.forms.create.bindFromRequest.fold(
err BadRequest(html.tournament.form(err, env.forms)).fuccess,
setup env.api.createTournament(setup, me) map { tour
Redirect(routes.Tournament.show(tour.id))
})
}
}
// def websocket(id: String) = Socket[JsValue] { implicit ctx
// socket.join(id, getInt("version"), get("sri"), ctx.me).unsafePerformIO
// }
// private def version(tournamentId: String): Int = socket blockingVersion tournamentId
def websocket(id: String) = Socket[JsValue] { implicit ctx
~(getInt("version") |@| get("sri") apply {
case (version, uid) env.socketHandler.join(id, version, uid, ctx.me)
})
}
}

View File

@ -13,14 +13,14 @@ final class SiteMenu(trans: I18nKeys) {
val play = new Elem("play", routes.Lobby.home, trans.play)
val game = new Elem("game", routes.Game.realtime, trans.games)
// val tournament = new Elem("tournament", routes.Tournament.home, trans.tournament)
val tournament = new Elem("tournament", routes.Tournament.home, trans.tournament)
val user = new Elem("user", routes.User.list(page = 1), trans.people)
val team = new Elem("team", routes.Team.home(page = 1), trans.teams)
val forum = new Elem("forum", routes.ForumCateg.index, trans.forum)
val message = new Elem("message", routes.Message.inbox(page = 1), trans.inbox)
private val authenticated = List(play, game, user, team, forum, message)//, game, tournament, user, team, forum, message)
private val anonymous = List(play, game, user, team, forum)//, game, tournament, user, team, forum)
private val authenticated = List(play, game, tournament, user, team, forum, message)
private val anonymous = List(play, game, tournament, user, team, forum)
def all(me: Option[User]) = me.isDefined.fold(authenticated, anonymous)
}

View File

@ -1,4 +1,4 @@
@(tours: List[lila.app.tournament.Created])
@(tours: List[lila.tournament.Created])
@if(tours.isEmpty) {
<tr class="create">

View File

@ -1,4 +1,4 @@
@(form: Form[_], config: lila.app.tournament.DataForm)(implicit ctx: Context)
@(form: Form[_], config: lila.tournament.DataForm)(implicit ctx: Context)
@import config._

View File

@ -1,4 +1,4 @@
@(games: List[DbGame])(implicit ctx: Context)
@(games: List[Game])(implicit ctx: Context)
<div class="game_list realtime clearfix">
@games.map { game =>

View File

@ -1,4 +1,4 @@
@(createds: List[lila.app.tournament.Created], starteds: List[lila.app.tournament.Started], finisheds: List[lila.app.tournament.Finished], leaderboard: List[User])(implicit ctx: Context)
@(createds: List[lila.tournament.Created], starteds: List[lila.tournament.Started], finisheds: List[lila.tournament.Finished], leaderboard: List[User])(implicit ctx: Context)
@goodies = {
<div class="tournament_links">

View File

@ -1,4 +1,4 @@
@(createds: List[lila.app.tournament.Created], starteds: List[lila.app.tournament.Started], finisheds: List[lila.app.tournament.Finished])(implicit ctx: Context)
@(createds: List[lila.tournament.Created], starteds: List[lila.tournament.Started], finisheds: List[lila.tournament.Finished])(implicit ctx: Context)
<div class="content_box tournament_box no_padding">
<h1>Tournaments</h1>

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Tournament)(implicit ctx: Context)
@(tour: lila.tournament.Tournament)(implicit ctx: Context)
<div class="lichess_goodies">
<div class="box">

View File

@ -1,3 +1,3 @@
@(tour: lila.app.tournament.Tournament)
@(tour: lila.tournament.Tournament)
<a class="s16 tournament" href="@routes.Tournament.show(tour.id)">@tour.nameT</a>

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Tournament)(implicit ctx: Context)
@(tour: lila.tournament.Tournament)(implicit ctx: Context)
<div class="pairings">
@tour.numerotedPairings.map {

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Tournament)
@(tour: lila.tournament.Tournament)
@notification.view("tournament_reminder", closable = false) {
@linkTo(tour) in progress!

View File

@ -1,8 +1,8 @@
@(tour: lila.app.tournament.Created, roomHtml: Html, version: Int)(implicit ctx: Context)
@(tour: lila.tournament.Created, messages: List[lila.tournament.Room.Message], version: Int)(implicit ctx: Context)
@tournament.show.layout(
tour = tour,
roomHtml = roomHtml,
messages = messages,
goodies = tournament.infoBox(tour),
version = version,
title = tour.nameT) {

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Created)(implicit ctx: Context)
@(tour: lila.tournament.Created)(implicit ctx: Context)
<h1>@tour.nameT</h1>
<div class="user_list">

View File

@ -1,8 +1,8 @@
@(tour: lila.app.tournament.Finished, roomHtml: Html, version: Int, games: List[DbGame])(implicit ctx: Context)
@(tour: lila.tournament.Finished, messages: List[lila.tournament.Room.Message], version: Int, games: List[Game])(implicit ctx: Context)
@tournament.show.layout(
tour = tour,
roomHtml = roomHtml,
messages = messages,
goodies = tournament.infoBox(tour),
version = version,
side = tournament.pairings(tour).some,

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Finished, games: List[DbGame])(implicit ctx: Context)
@(tour: lila.tournament.Finished, games: List[Game])(implicit ctx: Context)
<span class="title_tag">Finished</span>

View File

@ -1,10 +1,10 @@
@(tour: lila.app.tournament.Tournament, title: String, roomHtml: Html, version: Int, goodies: Html, side: Option[Html] = None)(body: Html)(implicit ctx: Context)
@(tour: lila.tournament.Tournament, title: String, messages: List[lila.tournament.Room.Message], version: Int, goodies: Html, side: Option[Html] = None)(body: Html)(implicit ctx: Context)
@chat = {
@for(m <- ctx.me; if m.canChat) {
@base.chatRoom(
title = "Tournament Room",
cssClass = "tournament_chat")(roomHtml)
cssClass = "tournament_chat")(tournament.show.room(messages))
}
}

View File

@ -0,0 +1,3 @@
@(messages: List[lila.tournament.Room.Message])
tournament room messages!

View File

@ -1,8 +1,8 @@
@(tour: lila.app.tournament.Started, roomHtml: Html, version: Int, games: List[DbGame], pov: Option[Pov])(implicit ctx: Context)
@(tour: lila.tournament.Started, messages: List[lila.tournament.Room.Message], version: Int, games: List[Game], pov: Option[Pov])(implicit ctx: Context)
@tournament.show.layout(
tour = tour,
roomHtml = roomHtml,
messages = messages,
goodies = tournament.infoBox(tour),
version = version,
side = tournament.pairings(tour).some,

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.Started, games: List[DbGame], pov: Option[Pov])(implicit ctx: Context)
@(tour: lila.tournament.Started, games: List[Game], pov: Option[Pov])(implicit ctx: Context)
<span class="tournament_clock title_tag" data-time="@tour.remainingSeconds">
@tour.clockStatus

View File

@ -1,4 +1,4 @@
@(tour: lila.app.tournament.StartedOrFinished)(implicit ctx: Context)
@(tour: lila.tournament.StartedOrFinished)(implicit ctx: Context)
<table class="slist standing">
<thead>

View File

@ -1,4 +1,4 @@
@(tours: List[lila.app.tournament.Tournament], name: String, cssClass: String = "", moreTr: Html = Html(""), showEmpty: Boolean = false)(implicit ctx: Context)
@(tours: List[lila.tournament.Tournament], name: String, cssClass: String = "", moreTr: Html = Html(""), showEmpty: Boolean = false)(implicit ctx: Context)
@if(showEmpty || tours.nonEmpty) {
<thead>

View File

@ -62,16 +62,17 @@ GET /$fullId<[\w\-]{12}>/table controllers.Round.tablePlay
GET /$gameId<[\w\-]{8}>/players controllers.Round.players(gameId: String)
# Tournament
# GET /tournament controllers.Tournament.home
# GET /tournament/reload controllers.Tournament.homeReload
# GET /tournament/new controllers.Tournament.form
# POST /tournament/new controllers.Tournament.create
GET /tournament controllers.Tournament.home
GET /tournament/reload controllers.Tournament.homeReload
GET /tournament/new controllers.Tournament.form
POST /tournament/new controllers.Tournament.create
GET /tournament/$id<[\w\-]{8}> controllers.Tournament.show(id: String)
# GET /tournament/$id<[\w\-]{8}>/socket controllers.Tournament.websocket(id: String)
# POST /tournament/$id<[\w\-]{8}>/join controllers.Tournament.join(id: String)
# POST /tournament/$id<[\w\-]{8}>/withdraw controllers.Tournament.withdraw(id: String)
# GET /tournament/$id<[\w\-]{8}>/reload controllers.Tournament.reload(id: String)
# GET /tournament/faq controllers.Tournament.faq
GET /tournament/$id<[\w\-]{8}>/socket controllers.Tournament.websocket(id: String)
POST /tournament/$id<[\w\-]{8}>/join controllers.Tournament.join(id: String)
POST /tournament/$id<[\w\-]{8}>/withdraw controllers.Tournament.withdraw(id: String)
GET /tournament/$id<[\w\-]{8}>/reload controllers.Tournament.reload(id: String)
POST /tournament/$id<[\w\-]{8}>/early-start controllers.Tournament.earlyStart(id: String)
GET /tournament/faq controllers.Tournament.faq
# Team
GET /team controllers.Team.home(page: Int ?= 1)

View File

@ -25,6 +25,8 @@ object GameRepo {
def game(gameId: ID): Fu[Option[Game]] = $find byId gameId
def games(gameIds: Seq[ID]): Fu[List[Game]] = $find byOrderedIds gameIds
def finished(gameId: ID): Fu[Option[Game]] =
$find.one($select(gameId) ++ Query.finished)

View File

@ -8,7 +8,7 @@ import play.api.data._
import play.api.data.Forms._
import play.api.data.validation.Constraints._
private[tournament] final class DataForm(isDev: Boolean) {
final class DataForm(isDev: Boolean) {
val clockTimes = 0 to 7 by 1
val clockTimeDefault = 2

View File

@ -1,10 +1,12 @@
package lila.tournament
import lila.socket.History
import lila.common.PimpedConfig._
import makeTimeout.short
import com.typesafe.config.Config
import lila.common.PimpedConfig._
import akka.actor._
import akka.pattern.ask
final class Env(
config: Config,
@ -72,12 +74,15 @@ final class Env(
renderer = renderer
)), name = ReminderName)
def version(tourId: String): Fu[Int] =
socketHub ? actorApi.GetTournamentVersion(tourId) mapTo manifest[Int]
private lazy val joiner = new GameJoiner(
roundMeddler = roundMeddler,
timelinePush = timelinePush,
system = system)
private[tournament] lazy val messenger = new Messenger(NetDomain)
lazy val messenger = new Messenger(NetDomain)
private[tournament] lazy val tournamentColl = db(CollectionTournament)
private[tournament] lazy val roomColl = db(CollectionRoom)

View File

@ -30,4 +30,7 @@ private[tournament] final class Messenger(val netDomain: String) extends UserRoo
Message(none, text) |> { message
RoomRepo.addMessage(tour.id, message) inject message
}
def getMessages(tournamentId: String): Fu[List[Room.Message]] =
RoomRepo room tournamentId map (_.decodedMessages)
}

View File

@ -3,6 +3,8 @@ package lila.tournament
case class Room(id: String, messages: List[String]) {
def nonEmpty = messages.nonEmpty
def decodedMessages = messages map Room.decode
}
object Room {

View File

@ -7,6 +7,8 @@ import lila.socket.Handler
import lila.socket.actorApi.{ Connected _, _ }
import lila.security.Flood
import lila.common.PimpedJson._
import tube.tournamentTube
import lila.db.api.$count
import makeTimeout.short
import akka.actor._
@ -21,20 +23,25 @@ private[tournament] final class SocketHandler(
flood: Flood) {
def join(
tour: Tournament,
tourId: String,
version: Int,
uid: String,
user: Option[User]): Fu[JsSocketHandler] = for {
socket socketHub ? GetSocket(tour.id) mapTo manifest[ActorRef]
join = Join(
uid = uid,
user = user,
version = version)
handler Handler(socket, uid, join) {
case Connected(enum, member)
controller(socket, tour.id, uid, member) -> enum
user: Option[User]): Fu[JsSocketHandler] =
$count.exists(tourId) flatMap {
_ ?? {
for {
socket socketHub ? GetSocket(tourId) mapTo manifest[ActorRef]
join = Join(
uid = uid,
user = user,
version = version)
handler Handler(socket, uid, join) {
case Connected(enum, member)
controller(socket, tourId, uid, member) -> enum
}
} yield handler
}
}
} yield handler
private def controller(
socket: ActorRef,

View File

@ -20,6 +20,8 @@ object TournamentRepo {
case t: Finished t
}
def byId(id: String): Fu[Option[Tournament]] = $find byId id
def createdById(id: String): Fu[Option[Created]] = byIdAs(id, asCreated)
def startedById(id: String): Fu[Option[Started]] = byIdAs(id, asStarted)

View File

@ -1,21 +0,0 @@
@()(implicit ctx: Context)
@site.layout(
title = "Developers",
moreCss = cssTag("developers.css")) {
<div class="content_box small_box developers">
<h1 class="lichess_title">Developers</h1>
<p>
Do you have a chess website, and want to add a live chess section?<br />
Add the following line to your site html:
</p>
<pre>&lt;script src="http://en.lichess.org/embed.js?w=820h=650"&gt;&lt;/script&gt;</pre>
<p>The <strong>w</strong> and <strong>h</strong> parameters control the width and height of the chess window.</p>
<p>Integration example: <a href="http://www.chessworldweb.com/ru/lichess.html">ChessWorldWeb live chess</a></p>
</div>
}

View File

@ -1,6 +0,0 @@
@(title: String, moreCss: Html = Html(""))(body: Html)(implicit ctx: Context)
@base.layout(
title = title,
active = none,
moreCss = moreCss)(body)

View File

@ -1,9 +0,0 @@
@()(implicit ctx: Context)
@site.layout(
title = "To be implemented") {
<div class="content_box small_box">
This feature is temporarily disabled. Will be back soon, promise!
</div>
}