more relay integration
parent
f45fa62d83
commit
9acf56139d
|
@ -56,8 +56,9 @@ object Analyse extends LilaController {
|
|||
else GameRepo initialFen pov.game.id flatMap { initialFen =>
|
||||
(env.analyser get pov.game.id) zip
|
||||
(pov.game.simulId ?? Env.simul.repo.find) zip
|
||||
(pov.game.relayId ?? Env.relay.repo.byId) zip
|
||||
Env.game.crosstableApi(pov.game) flatMap {
|
||||
case ((analysis, simul), crosstable) =>
|
||||
case (((analysis, simul), relay), crosstable) =>
|
||||
val pgn = Env.game.pgnDump(pov.game, initialFen)
|
||||
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion,
|
||||
tv = none,
|
||||
|
@ -72,6 +73,7 @@ object Analyse extends LilaController {
|
|||
analysis,
|
||||
analysis filter (_.done) map { a => AdvantageChart(a.infoAdvices, pov.game.pgnMoves, pov.game.startedAtTurn) },
|
||||
simul,
|
||||
relay,
|
||||
new TimeChart(pov.game, pov.game.pgnMoves),
|
||||
crosstable,
|
||||
userTv,
|
||||
|
@ -84,8 +86,9 @@ object Analyse extends LilaController {
|
|||
GameRepo initialFen pov.game.id flatMap { initialFen =>
|
||||
(env.analyser get pov.game.id) zip
|
||||
(pov.game.simulId ?? Env.simul.repo.find) zip
|
||||
(pov.game.relayId ?? Env.relay.repo.byId) zip
|
||||
Env.game.crosstableApi(pov.game) map {
|
||||
case ((analysis, simul), crosstable) =>
|
||||
case (((analysis, simul), relay), crosstable) =>
|
||||
val pgn = Env.game.pgnDump(pov.game, initialFen)
|
||||
Ok(html.analyse.replayBot(
|
||||
pov,
|
||||
|
@ -93,6 +96,7 @@ object Analyse extends LilaController {
|
|||
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status, pov.game.clock).toString,
|
||||
analysis,
|
||||
simul,
|
||||
relay,
|
||||
crosstable))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,10 +152,11 @@ object Round extends LilaController with TheftPrevention {
|
|||
case None if HTTPRequest.isHuman(ctx.req) =>
|
||||
myTour(pov.game.tournamentId, false) zip
|
||||
(pov.game.simulId ?? Env.simul.repo.find) zip
|
||||
(pov.game.relayId ?? Env.relay.repo.byId) zip
|
||||
Env.game.crosstableApi(pov.game) zip
|
||||
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, tv = none) map {
|
||||
case (((tour, simul), crosstable), data) =>
|
||||
Ok(html.round.watcher(pov, data, tour, simul, crosstable, userTv = userTv))
|
||||
case ((((tour, simul), relay), crosstable), data) =>
|
||||
Ok(html.round.watcher(pov, data, tour, simul, relay, crosstable, userTv = userTv))
|
||||
}
|
||||
case _ => // web crawlers don't need the full thing
|
||||
GameRepo.initialFen(pov.game.id) zip
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(pov: Pov, data: play.api.libs.json.JsObject, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], advantageChart: Option[String], simul: Option[lila.simul.Simul], timeChart: lila.analyse.TimeChart, cross: Option[lila.game.Crosstable], userTv: Option[User], division: chess.Division)(implicit ctx: Context)
|
||||
@(pov: Pov, data: play.api.libs.json.JsObject, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], advantageChart: Option[String], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], timeChart: lila.analyse.TimeChart, cross: Option[lila.game.Crosstable], userTv: Option[User], division: chess.Division)(implicit ctx: Context)
|
||||
|
||||
@import pov._
|
||||
|
||||
|
@ -45,7 +45,7 @@ userId: @Html(ctx.userId.fold("null")(id => s""""$id""""))
|
|||
|
||||
@analyse.layout(
|
||||
title = title,
|
||||
side = views.html.game.side(pov, initialFen, none, simul = simul, userTv = userTv).some,
|
||||
side = views.html.game.side(pov, initialFen, none, simul = simul, relay = relay, userTv = userTv).some,
|
||||
chat = base.chatDom(trans.spectatorRoom.str(), ctx.isAuth).some,
|
||||
underchat = underchat.some,
|
||||
moreCss = moreCss,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(pov: Pov, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], simul: Option[lila.simul.Simul], cross: Option[lila.game.Crosstable])(implicit ctx: Context)
|
||||
@(pov: Pov, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], cross: Option[lila.game.Crosstable])(implicit ctx: Context)
|
||||
|
||||
@import pov._
|
||||
|
||||
|
@ -37,7 +37,7 @@ orientation: "@pov.color.name"
|
|||
|
||||
@analyse.layout(
|
||||
title = title,
|
||||
side = views.html.game.side(pov, initialFen, none, simul = simul).some,
|
||||
side = views.html.game.side(pov, initialFen, none, simul = simul, relay = relay).some,
|
||||
chat = base.chatDom(trans.spectatorRoom.str(), ctx.isAuth).some,
|
||||
underchat = underchat.some,
|
||||
moreJs = moreJs,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(pov: Pov, initialFen: Option[String], tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], userTv: Option[User] = None)(implicit ctx: Context)
|
||||
@(pov: Pov, initialFen: Option[String], tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], userTv: Option[User] = None)(implicit ctx: Context)
|
||||
|
||||
@import pov._
|
||||
@import lila.tournament.arena
|
||||
|
@ -104,4 +104,9 @@
|
|||
<p class="top text" data-icon="|"><a href="@routes.Simul.show(sim.id)">@sim.fullName</a></p>
|
||||
</div>
|
||||
}
|
||||
@relay.map { rel =>
|
||||
<div class="game_relay side_box no_padding">
|
||||
<p class="top text" data-icon="n"><a href="@routes.Relay.show(rel.id, rel.slug)">@rel.name</a></p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
@jsAt(s"compiled/lichess.relay${isProd??(".min")}.js")
|
||||
@embedJs {
|
||||
lichess = lichess || {};
|
||||
lichess.relay = LichessRelay(document.getElementById('relay'), {
|
||||
lichess.relay = {
|
||||
data: @Html(J.stringify(data)),
|
||||
i18n: @jsI18n(),
|
||||
socketVersion: @socketVersion
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(pov: Pov, data: play.api.libs.json.JsObject, tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], cross: Option[lila.game.Crosstable], userTv: Option[User] = None)(implicit ctx: Context)
|
||||
@(pov: Pov, data: play.api.libs.json.JsObject, tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], cross: Option[lila.game.Crosstable], userTv: Option[User] = None)(implicit ctx: Context)
|
||||
|
||||
@title = @{ s"${playerText(pov.player)} vs ${playerText(pov.opponent)} in ${pov.gameId}" }
|
||||
|
||||
|
@ -17,7 +17,7 @@ i18n: @jsI18n()
|
|||
|
||||
@round.layout(
|
||||
title = title,
|
||||
side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour, simul = simul, userTv = userTv),
|
||||
side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour, simul = simul, relay = relay, userTv = userTv),
|
||||
chat = base.chatDom(trans.spectatorRoom.str()).some,
|
||||
underchat = views.html.game.watchers().some,
|
||||
moreJs = moreJs,
|
||||
|
|
|
@ -61,6 +61,7 @@ object BSONHandlers {
|
|||
metadata = Metadata(
|
||||
source = r intO source flatMap Source.apply,
|
||||
pgnImport = r.getO[PgnImport](pgnImport)(PgnImport.pgnImportBSONHandler),
|
||||
relay = r.getO[Relay](relay)(Relay.relayBSONHandler),
|
||||
tournamentId = r strO tournamentId,
|
||||
simulId = r strO simulId,
|
||||
tvAt = r dateO tvAt,
|
||||
|
@ -93,6 +94,7 @@ object BSONHandlers {
|
|||
updatedAt -> o.updatedAt.map(w.date),
|
||||
source -> o.metadata.source.map(_.id),
|
||||
pgnImport -> o.metadata.pgnImport,
|
||||
relay -> o.metadata.relay,
|
||||
tournamentId -> o.metadata.tournamentId,
|
||||
simulId -> o.metadata.simulId,
|
||||
tvAt -> o.metadata.tvAt.map(w.date),
|
||||
|
|
|
@ -431,6 +431,10 @@ case class Game(
|
|||
def pgnImport = metadata.pgnImport
|
||||
def isPgnImport = pgnImport.isDefined
|
||||
|
||||
def relay = metadata.relay
|
||||
def relayId = relay.map(_.id)
|
||||
def isRelay = relay.isDefined
|
||||
|
||||
def resetTurns = copy(turns = 0, startedAtTurn = 0)
|
||||
|
||||
lazy val opening: Option[chess.OpeningExplorer.Opening] =
|
||||
|
@ -486,6 +490,7 @@ object Game {
|
|||
variant: Variant,
|
||||
source: Source,
|
||||
pgnImport: Option[PgnImport],
|
||||
relay: Option[Relay] = None,
|
||||
castles: Castles = Castles.init,
|
||||
daysPerTurn: Option[Int] = None): Game = Game(
|
||||
id = IdGenerator.game,
|
||||
|
@ -505,6 +510,7 @@ object Game {
|
|||
metadata = Metadata(
|
||||
source = source.some,
|
||||
pgnImport = pgnImport,
|
||||
relay = relay,
|
||||
tournamentId = none,
|
||||
simulId = none,
|
||||
tvAt = none,
|
||||
|
@ -541,6 +547,7 @@ object Game {
|
|||
val updatedAt = "ua"
|
||||
val source = "so"
|
||||
val pgnImport = "pgni"
|
||||
val relay = "rel"
|
||||
val tournamentId = "tid"
|
||||
val simulId = "sid"
|
||||
val tvAt = "tv"
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.joda.time.DateTime
|
|||
private[game] case class Metadata(
|
||||
source: Option[Source],
|
||||
pgnImport: Option[PgnImport],
|
||||
relay: Option[Relay],
|
||||
tournamentId: Option[String],
|
||||
simulId: Option[String],
|
||||
tvAt: Option[DateTime],
|
||||
|
@ -21,7 +22,19 @@ private[game] case class Metadata(
|
|||
|
||||
private[game] object Metadata {
|
||||
|
||||
val empty = Metadata(None, None, None, None, None, false)
|
||||
val empty = Metadata(None, None, None, None, None, None, false)
|
||||
}
|
||||
|
||||
case class Relay(id: String, white: Relay.Player, black: Relay.Player)
|
||||
|
||||
object Relay {
|
||||
|
||||
case class Player(name: String, title: Option[String], rating: Option[Int])
|
||||
|
||||
import reactivemongo.bson.Macros
|
||||
import ByteArray.ByteArrayBSONHandler
|
||||
implicit val relayPlayerBSONHandler = Macros.handler[Relay.Player]
|
||||
implicit val relayBSONHandler = Macros.handler[Relay]
|
||||
}
|
||||
|
||||
case class PgnImport(
|
||||
|
|
|
@ -9,6 +9,7 @@ import lila.hub.SequentialActor
|
|||
private[relay] final class GameActor(
|
||||
fics: ActorRef,
|
||||
ficsId: Int,
|
||||
relayId: String,
|
||||
getRelayGame: () => Fu[Option[Relay.Game]],
|
||||
importer: Importer) extends SequentialActor {
|
||||
|
||||
|
@ -61,7 +62,7 @@ private[relay] final class GameActor(
|
|||
}
|
||||
|
||||
def recover(data: command.Moves.Game) = withRelayGame { g =>
|
||||
importer.full(g.id, data)
|
||||
importer.full(relayId, g.id, data)
|
||||
}
|
||||
|
||||
def withRelayGame[A](f: Relay.Game => Fu[A]): Funit = getRelayGame() flatMap {
|
||||
|
|
|
@ -17,7 +17,7 @@ final class Importer(
|
|||
delay: FiniteDuration,
|
||||
scheduler: akka.actor.Scheduler) {
|
||||
|
||||
def full(gameId: String, data: command.Moves.Game): Fu[Game] =
|
||||
def full(relayId: String, gameId: String, data: command.Moves.Game): Fu[Game] =
|
||||
chess.format.pgn.Reader.full(data.pgn).future flatMap { replay =>
|
||||
GameRepo game gameId flatMap {
|
||||
case Some(game) => fuccess(game)
|
||||
|
@ -29,7 +29,12 @@ final class Importer(
|
|||
mode = chess.Mode.Casual,
|
||||
variant = replay.setup.board.variant,
|
||||
source = Source.Relay,
|
||||
pgnImport = none).withId(gameId).start
|
||||
pgnImport = none,
|
||||
relay = lila.game.Relay(
|
||||
id = relayId,
|
||||
white = toGamePlayer(data.white),
|
||||
black = toGamePlayer(data.black)).some
|
||||
).withId(gameId).start
|
||||
(GameRepo insertDenormalized game) inject game
|
||||
} flatMap { game =>
|
||||
|
||||
|
@ -90,4 +95,9 @@ final class Importer(
|
|||
onFailure = println
|
||||
))
|
||||
}
|
||||
|
||||
private def toGamePlayer(p: command.Moves.Player) = lila.game.Relay.Player(
|
||||
name = p.name,
|
||||
title = p.title,
|
||||
rating = p.rating)
|
||||
}
|
||||
|
|
|
@ -12,14 +12,22 @@ final class JsonView {
|
|||
"id" -> relay.id,
|
||||
"name" -> relay.name,
|
||||
"status" -> relay.status.id,
|
||||
"games" -> games.map(gameJson)
|
||||
)
|
||||
"games" -> games.flatMap(gameJson))
|
||||
}
|
||||
|
||||
private def gameJson(g: Game) = Json.obj(
|
||||
"id" -> g.id,
|
||||
"status" -> g.status.id,
|
||||
"fen" -> (chess.format.Forsyth exportBoard g.toChess.board),
|
||||
"lastMove" -> ~g.castleLastMoveTime.lastMoveString,
|
||||
"orient" -> g.firstPlayer.color.name)
|
||||
private def playerJson(p: lila.game.Relay.Player) = Json.obj(
|
||||
"name" -> p.name,
|
||||
"title" -> p.title,
|
||||
"rating" -> p.rating)
|
||||
|
||||
private def gameJson(g: Game) = g.relay map { r =>
|
||||
Json.obj(
|
||||
"id" -> g.id,
|
||||
"white" -> playerJson(r.white),
|
||||
"black" -> playerJson(r.black),
|
||||
"status" -> g.status.id,
|
||||
"fen" -> (chess.format.Forsyth exportBoard g.toChess.board),
|
||||
"lastMove" -> ~g.castleLastMoveTime.lastMoveString,
|
||||
"orient" -> g.firstPlayer.color.name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ private[relay] final class TourneyActor(
|
|||
new GameActor(
|
||||
fics = fics,
|
||||
ficsId = ficsId,
|
||||
relayId = id,
|
||||
getRelayGame = () => repo.gameByFicsId(id, ficsId),
|
||||
importer = importer)
|
||||
}
|
||||
|
|
|
@ -593,6 +593,7 @@ lichess.storage = {
|
|||
else if (lichess.lobby) startLobby(document.getElementById('hooks_wrap'), lichess.lobby);
|
||||
else if (lichess.tournament) startTournament(document.getElementById('tournament'), lichess.tournament);
|
||||
else if (lichess.simul) startSimul(document.getElementById('simul'), lichess.simul);
|
||||
else if (lichess.relay) startRelay(document.getElementById('relay'), lichess.relay);
|
||||
|
||||
document.body.classList.remove('preload');
|
||||
|
||||
|
@ -2027,6 +2028,30 @@ lichess.storage = {
|
|||
simul = LichessSimul(element, cfg);
|
||||
};
|
||||
|
||||
function startRelay(element, cfg) {
|
||||
var $watchers = $("div.watchers").watchers();
|
||||
if (typeof lichess_chat !== 'undefined') $('#chat').chat({
|
||||
messages: lichess_chat
|
||||
});
|
||||
var relay;
|
||||
lichess.socket = new lichess.StrongSocket(
|
||||
'/watch/' + cfg.data.id + '/socket/v1', cfg.socketVersion, {
|
||||
receive: function(t, d) {
|
||||
relay.socketReceive(t, d)
|
||||
},
|
||||
events: {
|
||||
crowd: function(data) {
|
||||
$watchers.watchers("set", data);
|
||||
}
|
||||
},
|
||||
options: {
|
||||
name: "relay"
|
||||
}
|
||||
});
|
||||
cfg.socketSend = lichess.socket.send.bind(lichess.socket);
|
||||
relay = LichessRelay(element, cfg);
|
||||
};
|
||||
|
||||
////////////////
|
||||
// analyse.js //
|
||||
////////////////
|
||||
|
|
|
@ -2,6 +2,15 @@ var m = require('mithril');
|
|||
|
||||
var boardContent = m('div.cg-board-wrap', m('div.cg-board'));
|
||||
|
||||
function player(p) {
|
||||
return [
|
||||
p.name,
|
||||
m('br'),
|
||||
p.title ? p.title + ' ' : '',
|
||||
p.rating
|
||||
]
|
||||
}
|
||||
|
||||
function miniGame(game) {
|
||||
return m('div', [
|
||||
m('a', {
|
||||
|
@ -16,18 +25,8 @@ function miniGame(game) {
|
|||
}
|
||||
}, boardContent),
|
||||
m('div.vstext.clearfix', [
|
||||
m('div.left', [
|
||||
game.user1.name,
|
||||
m('br'),
|
||||
game.user1.title ? game.user1.title + ' ' : '',
|
||||
game.user1.rating
|
||||
]),
|
||||
m('div.right', [
|
||||
game.user2.name,
|
||||
m('br'),
|
||||
game.user2.rating,
|
||||
game.user2.title ? ' ' + game.user2.title : ''
|
||||
])
|
||||
m('div.left', player(game.white)),
|
||||
m('div.right', player(game.black))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue