more on mithril play
parent
51b740de51
commit
cf0fbf5b00
|
@ -58,14 +58,14 @@ object Round extends LilaController with TheftPrevention {
|
|||
(pov.game.tournamentId ?? TournamentRepo.byId) zip
|
||||
Env.game.crosstableApi(pov.game) flatMap {
|
||||
case (tour, crosstable) =>
|
||||
env.jsonView.playerJson(pov, ctx.pref, Env.api.version, ctx.me) map { data =>
|
||||
Env.api.roundApi.player(pov, Env.api.version) map { data =>
|
||||
Ok(html.round.player(pov, data, tour = tour, cross = crosstable))
|
||||
}
|
||||
}
|
||||
},
|
||||
Redirect(routes.Setup.await(fullId)).fuccess
|
||||
),
|
||||
api = apiVersion => env.jsonView.playerJson(pov, ctx.pref, apiVersion, ctx.me) map { Ok(_) }
|
||||
api = apiVersion => Env.api.roundApi.player(pov, apiVersion) map { Ok(_) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
@jsAt(s"compiled/lichess.round.js")
|
||||
@helper.javascriptRouter("roundRoutes")(
|
||||
routes.javascript.Auth.signup,
|
||||
routes.javascript.User.show
|
||||
routes.javascript.User.show,
|
||||
routes.javascript.Tournament.show,
|
||||
routes.javascript.Pool.show,
|
||||
routes.javascript.Pool.leave
|
||||
)(ctx.req)
|
||||
@embedJs {
|
||||
lichess = lichess || {};
|
||||
|
@ -53,7 +56,15 @@ trans.timeOut,
|
|||
trans.premoveEnabledClickAnywhereToCancel,
|
||||
trans.playingRightNow,
|
||||
trans.whiteIsVictorious,
|
||||
trans.blackIsVictorious
|
||||
trans.blackIsVictorious,
|
||||
trans.backToTournament,
|
||||
trans.joinTheGame,
|
||||
trans.playWithTheSameOpponentAgain,
|
||||
trans.declineInvitation,
|
||||
trans.rematch,
|
||||
trans.rematchOfferSent,
|
||||
trans.waitingForOpponent,
|
||||
trans.cancelRematchOffer
|
||||
)))
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ final class Env(
|
|||
renderer: akka.actor.ActorSelection,
|
||||
router: akka.actor.ActorSelection,
|
||||
bus: lila.common.Bus,
|
||||
roundJsonView: lila.round.JsonView,
|
||||
pgnDump: lila.game.PgnDump,
|
||||
userEnv: lila.user.Env,
|
||||
analyseEnv: lila.analyse.Env,
|
||||
|
@ -56,6 +57,9 @@ final class Env(
|
|||
apiToken = apiToken,
|
||||
pgnDump = pgnDump)
|
||||
|
||||
val roundApi = new RoundApi(
|
||||
jsonView = roundJsonView)
|
||||
|
||||
val puzzleApi = new PuzzleApi(
|
||||
env = puzzleEnv,
|
||||
makeUrl = apiUrl)
|
||||
|
@ -78,6 +82,7 @@ object Env {
|
|||
userEnv = lila.user.Env.current,
|
||||
analyseEnv = lila.analyse.Env.current,
|
||||
puzzleEnv = lila.puzzle.Env.current,
|
||||
roundJsonView = lila.round.Env.current.jsonView,
|
||||
pgnDump = lila.game.Env.current.pgnDump,
|
||||
userIdsSharingIp = lila.security.Env.current.api.userIdsSharingIp,
|
||||
bus = lila.common.PlayApp.system.lilaBus,
|
||||
|
|
|
@ -106,7 +106,7 @@ private[api] final class GameApi(
|
|||
"perf" -> PerfPicker.key(g),
|
||||
"timestamp" -> g.createdAt.getDate,
|
||||
"turns" -> g.turns,
|
||||
"status" -> g.status.name.toLowerCase,
|
||||
"status" -> g.status.name,
|
||||
"clock" -> g.clock.map { clock =>
|
||||
Json.obj(
|
||||
"initial" -> clock.limit,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package lila.api
|
||||
|
||||
import play.api.libs.json._
|
||||
|
||||
import lila.game.Pov
|
||||
import lila.pref.Pref
|
||||
import lila.round.JsonView
|
||||
import lila.tournament.TournamentRepo
|
||||
import lila.user.User
|
||||
|
||||
private[api] final class RoundApi(jsonView: JsonView) {
|
||||
|
||||
def player(pov: Pov, apiVersion: Int)(implicit ctx: Context): Fu[JsObject] =
|
||||
jsonView.playerJson(pov, ctx.pref, apiVersion, ctx.me) zip
|
||||
(pov.game.tournamentId ?? TournamentRepo.byId) map {
|
||||
case (json, tourOption) => tourOption.fold(json) { tour =>
|
||||
json + (
|
||||
"tournament" -> Json.obj(
|
||||
"id" -> tour.id,
|
||||
"name" -> tour.name,
|
||||
"running" -> tour.isRunning
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 8a5223f54661801520d5a28c78f6354163b67a65
|
||||
Subproject commit 4ef85368489ffac650233d32057882195d4ac7a8
|
|
@ -117,6 +117,6 @@ object Query {
|
|||
|
||||
val statuses =
|
||||
Status.finishedNotCheated filterNot (_.is(_.Timeout)) map { s =>
|
||||
s.id -> s.is(_.Outoftime).fold("Clock Flag", s.name)
|
||||
s.id -> s.is(_.Outoftime).fold("Clock Flag", s.toString)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ final class JsonView(
|
|||
pov: Pov,
|
||||
pref: Pref,
|
||||
apiVersion: Int,
|
||||
tourOption: Option[lila.tournament.Tournament],
|
||||
playerUser: Option[User]): Fu[JsObject] =
|
||||
getVersion(pov.game.id) zip
|
||||
(pov.opponent.userId ?? UserRepo.byId) zip
|
||||
|
@ -54,7 +53,7 @@ final class JsonView(
|
|||
"lastMove" -> game.castleLastMoveTime.lastMoveString,
|
||||
"status" -> Json.obj(
|
||||
"id" -> pov.game.status.id,
|
||||
"name" -> pov.game.status.lowerName)),
|
||||
"name" -> pov.game.status.name)),
|
||||
"clock" -> game.clock.map(clockJson),
|
||||
"player" -> Json.obj(
|
||||
"id" -> playerId,
|
||||
|
@ -98,13 +97,12 @@ final class JsonView(
|
|||
"t" -> text)
|
||||
})
|
||||
},
|
||||
"tournament" -> tourOption.map { tour =>
|
||||
Json.obj(
|
||||
"id" ->game.tournamentId
|
||||
)
|
||||
},
|
||||
"possibleMoves" -> possibleMoves(pov),
|
||||
"poolId" -> game.poolId,
|
||||
"pool" -> game.poolId.map { pid =>
|
||||
Json.obj(
|
||||
"id" -> pid
|
||||
)
|
||||
},
|
||||
"takebackable" -> takebackable)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package lila.tournament
|
||||
|
||||
case class LightTournament(
|
||||
id: String,
|
||||
name: String,
|
||||
status: Int) {
|
||||
|
||||
def running = status == Status.Started.id
|
||||
}
|
||||
|
||||
object LightTournament {
|
||||
|
||||
import reactivemongo.bson._
|
||||
private[tournament] implicit val lightTournamentBSONHandler = Macros.handler[LightTournament]
|
||||
}
|
|
@ -10,6 +10,8 @@ import tube.tournamentTube
|
|||
|
||||
object TournamentRepo {
|
||||
|
||||
import LightTournament.lightTournamentBSONHandler
|
||||
|
||||
private def asCreated(tour: Tournament): Option[Created] = tour.some collect {
|
||||
case t: Created => t
|
||||
}
|
||||
|
@ -26,6 +28,9 @@ object TournamentRepo {
|
|||
|
||||
def byId(id: String): Fu[Option[Tournament]] = $find byId id
|
||||
|
||||
def lightById(id: String): Fu[Option[LightTournament]] =
|
||||
tournamentTube.coll.find(BSONDocument("_id" -> id)).one[LightTournament]
|
||||
|
||||
def nameById(id: String): Fu[Option[String]] =
|
||||
$primitive.one($select(id), "name")(_.asOpt[String])
|
||||
|
||||
|
|
|
@ -1,129 +1,8 @@
|
|||
var map = require('lodash-node/modern/collections/map');
|
||||
var chessground = require('chessground');
|
||||
var round = require('../round');
|
||||
var status = require('../status');
|
||||
var opposite = chessground.util.opposite;
|
||||
var classSet = chessground.util.classSet;
|
||||
var partial = chessground.util.partial;
|
||||
var renderClock = require('../clock/view');
|
||||
var renderStatus = require('./status');
|
||||
var m = require('mithril');
|
||||
|
||||
function renderOpponent(ctrl) {
|
||||
var op = ctrl.data.opponent;
|
||||
return op.ai ? m('div.username.connected.statused',
|
||||
ctrl.trans('aiNameLevelAiLevel', 'Stockfish', op.ai)
|
||||
) : m('div', {
|
||||
class: 'username ' + op.color + ' ' + classSet({
|
||||
'statused': op.statused,
|
||||
'connected': op.connected,
|
||||
'offline': !op.connected
|
||||
})
|
||||
},
|
||||
op.user ? [
|
||||
m('a', {
|
||||
class: 'user_link ulpt',
|
||||
href: ctrl.router.User.show(op.user.username).url,
|
||||
target: round.playable(ctrl.data) ? '_blank' : null,
|
||||
'data-icon': 'r',
|
||||
}, [
|
||||
(op.user.title ? op.user.title + ' ' : '') + op.user.username,
|
||||
op.engine ? m('span[data-icon=j]', {
|
||||
title: ctrl.trans('thisPlayerUsesChessComputerAssistance')
|
||||
}) : null
|
||||
]),
|
||||
m('span.status')
|
||||
] : m('span.user_link', [
|
||||
'Anonymous',
|
||||
m('span.status')
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function renderResult(ctrl) {
|
||||
var winner = round.getPlayer(ctrl.data, ctrl.data.game.winner);
|
||||
return winner ? m('div.lichess_player.' + winner.color, [
|
||||
m('div.cg-piece.king.' + winner.color),
|
||||
m('p', [
|
||||
renderStatus(ctrl),
|
||||
m('br'),
|
||||
ctrl.trans(winner.color == 'white' ? 'whiteIsVictorious' : 'blackIsVictorious')
|
||||
])
|
||||
]) :
|
||||
m('div.lichess_player', renderStatus(ctrl));
|
||||
}
|
||||
|
||||
function renderTableEnd(ctrl) {
|
||||
var d = ctrl.data;
|
||||
return [
|
||||
m('div.lichess_current_player', renderResult(ctrl))
|
||||
];
|
||||
}
|
||||
|
||||
function renderButton(ctrl, condition, icon, hint, socketMsg) {
|
||||
return condition(ctrl.data) ? m('button', {
|
||||
class: 'button hint--bottom',
|
||||
'data-hint': ctrl.trans(hint),
|
||||
onclick: partial(ctrl.socket.send, socketMsg, null)
|
||||
}, m('span[data-icon=' + icon + ']')) : null;
|
||||
}
|
||||
|
||||
function renderTablePlay(ctrl) {
|
||||
var d = ctrl.data;
|
||||
return [
|
||||
m('div.lichess_current_player',
|
||||
m('div.lichess_player', [
|
||||
m('div.cg-piece.king.' + d.game.player),
|
||||
m('p', ctrl.trans(d.game.player == d.player.color ? 'yourTurn' : 'waiting'))
|
||||
])
|
||||
),
|
||||
m('div.lichess_control.icons', [
|
||||
renderButton(ctrl, round.abortable, 'L', 'abortGame', 'abort'),
|
||||
renderButton(ctrl, round.takebackable, 'i', 'proposeATakeback', 'takeback-yes'),
|
||||
renderButton(ctrl, round.drawable, '2', 'offerDraw', 'draw-yes'),
|
||||
renderButton(ctrl, round.resignable, 'b', 'resign', 'resign')
|
||||
]),
|
||||
d.player.isOfferingDraw ? m('div.negociation', [
|
||||
ctrl.trans('drawOfferSent') + ' ',
|
||||
m('a', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-no', null)
|
||||
}, ctrl.trans('cancel'))
|
||||
]) : null,
|
||||
d.opponent.isOfferingDraw ? m('div.negociation', [
|
||||
ctrl.trans('yourOpponentOffersADraw'),
|
||||
m('br'),
|
||||
m('a.button[data-icon=E]', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-yes', null)
|
||||
}, ctrl.trans('accept')),
|
||||
m.trust(' '),
|
||||
m('a.button[data-icon=L]', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-no', null)
|
||||
}, ctrl.trans('decline')),
|
||||
]) : null,
|
||||
d.player.isProposingTakeback ? m('div.negociation', [
|
||||
ctrl.trans('takebackPropositionSent') + ' ',
|
||||
m('a', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-no', null)
|
||||
}, ctrl.trans('cancel'))
|
||||
]) : null,
|
||||
d.opponent.isProposingTakeback ? m('div.negociation', [
|
||||
ctrl.trans('yourOpponentProposesATakeback'),
|
||||
m('br'),
|
||||
m('a.button[data-icon=E]', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-yes', null)
|
||||
}, ctrl.trans('accept')),
|
||||
m.trust(' '),
|
||||
m('a.button[data-icon=L]', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-no', null)
|
||||
}, ctrl.trans('decline')),
|
||||
]) : null, (round.mandatory(d) && round.nbMoves(d, d.player.color) === 0) ? m('div[data-icon=j]',
|
||||
ctrl.trans('youHaveNbSecondsToMakeYourFirstMove')
|
||||
) : null
|
||||
];
|
||||
}
|
||||
var chessground = require('chessground');
|
||||
var renderTable = require('./table');
|
||||
|
||||
module.exports = function(ctrl) {
|
||||
var clockRunningColor = ctrl.isClockRunning() ? ctrl.data.game.player : null;
|
||||
return m('div', {
|
||||
config: function(el, isUpdate, context) {
|
||||
if (isUpdate) return;
|
||||
|
@ -136,22 +15,6 @@ module.exports = function(ctrl) {
|
|||
m('div.lichess_board.' + ctrl.data.game.variant.key, chessground.view(ctrl.chessground)),
|
||||
m('div#premove_alert', ctrl.trans('premoveEnabledClickAnywhereToCancel'))
|
||||
]),
|
||||
m('div.lichess_ground',
|
||||
m('div.lichess_table_wrap', [
|
||||
(ctrl.clock && !ctrl.data.blindMode) ? renderClock(ctrl.clock, opposite(ctrl.data.player.color), "top", clockRunningColor) : null,
|
||||
m('div', {
|
||||
class: 'lichess_table onbg ' + classSet({
|
||||
'table_with_clock': ctrl.clock,
|
||||
'finished': status.finished(ctrl.data)
|
||||
})
|
||||
}, [
|
||||
m('div.lichess_opponent', renderOpponent(ctrl)),
|
||||
m('div.lichess_separator'),
|
||||
m('div.table_inner',
|
||||
round.playable(ctrl.data) ? renderTablePlay(ctrl) : renderTableEnd(ctrl)
|
||||
)
|
||||
]), (ctrl.clock && !ctrl.data.blindMode) ? renderClock(ctrl.clock, ctrl.data.player.color, "bottom", clockRunningColor) : null,
|
||||
])
|
||||
)
|
||||
m('div.lichess_ground', renderTable(ctrl))
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
var m = require('mithril');
|
||||
var chessground = require('chessground');
|
||||
var round = require('../round');
|
||||
var status = require('../status');
|
||||
var opposite = chessground.util.opposite;
|
||||
var classSet = chessground.util.classSet;
|
||||
var partial = chessground.util.partial;
|
||||
var renderClock = require('../clock/view');
|
||||
var renderStatus = require('./status');
|
||||
|
||||
function renderOpponent(ctrl) {
|
||||
var op = ctrl.data.opponent;
|
||||
return op.ai ? m('div.username.connected.statused',
|
||||
ctrl.trans('aiNameLevelAiLevel', 'Stockfish', op.ai)
|
||||
) : m('div', {
|
||||
class: 'username ' + op.color + ' ' + classSet({
|
||||
'statused': op.statused,
|
||||
'connected': op.connected,
|
||||
'offline': !op.connected
|
||||
})
|
||||
},
|
||||
op.user ? [
|
||||
m('a', {
|
||||
class: 'user_link ulpt',
|
||||
href: ctrl.router.User.show(op.user.username).url,
|
||||
target: round.playable(ctrl.data) ? '_blank' : null,
|
||||
'data-icon': 'r',
|
||||
}, [
|
||||
(op.user.title ? op.user.title + ' ' : '') + op.user.username,
|
||||
op.engine ? m('span[data-icon=j]', {
|
||||
title: ctrl.trans('thisPlayerUsesChessComputerAssistance')
|
||||
}) : null
|
||||
]),
|
||||
m('span.status')
|
||||
] : m('span.user_link', [
|
||||
'Anonymous',
|
||||
m('span.status')
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function renderResult(ctrl) {
|
||||
var winner = round.getPlayer(ctrl.data, ctrl.data.game.winner);
|
||||
return winner ? m('div.lichess_player.' + winner.color, [
|
||||
m('div.cg-piece.king.' + winner.color),
|
||||
m('p', [
|
||||
renderStatus(ctrl),
|
||||
m('br'),
|
||||
ctrl.trans(winner.color == 'white' ? 'whiteIsVictorious' : 'blackIsVictorious')
|
||||
])
|
||||
]) :
|
||||
m('div.lichess_player', renderStatus(ctrl));
|
||||
}
|
||||
|
||||
function renderRematchButton(ctrl) {
|
||||
return m('a.lichess_rematch.offer.button.hint--bottom', {
|
||||
'data-hint': ctrl.trans('playWithTheSameOpponentAgain'),
|
||||
onclick: partial(ctrl.socket.send, 'rematch-yes', null)
|
||||
}, ctrl.trans('rematch'));
|
||||
}
|
||||
|
||||
function renderTableEnd(ctrl) {
|
||||
var d = ctrl.data;
|
||||
return [
|
||||
m('div.lichess_current_player', renderResult(ctrl)),
|
||||
m('div.lichess_control.buttons', [
|
||||
d.game.pool ? [
|
||||
m('a.button[data-icon=,]', {
|
||||
href: router.Pool.show(d.game.pool.id),
|
||||
}, 'Return to pool'),
|
||||
m('form[method=post]', {
|
||||
action: router.Pool.leave(d.game.pool.id)
|
||||
}, m('button.button[type=submit]', 'Leave the pool'))
|
||||
] : (d.game.tournament ? m('a[data-icon=G]', {
|
||||
class: classSet({
|
||||
button: true,
|
||||
strong: d.game.tournament.running
|
||||
}),
|
||||
href: ctrl.router.Tournament.show(d.game.tournament.id)
|
||||
}, ctrl.trans('backToTournament')) : (d.opponent.ai ? renderRematchButton(ctrl) : [
|
||||
m('div.lichess_separator'),
|
||||
d.opponent.isOfferingRematch ? m('div.lichess_play_again_join.rematch_alert', [
|
||||
ctrl.trans('yourOpponentWantsToPlayANewGameWithYou'),
|
||||
m('a.glowing.button.lichess_play_again.lichess_rematch.hint--bottom', {
|
||||
'data-hint': ctrl.trans('playWithTheSameOpponentAgain'),
|
||||
onclick: partial(ctrl.socket.send, 'rematch-yes', null),
|
||||
}, ctrl.trans('joinTheGame')),
|
||||
m('a', {
|
||||
onclick: partial(ctrl.socket.send, 'rematch-no', null),
|
||||
}, ctrl.trans('declineInvitation'))
|
||||
]) : (d.player.isOfferingRematch ? m('div.lichess_play_again_join.rematch_wait', [
|
||||
ctrl.trans('rematchOfferSent'),
|
||||
m('br'),
|
||||
ctrl.trans('waitingForOpponent'),
|
||||
m('br'), m('br'),
|
||||
m('a.lichess_rematch_cancel', {
|
||||
onclick: partial(ctrl.socket.send, 'rematch-no', null),
|
||||
}, ctrl.trans('cancelRematchOffer'))
|
||||
]) : renderRematchButton(ctrl))
|
||||
]))
|
||||
])
|
||||
];
|
||||
}
|
||||
|
||||
function renderButton(ctrl, condition, icon, hint, socketMsg) {
|
||||
return condition(ctrl.data) ? m('button', {
|
||||
class: 'button hint--bottom',
|
||||
'data-hint': ctrl.trans(hint),
|
||||
onclick: partial(ctrl.socket.send, socketMsg, null)
|
||||
}, m('span[data-icon=' + icon + ']')) : null;
|
||||
}
|
||||
|
||||
function renderTablePlay(ctrl) {
|
||||
var d = ctrl.data;
|
||||
return [
|
||||
m('div.lichess_current_player',
|
||||
m('div.lichess_player', [
|
||||
m('div.cg-piece.king.' + d.game.player),
|
||||
m('p', ctrl.trans(d.game.player == d.player.color ? 'yourTurn' : 'waiting'))
|
||||
])
|
||||
),
|
||||
m('div.lichess_control.icons', [
|
||||
renderButton(ctrl, round.abortable, 'L', 'abortGame', 'abort'),
|
||||
renderButton(ctrl, round.takebackable, 'i', 'proposeATakeback', 'takeback-yes'),
|
||||
renderButton(ctrl, round.drawable, '2', 'offerDraw', 'draw-yes'),
|
||||
renderButton(ctrl, round.resignable, 'b', 'resign', 'resign')
|
||||
]),
|
||||
d.player.isOfferingDraw ? m('div.negociation', [
|
||||
ctrl.trans('drawOfferSent') + ' ',
|
||||
m('a', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-no', null)
|
||||
}, ctrl.trans('cancel'))
|
||||
]) : null,
|
||||
d.opponent.isOfferingDraw ? m('div.negociation', [
|
||||
ctrl.trans('yourOpponentOffersADraw'),
|
||||
m('br'),
|
||||
m('a.button[data-icon=E]', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-yes', null)
|
||||
}, ctrl.trans('accept')),
|
||||
m.trust(' '),
|
||||
m('a.button[data-icon=L]', {
|
||||
onclick: partial(ctrl.socket.send, 'draw-no', null)
|
||||
}, ctrl.trans('decline')),
|
||||
]) : null,
|
||||
d.player.isProposingTakeback ? m('div.negociation', [
|
||||
ctrl.trans('takebackPropositionSent') + ' ',
|
||||
m('a', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-no', null)
|
||||
}, ctrl.trans('cancel'))
|
||||
]) : null,
|
||||
d.opponent.isProposingTakeback ? m('div.negociation', [
|
||||
ctrl.trans('yourOpponentProposesATakeback'),
|
||||
m('br'),
|
||||
m('a.button[data-icon=E]', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-yes', null)
|
||||
}, ctrl.trans('accept')),
|
||||
m.trust(' '),
|
||||
m('a.button[data-icon=L]', {
|
||||
onclick: partial(ctrl.socket.send, 'takeback-no', null)
|
||||
}, ctrl.trans('decline')),
|
||||
]) : null, (round.mandatory(d) && round.nbMoves(d, d.player.color) === 0) ? m('div[data-icon=j]',
|
||||
ctrl.trans('youHaveNbSecondsToMakeYourFirstMove')
|
||||
) : null
|
||||
];
|
||||
}
|
||||
|
||||
module.exports = function(ctrl) {
|
||||
var clockRunningColor = ctrl.isClockRunning() ? ctrl.data.game.player : null;
|
||||
return m('div.lichess_table_wrap', [
|
||||
(ctrl.clock && !ctrl.data.blindMode) ? renderClock(ctrl.clock, opposite(ctrl.data.player.color), "top", clockRunningColor) : null,
|
||||
m('div', {
|
||||
class: 'lichess_table onbg ' + classSet({
|
||||
'table_with_clock': ctrl.clock,
|
||||
'finished': status.finished(ctrl.data)
|
||||
})
|
||||
}, [
|
||||
m('div.lichess_opponent', renderOpponent(ctrl)),
|
||||
m('div.lichess_separator'),
|
||||
m('div.table_inner',
|
||||
round.playable(ctrl.data) ? renderTablePlay(ctrl) : renderTableEnd(ctrl)
|
||||
)
|
||||
]), (ctrl.clock && !ctrl.data.blindMode) ? renderClock(ctrl.clock, ctrl.data.player.color, "bottom", clockRunningColor) : null,
|
||||
])
|
||||
}
|
Loading…
Reference in New Issue