diff --git a/app/controllers/User.scala b/app/controllers/User.scala index 67dca081f0..cd0c7e2a7f 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -5,6 +5,7 @@ import play.api.mvc._, Results._ import lila.app._ import lila.common.LilaCookie import lila.db.api.$find +import lila.game.GameRepo import lila.security.Permission import lila.user.tube.userTube import lila.user.{ Context, User ⇒ UserModel, UserRepo } @@ -21,7 +22,9 @@ object User extends LilaController { } def showMini(username: String) = Open { implicit ctx ⇒ - mini(username) + OptionFuOk(UserRepo named username) { user ⇒ + GameRepo nowPlaying user.id map { html.user.mini(user, _) } + } } def showFilter(username: String, filterName: String, page: Int) = Open { implicit ctx ⇒ @@ -53,12 +56,6 @@ object User extends LilaController { }) } yield html.user.show(u, info, pag, filters) - private def mini(username: String)(implicit ctx: Context) = - OptionOk(UserRepo named username) { user ⇒ - Thread sleep 200 - html.user.mini(user) - } - def list(page: Int) = Open { implicit ctx ⇒ Reasonable(page) { val nb = 10 diff --git a/app/views/relation/actions.scala.html b/app/views/relation/actions.scala.html index 54ad556d94..20a02dd6a9 100644 --- a/app/views/relation/actions.scala.html +++ b/app/views/relation/actions.scala.html @@ -1,25 +1,27 @@ -@(userId: String, signup: Boolean = false)(implicit ctx: Context) +@(userId: String, signup: Boolean = false, playing: Boolean = false)(implicit ctx: Context) @ctx.userId.map { myId => @if(myId != userId) { @if(!blocks(userId, myId)) { +@if(!playing) { +} } @relationWith(userId) match { case None => { - - diff --git a/app/views/user/mini.scala.html b/app/views/user/mini.scala.html index 1c6c7c37fb..87595a8638 100644 --- a/app/views/user/mini.scala.html +++ b/app/views/user/mini.scala.html @@ -1,23 +1,26 @@ -@(u: User)(implicit ctx: Context) +@(u: User, playing: Option[Game])(implicit ctx: Context)
@u.rating - ±@u.perfs.global.glicko.intDeviation + ±@u.perfs.global.glicko.intDeviation @showProgress(u.progress) @u.count.game.localize @trans.games()

- @u.profileOrDefault.countryInfo.map { - case (code, name) => { - @name - } - } - @u.lang.flatMap(langName).map { name => - @name - } + @u.profileOrDefault.countryInfo.map { + case (code, name) => { + @name + } + } + @u.lang.flatMap(langName).map { name => + @name + }

@if(followsMe(u.id)) { @trans.followsYou() } + @playing.map { g => + @gameFen(g, g.player(u).getOrElse(g.firstPlayer).color) + }
-
@relation.actions(u.id)
+
@relation.actions(u.id, playing = playing.isDefined)
diff --git a/modules/game/src/main/GameRepo.scala b/modules/game/src/main/GameRepo.scala index 38725cf1f1..b1911e0ac5 100644 --- a/modules/game/src/main/GameRepo.scala +++ b/modules/game/src/main/GameRepo.scala @@ -164,6 +164,11 @@ trait GameRepo { $count(Json.obj(BSONFields.createdAt -> ($gte($date(from)) ++ $lt($date(to))))) }).sequenceFu + def nowPlaying(userId: String): Fu[Option[Game]] = + $find.one(Query.status(Status.Started) ++ Query.user(userId) ++ Json.obj( + BSONFields.createdAt -> $gt($date(DateTime.now - 30.minutes)) + )) + def bestOpponents(userId: String, limit: Int): Fu[List[(String, Int)]] = { import reactivemongo.bson._ import reactivemongo.core.commands._ diff --git a/modules/round/src/main/SocketHandler.scala b/modules/round/src/main/SocketHandler.scala index 31906fa15f..db472a5cf3 100644 --- a/modules/round/src/main/SocketHandler.scala +++ b/modules/round/src/main/SocketHandler.scala @@ -5,7 +5,6 @@ import scala.concurrent.duration._ import akka.actor._ import akka.pattern.{ ask, pipe } import chess.Color -import makeTimeout.short import play.api.libs.json.{ JsObject, Json } import actorApi._, round._ @@ -16,6 +15,7 @@ import lila.security.Flood import lila.socket.actorApi.{ Connected ⇒ _, _ } import lila.socket.Handler import lila.user.{ User, Context } +import makeTimeout.short private[round] final class SocketHandler( roundMap: ActorRef, @@ -78,6 +78,9 @@ private[round] final class SocketHandler( case ("challenge", o) ⇒ ((o str "d") |@| member.userId).tupled foreach { case (to, from) ⇒ hub.actor.challenger ! lila.hub.actorApi.setup.RemindChallenge(gameId, from, to) } + case ("liveGames", o) ⇒ o str "d" foreach { ids ⇒ + socket ! LiveGames(uid, ids.split(' ').toList) + } } } } diff --git a/modules/socket/src/main/SocketHub.scala b/modules/socket/src/main/SocketHub.scala index 36aeb00840..08e7143148 100644 --- a/modules/socket/src/main/SocketHub.scala +++ b/modules/socket/src/main/SocketHub.scala @@ -13,8 +13,8 @@ final class SocketHub extends Actor { private val sockets = collection.mutable.Set[ActorRef]() - context.system.lilaBus.subscribe(self, - 'moveEvent, 'users, 'deploy, 'nbMembers, 'socket, + context.system.lilaBus.subscribe(self, + 'moveEvent, 'users, 'deploy, 'nbMembers, 'socket, // FIXME this event only concern the current TV room 'changeFeaturedGame) diff --git a/public/javascripts/big.js b/public/javascripts/big.js index 8c6724fdf0..15967354d2 100644 --- a/public/javascripts/big.js +++ b/public/javascripts/big.js @@ -42,7 +42,13 @@ var storage = { ////////////////// var strongSocketDefaults = { - events: {}, + events: { + fen: function(e) { + $('a.live_' + e.id).each(function() { + parseFen($(this).data("fen", e.fen).data("lastmove", e.lm)); + }); + } + }, params: { sri: lichess_sri }, @@ -498,6 +504,7 @@ var storage = { url: $(this).attr('href') + '/mini', success: function(html) { $('#powerTip').html(html); + $('body').trigger('lichess.content_loaded'); } }); } @@ -1739,93 +1746,93 @@ var storage = { // gamelist.js // ///////////////// - $(function() { - - function parseFen($elem) { - if (!$elem || !$elem.jquery) { - $elem = $('.parse_fen'); - } - $elem.each(function() { - var $this = $(this); - var color = $this.data('color') || "white"; - var withKeys = $this.hasClass('with_keys'); - var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; - var fen = $this.data('fen').split(' ')[0].replace(/\//g, ''); - var lm = $this.data('lastmove'); - var lastMove = lm ? [lm[0] + lm[1], lm[2] + lm[3]] : []; - var x, y, html = '', - scolor, pcolor, pclass, c, d, increment; - var pclasses = { - 'p': 'pawn', - 'r': 'rook', - 'n': 'knight', - 'b': 'bishop', - 'q': 'queen', - 'k': 'king' - }; - var pregex = /(p|r|n|b|q|k)/; - - if ('white' == color) { - x = 8; - y = 1; - increment = function() { - y++; - if (y > 8) { - y = 1; - x--; - } - }; - } else { - x = 1; - y = 8; - increment = function() { - y--; - if (y < 1) { - y = 8; - x++; - } - }; - } - - function openSquare(x, y) { - var key = 'white' == color ? letters[y - 1] + x : letters[8 - y] + (9 - x); - var scolor = (x + y) % 2 ? 'white' : 'black'; - if ($.inArray(key, lastMove) != -1) scolor += " moved"; - var html = '
'; - } - - function closeSquare() { - return '
'; - } - - for (var fenIndex in fen) { - c = fen[fenIndex]; - html += openSquare(x, y); - if (!isNaN(c)) { // it is numeric - html += closeSquare(); - increment(); - for (d = 1; d < c; d++) { - html += openSquare(x, y) + closeSquare(); - increment(); - } - } else { - pcolor = pregex.test(c) ? 'black' : 'white'; - pclass = pclasses[c.toLowerCase()]; - html += '
'; - html += closeSquare(); - increment(); - } - } - - $this.html(html).removeClass('parse_fen'); - // attempt to free memory - html = pclasses = increment = pregex = fen = $this = 0; - }); + function parseFen($elem) { + if (!$elem || !$elem.jquery) { + $elem = $('.parse_fen'); } + $elem.each(function() { + var $this = $(this); + var color = $this.data('color') || "white"; + var withKeys = $this.hasClass('with_keys'); + var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; + var fen = $this.data('fen').split(' ')[0].replace(/\//g, ''); + var lm = $this.data('lastmove'); + var lastMove = lm ? [lm[0] + lm[1], lm[2] + lm[3]] : []; + var x, y, html = '', + scolor, pcolor, pclass, c, d, increment; + var pclasses = { + 'p': 'pawn', + 'r': 'rook', + 'n': 'knight', + 'b': 'bishop', + 'q': 'queen', + 'k': 'king' + }; + var pregex = /(p|r|n|b|q|k)/; + + if ('white' == color) { + x = 8; + y = 1; + increment = function() { + y++; + if (y > 8) { + y = 1; + x--; + } + }; + } else { + x = 1; + y = 8; + increment = function() { + y--; + if (y < 1) { + y = 8; + x++; + } + }; + } + + function openSquare(x, y) { + var key = 'white' == color ? letters[y - 1] + x : letters[8 - y] + (9 - x); + var scolor = (x + y) % 2 ? 'white' : 'black'; + if ($.inArray(key, lastMove) != -1) scolor += " moved"; + var html = '
'; + } + + function closeSquare() { + return '
'; + } + + for (var fenIndex in fen) { + c = fen[fenIndex]; + html += openSquare(x, y); + if (!isNaN(c)) { // it is numeric + html += closeSquare(); + increment(); + for (d = 1; d < c; d++) { + html += openSquare(x, y) + closeSquare(); + increment(); + } + } else { + pcolor = pregex.test(c) ? 'black' : 'white'; + pclass = pclasses[c.toLowerCase()]; + html += '
'; + html += closeSquare(); + increment(); + } + } + + $this.html(html).removeClass('parse_fen'); + // attempt to free memory + html = pclasses = increment = pregex = fen = $this = 0; + }); + } + + $(function() { parseFen(); $('body').on('lichess.content_loaded', parseFen); @@ -1847,13 +1854,6 @@ var storage = { registerLiveGames(); }); - lichess.socketDefaults.events.fen = function(e) { - $('a.live_' + e.id).each(function() { - var $this = $(this); - parseFen($this.data("fen", e.fen).data("lastmove", e.lm)); - }); - }; - $('div.checkmateCaptcha').each(function() { var $captcha = $(this); var color = $captcha.find('.mini_board').data('color');