add game powertips to crosstables and tournament pairings - closes #822
parent
1db8d45a5b
commit
35fb4ab9dc
|
@ -4,7 +4,7 @@ package actor
|
|||
import akka.actor._
|
||||
import play.twirl.api.Html
|
||||
|
||||
import lila.game.GameRepo
|
||||
import lila.game.{ GameRepo, Pov }
|
||||
import lila.user.UserRepo
|
||||
import views.{ html => V }
|
||||
|
||||
|
@ -13,7 +13,7 @@ private[app] final class Renderer extends Actor {
|
|||
def receive = {
|
||||
|
||||
case lila.tv.actorApi.RenderFeaturedJs(game) =>
|
||||
sender ! V.game.featuredJs(game)
|
||||
sender ! V.game.featuredJs(Pov first game)
|
||||
|
||||
case lila.notification.actorApi.RenderNotification(id, from, body) =>
|
||||
sender ! V.notification.view(id, from)(Html(body))
|
||||
|
|
|
@ -241,4 +241,10 @@ object Round extends LilaController with TheftPrevention {
|
|||
Redirect(routes.Lobby.home)
|
||||
}
|
||||
}
|
||||
|
||||
def mini(gameId: String, color: String) = Open { implicit ctx =>
|
||||
OptionOk(GameRepo.pov(gameId, color)) { pov =>
|
||||
html.game.mini(pov)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ object Tournament extends LilaController {
|
|||
|
||||
def userGameNbMini(id: String, user: String, nb: Int) = Open { implicit ctx =>
|
||||
withUserGameNb(id, user, nb) { pov =>
|
||||
Ok(html.game.mini(pov))
|
||||
Ok(html.tournament.miniGame(pov))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ object Tv extends LilaController {
|
|||
Env.tv.tv.getBest map {
|
||||
case None => NotFound
|
||||
case Some(game) => Ok(views.html.tv.embed(
|
||||
game,
|
||||
Pov first game,
|
||||
get("bg", req) | "light",
|
||||
lila.pref.Theme(~get("theme", req)).cssClass
|
||||
))
|
||||
|
|
|
@ -203,37 +203,37 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel
|
|||
}
|
||||
|
||||
def gameFen(
|
||||
game: Game,
|
||||
color: Color,
|
||||
pov: Pov,
|
||||
ownerLink: Boolean = false,
|
||||
tv: Boolean = false,
|
||||
withTitle: Boolean = true,
|
||||
withLink: Boolean = true,
|
||||
withLive: Boolean = true)(implicit ctx: UserContext) = Html {
|
||||
val game = pov.game
|
||||
var isLive = withLive && game.isBeingPlayed
|
||||
val href = withLink ?? s"""href="${gameLink(game, color, ownerLink, tv)}""""
|
||||
val title = withTitle ?? s"""title="${gameTitle(game, color)}""""
|
||||
val href = withLink ?? s"""href="${gameLink(game, pov.color, ownerLink, tv)}""""
|
||||
val title = withTitle ?? s"""title="${gameTitle(game, pov.color)}""""
|
||||
val cssClass = isLive ?? ("live live_" + game.id)
|
||||
val live = isLive ?? game.id
|
||||
val fen = Forsyth exportBoard game.toChess.board
|
||||
val lastMove = ~game.castleLastMoveTime.lastMoveString
|
||||
val variant = game.variant.key
|
||||
val tag = if (withLink) "a" else "span"
|
||||
s"""<$tag $href $title class="mini_board mini_board_${game.id} parse_fen is2d $cssClass $variant" data-live="$live" data-color="${color.name}" data-fen="$fen" data-lastmove="$lastMove">$miniBoardContent</$tag>"""
|
||||
s"""<$tag $href $title class="mini_board mini_board_${game.id} parse_fen is2d $cssClass $variant" data-live="$live" data-color="${pov.color.name}" data-fen="$fen" data-lastmove="$lastMove">$miniBoardContent</$tag>"""
|
||||
}
|
||||
|
||||
def gameFenNoCtx(game: Game, color: Color, tv: Boolean = false, blank: Boolean = false) = Html {
|
||||
var isLive = game.isBeingPlayed
|
||||
val variant = game.variant.key
|
||||
s"""<a href="%s%s" title="%s" class="mini_board mini_board_${game.id} parse_fen is2d %s $variant" data-live="%s" data-color="%s" data-fen="%s" data-lastmove="%s"%s>$miniBoardContent</a>""".format(
|
||||
def gameFenNoCtx(pov: Pov, tv: Boolean = false, blank: Boolean = false) = Html {
|
||||
var isLive = pov.game.isBeingPlayed
|
||||
val variant = pov.game.variant.key
|
||||
s"""<a href="%s%s" title="%s" class="mini_board mini_board_${pov.game.id} parse_fen is2d %s $variant" data-live="%s" data-color="%s" data-fen="%s" data-lastmove="%s"%s>$miniBoardContent</a>""".format(
|
||||
blank ?? netBaseUrl,
|
||||
tv.fold(routes.Tv.index, routes.Round.watcher(game.id, color.name)),
|
||||
gameTitle(game, color),
|
||||
isLive ?? ("live live_" + game.id),
|
||||
isLive ?? game.id,
|
||||
color.name,
|
||||
Forsyth exportBoard game.toChess.board,
|
||||
~game.castleLastMoveTime.lastMoveString,
|
||||
tv.fold(routes.Tv.index, routes.Round.watcher(pov.game.id, pov.color.name)),
|
||||
gameTitle(pov.game, pov.color),
|
||||
isLive ?? ("live live_" + pov.game.id),
|
||||
isLive ?? pov.game.id,
|
||||
pov.color.name,
|
||||
Forsyth exportBoard pov.game.toChess.board,
|
||||
~pov.game.castleLastMoveTime.lastMoveString,
|
||||
blank ?? """ target="_blank"""")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
@crosstable.results.zipWithIndex.map {
|
||||
case (r, index) => {
|
||||
<td @if(currentId.??(r.gameId==)){class="current"}>
|
||||
<a href="@routes.Round.watcher(r.gameId, "white")" class="@r.winnerId match {
|
||||
<a
|
||||
href="@routes.Round.watcher(r.gameId, "white")"
|
||||
class="glpt @r.winnerId match {
|
||||
case Some(w) if w == u.id => { win }
|
||||
case None => {}
|
||||
case _ => { loss }
|
||||
|
@ -38,4 +40,3 @@
|
|||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@(g: lila.game.Game)
|
||||
@gameFenNoCtx(g, g.firstPlayer.color, tv = true)
|
||||
@game.vstext(g)(none)
|
||||
@(pov: Pov)
|
||||
@gameFenNoCtx(pov, tv = true)
|
||||
@game.vstext(pov)(none)
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
@(pov: Pov)(implicit ctx: Context)
|
||||
|
||||
@gameFen(pov.game, pov.color)
|
||||
<div class="vstext">
|
||||
@playerUsername(pov.opponent, withRating = true, withTitle = true)<br />
|
||||
<span class="result @{(~pov.win).fold("win", (~pov.loss).??("loss"))}">
|
||||
@gameEndStatus(pov.game)
|
||||
</span>
|
||||
</div>
|
||||
@gameFen(pov)
|
||||
@vstext(pov)(ctx.some)
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
@(g: Game)(ctxOption: Option[Context])
|
||||
@(pov: Pov)(ctxOption: Option[Context])
|
||||
<div class="vstext clearfix">
|
||||
<div class="left">
|
||||
@playerUsername(g.firstPlayer, withRating = false, withTitle = false)
|
||||
@playerUsername(pov.player, withRating = false, withTitle = false)
|
||||
<br />
|
||||
@lightUser(g.firstPlayer.userId).flatMap(_.title).map(_ + " ")
|
||||
@g.firstPlayer.rating@if(g.firstPlayer.provisional){?}
|
||||
@lightUser(pov.player.userId).flatMap(_.title).map(_ + " ")
|
||||
@pov.player.rating@if(pov.player.provisional){?}
|
||||
</div>
|
||||
<div class="right">
|
||||
@playerUsername(g.secondPlayer, withRating = false, withTitle = false)
|
||||
@playerUsername(pov.opponent, withRating = false, withTitle = false)
|
||||
<br />
|
||||
@g.secondPlayer.rating@if(g.secondPlayer.provisional){?}
|
||||
@lightUser(g.secondPlayer.userId).flatMap(_.title).map(" " + _)
|
||||
@pov.opponent.rating@if(pov.opponent.provisional){?}
|
||||
@lightUser(pov.opponent.userId).flatMap(_.title).map(" " + _)
|
||||
</div>
|
||||
@g.clock.map { c =>
|
||||
@pov.game.clock.map { c =>
|
||||
<div class="center"><span data-icon="p"> @shortClockName(c)</span></div>
|
||||
}.getOrElse {
|
||||
@ctxOption.map { ctx =>
|
||||
@g.daysPerTurn.map { days =>
|
||||
@pov.game.daysPerTurn.map { days =>
|
||||
<div class="center">
|
||||
<span data-hint="@trans.correspondence()(ctx)" class="hint--top">@{(days == 1).fold(trans.oneDay()(ctx), trans.nbDays(days)(ctx))}</span>
|
||||
</div>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<div class="game_row paginated_element">
|
||||
@defining(user flatMap g.player) { fromPlayer =>
|
||||
@defining(fromPlayer | g.firstPlayer ) { firstPlayer =>
|
||||
@gameFen(g, firstPlayer.color, ownerLink, withTitle = false)
|
||||
@gameFen(Pov.first(g), ownerLink, withTitle = false)
|
||||
<a class="game_link_overlay" href="@gameLink(g, firstPlayer.color, ownerLink)"></a>
|
||||
<div class="infos" data-icon="@gameIcon(g)">
|
||||
@bookmark.toggle(g)
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
@underchat = {
|
||||
<div id="featured_game">
|
||||
@featured.map { g =>
|
||||
@gameFen(g, g.firstPlayer.color, tv = true)
|
||||
@game.vstext(g)(ctx.some)
|
||||
@gameFen(Pov.first(g), tv = true)
|
||||
@game.vstext(Pov.first(g))(ctx.some)
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
@povs.take(9).map { pov =>
|
||||
<a href="@routes.Round.player(pov.fullId)" class="@if(pov.isMyTurn){my_turn}">
|
||||
@gameFen(pov.game, pov.color, withLink = false, withTitle = false, withLive = false)
|
||||
@gameFen(pov, withLink = false, withTitle = false, withLive = false)
|
||||
<span class="meta">
|
||||
@playerText(pov.opponent, withRating = false)
|
||||
<span class="indicator">
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
case (pov, rel) => {
|
||||
<div>
|
||||
<a href="@routes.Round.watcher(pov.gameId, pov.color.name)">
|
||||
@gameFen(pov.game, pov.color, withLink = false, withTitle = false, withLive = false)
|
||||
@gameFen(pov, withLink = false, withTitle = false, withLive = false)
|
||||
</a>
|
||||
<div class="vstext clearfix">
|
||||
<div class="left">
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
@(pov: Pov)(implicit ctx: Context)
|
||||
|
||||
@gameFen(pov)
|
||||
<div class="vstext">
|
||||
@playerUsername(pov.opponent, withRating = true, withTitle = true)<br />
|
||||
<span class="result @{(~pov.win).fold("win", (~pov.loss).??("loss"))}">
|
||||
@gameEndStatus(pov.game)
|
||||
</span>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
@(g: Game, bg: String, theme: String)
|
||||
@(pov: Pov, bg: String, theme: String)
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
@ -17,8 +17,8 @@
|
|||
style="width: 224px; height: 264px; overflow: hidden;"
|
||||
data-stream-url="@routes.Tv.streamOut">
|
||||
<div id="featured_game" class="is2d highlight @bg @theme merida" title="lichess.org TV">
|
||||
@gameFenNoCtx(g, g.firstPlayer.color, tv = true, blank = true)
|
||||
@game.vstext(g)(none)
|
||||
@gameFenNoCtx(pov, tv = true, blank = true)
|
||||
@game.vstext(pov)(none)
|
||||
</div>
|
||||
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
|
||||
@jsTag("vendor/chessground.min.js")
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
@if(filterName == "playing" && gs.nbResults > 2) {
|
||||
@gs.currentPageResults.flatMap{ Pov(_, u) }.map { p =>
|
||||
<div class="paginated_element">
|
||||
@gameFen(p.game, p.color)
|
||||
@game.vstext(p.game)(ctx.some)
|
||||
@gameFen(p)
|
||||
@game.vstext(p)(ctx.some)
|
||||
</div>
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
@if(!ctx.pref.isBlindfold) {
|
||||
@playing.map { pov =>
|
||||
@gameFen(pov.game, pov.color)
|
||||
@gameFen(pov)
|
||||
<div class="game_legend">
|
||||
@playerText(pov.opponent, withRating = true)
|
||||
@pov.game.clock.map { c =>
|
||||
|
|
|
@ -118,6 +118,8 @@ GET /$gameId<\w{8}>/$color<white|black>/sides/player controllers.Round.sidesPl
|
|||
GET /$gameId<\w{8}>/others controllers.Round.others(gameId: String)
|
||||
GET /$gameId<\w{8}>/continue/:mode controllers.Round.continue(gameId: String, mode: String)
|
||||
POST /$gameId<\w{8}>/note controllers.Round.writeNote(gameId: String)
|
||||
GET /$gameId<\w{8}>/mini controllers.Round.mini(gameId: String, color: String = "white")
|
||||
GET /$gameId<\w{8}>/$color<white|black>/mini controllers.Round.mini(gameId: String, color: String)
|
||||
GET /$gameId<\w{8}>/edit controllers.Editor.game(gameId: String)
|
||||
GET /$gameId<\w{8}>/$color<white|black>/analysis controllers.UserAnalysis.game(gameId: String, color: String)
|
||||
POST /$fullId<\w{12}>/resign controllers.Round.resign(fullId: String)
|
||||
|
|
|
@ -637,7 +637,7 @@ lichess.desktopNotification = function(msg) {
|
|||
return false;
|
||||
});
|
||||
|
||||
function applyPowertip($els, placement) {
|
||||
function userPowertip($els, placement) {
|
||||
$els.removeClass('ulpt').powerTip({
|
||||
fadeInTime: 100,
|
||||
fadeOutTime: 100,
|
||||
|
@ -657,13 +657,35 @@ lichess.desktopNotification = function(msg) {
|
|||
}).data('powertip', ' ');
|
||||
}
|
||||
|
||||
function userPowertips() {
|
||||
applyPowertip($('#site_header .ulpt'), 'e');
|
||||
applyPowertip($('#friend_box .ulpt'), 'nw');
|
||||
applyPowertip($('.ulpt'), 'w');
|
||||
function gamePowertip($els, placement) {
|
||||
$els.removeClass('glpt').powerTip({
|
||||
fadeInTime: 100,
|
||||
fadeOutTime: 100,
|
||||
placement: placement,
|
||||
mouseOnToPopup: true,
|
||||
closeDelay: 200,
|
||||
popupId: 'miniGame'
|
||||
}).on({
|
||||
powerTipPreRender: function() {
|
||||
$.ajax({
|
||||
url: ($(this).attr('href') || $(this).data('href')).replace(/\?.+$/, '') + '/mini',
|
||||
success: function(html) {
|
||||
$('#miniGame').html(html);
|
||||
$('body').trigger('lichess.content_loaded');
|
||||
}
|
||||
});
|
||||
}
|
||||
}).data('powertip', ' ');
|
||||
}
|
||||
setTimeout(userPowertips, 600);
|
||||
$('body').on('lichess.content_loaded', userPowertips);
|
||||
|
||||
function updatePowertips() {
|
||||
userPowertip($('#site_header .ulpt'), 'e');
|
||||
userPowertip($('#friend_box .ulpt'), 'nw');
|
||||
userPowertip($('.ulpt'), 'w');
|
||||
gamePowertip($('.glpt'), 'w');
|
||||
}
|
||||
setTimeout(updatePowertips, 600);
|
||||
$('body').on('lichess.content_loaded', updatePowertips);
|
||||
|
||||
$('#message_notifications_tag').on('click', function() {
|
||||
$.ajax({
|
||||
|
|
|
@ -22,7 +22,8 @@ module.exports = function(ctrl) {
|
|||
tag: 'a',
|
||||
attrs: {
|
||||
key: p.id,
|
||||
href: '/' + p.id
|
||||
href: '/' + p.id,
|
||||
class: 'glpt'
|
||||
},
|
||||
children: [
|
||||
user(p, 0),
|
||||
|
|
Loading…
Reference in New Issue