show current playing game on homepage - WIP

pull/83/head
Thibault Duplessis 2014-04-18 09:53:58 +02:00
parent 20c72ceb02
commit 29fb2a842c
9 changed files with 43 additions and 13 deletions

View File

@ -32,9 +32,9 @@ object Lobby extends LilaController {
tours = Env.tournament.allCreatedSorted(true),
filter = Env.setup.filter
).map(_.fold(Redirect(_), {
case (preload, entries, posts, tours, featured, leaderboard, progress, puzzle) =>
case (preload, entries, posts, tours, featured, leaderboard, progress, puzzle, playing) =>
val response = status(html.lobby.home(
Json stringify preload, entries, posts, tours, featured, leaderboard, progress, puzzle
Json stringify preload, entries, posts, tours, featured, leaderboard, progress, puzzle, playing
))
// the session cookie is required for anon lobby filter storage
ctx.req.session.data.contains(LilaCookie.sessionId).fold(

View File

@ -62,7 +62,7 @@ object User extends LilaController {
pag (filters.query.fold(Env.bookmark.api.gamePaginatorByUser(u, page)) { query =>
gamePaginator.recentlyCreated(query, filters.cachedNb)(page)
})
playing <- GameRepo nowPlaying u.id map (_.isDefined)
playing <- GameRepo isNowPlaying u.id
relation <- ctx.userId ?? { relationApi.relation(_, u.id) }
} yield html.user.show(u, info, pag, filters, playing, relation)

View File

@ -9,7 +9,7 @@ import play.api.mvc.Call
import controllers.routes
import lila.api.Context
import lila.forum.PostLiteView
import lila.game.{ Game, GameRepo, Featured }
import lila.game.{ Game, GameRepo, Featured, Pov }
import lila.lobby.actorApi.GetOpen
import lila.lobby.{ Hook, HookRepo }
import lila.relation.RelationApi
@ -30,7 +30,7 @@ final class Preload(
timelineEntries: String => Fu[List[Entry]],
dailyPuzzle: () => Fu[Option[lila.puzzle.DailyPuzzle]]) {
private type RightResponse = (JsObject, List[Entry], List[PostLiteView], List[Created], Option[Game], List[User], List[User], Option[lila.puzzle.DailyPuzzle])
private type RightResponse = (JsObject, List[Entry], List[PostLiteView], List[Created], Option[Game], List[User], List[User], Option[lila.puzzle.DailyPuzzle], Option[Pov])
private type Response = Either[Call, RightResponse]
def apply(
@ -46,13 +46,14 @@ final class Preload(
leaderboard(10) zip
progress(10) zip
dailyPuzzle() zip
(ctx.me ?? GameRepo.lastPlayingByUser) zip
filter map {
case (((((((((hooks, posts), tours), feat), blocks), entries), leaderboard), progress), puzzle), filter) =>
case ((((((((((hooks, posts), tours), feat), blocks), entries), leaderboard), progress), puzzle), playing), filter) =>
(Right((Json.obj(
"version" -> history.version,
"pool" -> JsArray(hooks map (_.render)),
"filter" -> filter.render,
"blocks" -> blocks
), entries, posts, tours, feat, leaderboard, progress, puzzle)))
), entries, posts, tours, feat, leaderboard, progress, puzzle, playing)))
}
}

View File

@ -1,4 +1,4 @@
@(preload: String, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.PostLiteView], tours: List[lila.tournament.Created], featured: Option[Game], leaderboard: List[User], progress: List[User], puzzle: Option[lila.puzzle.DailyPuzzle])(implicit ctx: Context)
@(preload: String, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.PostLiteView], tours: List[lila.tournament.Created], featured: Option[Game], leaderboard: List[User], progress: List[User], puzzle: Option[lila.puzzle.DailyPuzzle], playing: Option[Pov])(implicit ctx: Context)
@underchat = {
<div id="featured_game" title="@trans.watchLichessTV()">
@ -22,6 +22,11 @@
@goodies = {
@ctx.me.map { u =>
@playing.map { p =>
<a id="now_playing" class="is button" href="@routes.Round.player(p.fullId)">
@playerUsername(p.opponent)<br />@trans.yourTurn()
</a>
}
<div id="timeline" data-href="@routes.Lobby.timeline">
@timeline.entries(userTimeline)
<div class="links clearfix">

View File

@ -201,7 +201,7 @@ object BinaryFormat {
if (i > int23Max) int23Max - i else i
}
// this will break in 2046
// this will break in 2046
private val long40Max = math.pow(2, 40).toLong
private val long40Decay = 100000000000l
def writeLong40(long: Long) = {

View File

@ -65,8 +65,9 @@ case class Game(
def turnColor = Color(0 == turns % 2)
def turnOf(p: Player) = p == player
def turnOf(c: Color) = c == turnColor
def turnOf(p: Player): Boolean = p == player
def turnOf(c: Color): Boolean = c == turnColor
def turnOf(u: User): Boolean = player(u) ?? turnOf
def playedTurns = turns - startedAtTurn

View File

@ -70,6 +70,11 @@ trait GameRepo {
$query(Query user userId) sort Query.sortCreated
)
def lastPlayingByUser(user: User): Fu[Option[Pov]] =
(Set("thibault", "veloce") contains user.id) ?? $find(
$query(Query notFinished user.id) sort Query.sortCreated, 1
) map (_.headOption filter (_ turnOf user) flatMap { Pov(_, user) })
def chronologicalFinishedByUser(userId: String): Fu[List[Game]] = $find(
$query(Query.finished ++ Query.rated ++ Query.user(userId)) sort ($sort asc F.createdAt)
)
@ -182,6 +187,8 @@ trait GameRepo {
F.createdAt -> $gt($date(DateTime.now - 30.minutes))
))
def isNowPlaying(userId: String): Fu[Boolean] = nowPlaying(userId) map (_.isDefined)
def bestOpponents(userId: String, limit: Int): Fu[List[(String, Int)]] = {
import reactivemongo.bson._
import reactivemongo.core.commands._

View File

@ -40,7 +40,10 @@ object Pov {
def apply(game: Game, player: Player) = new Pov(game, player.color)
def apply(game: Game, playerId: String): Option[Pov] =
game player playerId map { p => new Pov(game, p.color) }
game player playerId map { apply(game, _) }
def apply(game: Game, user: lila.user.User): Option[Pov] =
game player user map { apply(game, _) }
}
case class PovRef(gameId: String, color: Color) {

View File

@ -1309,7 +1309,6 @@ div.lcmp {
.mini_board .ui-draggable-dragging {
z-index: 9;
}
/* opening.css */
div.game_config button {
@ -1954,6 +1953,20 @@ div.lichess_overboard.joining .mini_board {
#crosstable .score {
font-size: 1.3em;
}
#now_playing {
margin: 2em 0 2em -30px;
display: block;
text-align: center;
position: relative;
padding-left: 45px;
}
#now_playing::before {
content: 'U';
font-size: 32px;
position: absolute;
top: 7px;
left: 10px;
}
#timeline {
margin-top: 2em;
border-top: 1px solid #e4e4e4;