Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 5 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
View
13 app/controllers/Round.scala
@@ -10,13 +10,15 @@ import socket.Util.connectionFail
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.iteratee._
+import play.api.templates.Html
import scalaz.effects._
object Round extends LilaController {
private val gameRepo = env.game.gameRepo
private val socket = env.round.socket
private val hand = env.round.hand
+ private val messenger = env.round.messenger
private val rematcher = env.setup.rematcher
private val joiner = env.setup.joiner
@@ -35,10 +37,15 @@ object Round extends LilaController {
}
def player(fullId: String) = Open { implicit ctx
- IOptionResult(gameRepo pov fullId) { pov
+ IOptionIOResult(gameRepo pov fullId) { pov
pov.game.started.fold(
- Ok(html.round.player(pov, version(pov.gameId))),
- Redirect(routes.Setup.await(fullId))
+ messenger render pov.game map { roomHtml
+ Ok(html.round.player(
+ pov,
+ version(pov.gameId),
+ roomHtml map { Html(_) }))
+ },
+ io(Redirect(routes.Setup.await(fullId)))
)
}
}
View
2 app/game/DbGame.scala
@@ -225,7 +225,7 @@ case class DbGame(
def aiLevel: Option[Int] = players find (_.isAi) flatMap (_.aiLevel)
- lazy val hasAi: Boolean = players exists (_.isAi)
+ def hasAi: Boolean = players exists (_.isAi)
def mapPlayers(f: DbPlayer DbPlayer) = copy(
whitePlayer = f(whitePlayer),
View
3 app/round/Messenger.scala
@@ -55,6 +55,9 @@ final class Messenger(
},
io(Nil))
+ def render(game: DbGame): IO[Option[String]] =
+ game.hasAi.fold(io(None), render(game.id) map (_.some))
+
def render(roomId: String): IO[String] =
roomRepo room roomId map (_.render)
View
4 app/round/Room.scala
@@ -29,7 +29,9 @@ object Room {
def render(msg: (String, String)): String = msg match {
case (author, text) """<li class="%s%s">%s</li>""".format(
- author, (author == "system").fold(" trans_me", ""), escapeXml(text)
+ author,
+ if (author == "system") " trans_me" else "",
+ escapeXml(text)
)
}
}
View
65 app/setup/Rematcher.scala
@@ -17,37 +17,52 @@ final class Rematcher(
messenger: Messenger,
timelinePush: DbGame IO[Unit]) extends Handler(gameRepo) {
- def offerOrAccept(fullId: String): IO[Valid[(String, List[Event])]] =
+ type Result = (String, List[Event])
+
+ def offerOrAccept(fullId: String): IO[Valid[Result]] =
attempt(fullId, {
case pov @ Pov(game, color) if game playerCanRematch color
success(game.opponent(color).isOfferingRematch.fold(
game.nextId.fold(
- nextId io(nextId -> Nil),
- for {
- nextGame returnGame(pov) map (_.start)
- _ gameRepo insert nextGame
- nextId = nextGame.id
- _ game.variant.standard.fold(io(), gameRepo saveInitialFen game)
- _ timelinePush(game)
- // messenges are not sent to the next game socket
- // as nobody is there to see them yet
- _ messenger init nextGame
- } yield nextId -> List(
- Event.RedirectOwner(White, playerUrl(nextGame, White)),
- Event.RedirectOwner(Black, playerUrl(nextGame, Black)),
- // tell spectators to reload the table
- Event.ReloadTable(White),
- Event.ReloadTable(Black))
- )
- , {
- val progress = Progress(game, Event.ReloadTable(!color)) map { g
- g.updatePlayer(color, _.offerRematch)
- }
- gameRepo save progress map { _ fullId -> progress.events }
- }))
+ rematchExists(pov),
+ rematchJoin(pov)
+ ),
+ rematchCreate(pov)
+ ))
case _ !!("invalid rematch offer " + fullId)
})
+ private def rematchExists(pov: Pov)(nextId: String): IO[Result] =
+ gameRepo.pov(nextId, !pov.color) map { nextPovOption
+ nextPovOption.fold(
+ _.fullId -> Nil,
+ pov.fullId -> Nil)
+ }
+
+ private def rematchJoin(pov: Pov): IO[Result] = for {
+ nextGame returnGame(pov) map (_.start)
+ _ gameRepo insert nextGame
+ nextId = nextGame.id
+ _ pov.game.variant.standard.fold(io(), gameRepo saveInitialFen nextGame)
+ _ timelinePush(nextGame)
+ // messenges are not sent to the next game socket
+ // as nobody is there to see them yet
+ _ messenger init nextGame
+ } yield (nextGame fullIdOf !pov.color) -> List(
+ Event.RedirectOwner(White, playerUrl(nextGame, Black)),
+ Event.RedirectOwner(Black, playerUrl(nextGame, White)),
+ // tell spectators to reload the table
+ Event.ReloadTable(White),
+ Event.ReloadTable(Black))
+
+ private def rematchCreate(pov: Pov): IO[Result] = for {
+ p1 messenger.systemMessage(pov.game, _.rematchOfferSent) map { es
+ Progress(pov.game, Event.ReloadTable(!pov.color) :: es)
+ }
+ p2 = p1 map { g g.updatePlayer(pov.color, _ offerRematch) }
+ _ gameRepo save p2
+ } yield pov.fullId -> p2.events
+
private def returnGame(pov: Pov): IO[DbGame] = for {
board pov.game.variant.standard.fold(
io(pov.game.variant.pieces),
@@ -83,6 +98,6 @@ final class Rematcher(
private def clockName(clock: Option[Clock]): String =
clock.fold(Namer.clock, "Unlimited")
- private def playerUrl(game: DbGame, color: ChessColor): String =
+ private def playerUrl(game: DbGame, color: ChessColor): String =
routes.Round.player(game fullIdOf color).url
}
View
7 app/views/round/player.scala.html
@@ -1,4 +1,4 @@
-@(pov: Pov, version: Int)(implicit ctx: Context)
+@(pov: Pov, version: Int, roomHtml: Option[Html])(implicit ctx: Context)
@import pov._
@@ -17,7 +17,10 @@
</div>
}
-@round.layout(title = title, goodies = goodies) {
+@round.layout(
+title = title,
+goodies = goodies,
+chat = roomHtml.map(round.room(_))) {
<div class="lichess_game clearfix lichess_player_@color not_spectator"
data-socket-url="@routes.Round.websocketPlayer(fullId)"
data-table-url="@routes.Round.tablePlayer(fullId)"
View
15 app/views/round/room.scala.html
@@ -0,0 +1,15 @@
+@(roomHtml: Html)(implicit ctx: Context)
+
+<div class="lichess_chat">
+ <div class="lichess_chat_top">
+ <span class="s16 title">@trans.chatRoom()</span>
+ <input title="@trans.toggleTheChat()" class="toggle_chat" type="checkbox" checked="checked" />
+ </div>
+ <div class="lichess_chat_inner">
+ <ol class="lichess_messages">@roomHtml</ol>
+ <form action="" method="post">
+ <input class="lichess_say lichess_hint" value="@trans.talkInChat()" />
+ <a class="send"></a>
+ </form>
+ </div>
+</div>
View
4 cli/src/main/scala/TransJsDump.scala
@@ -24,6 +24,8 @@ case class TransJsDump(
keys.drawOfferDeclined,
keys.drawOfferAccepted,
keys.drawOfferCanceled,
+ keys.rematchOfferSent,
+ keys.rematchOfferAccepted,
keys.rematchOfferCanceled,
keys.rematchOfferDeclined,
keys.takebackPropositionSent,
@@ -38,7 +40,7 @@ case class TransJsDump(
_ putStrLn("Dumping JavaScript translations in " + path)
langs = pool.langs
_ run(path.mkdir, "Create directory")
- _ run(langs foreach { lang run(write(lang)) }, "Write translations")
+ _ run(langs foreach { lang write(lang) }, "Write translations")
} yield ()
def write(lang: Lang) {
View
60 public/javascripts/game.js
@@ -474,44 +474,44 @@ $.widget("lichess.game", {
},
initChat: function() {
var self = this;
- if (self.options.player.spectator) {
+ if (!self.$chat.length) {
return;
}
- if (self.$chat.length) {
- self.$chatMsgs.find('>li').each(function() { $(this).html(urlToLink($(this).html())); });
- self.$chatMsgs.scrollable();
- var $form = self.$chat.find('form');
- self.$chatMsgs[0].scrollTop = 9999999;
- var $input = self.$chat.find('input.lichess_say').one("focus", function() {
- $input.val('').removeClass('lichess_hint');
- });
+ self.$chatMsgs.find('>li').each(function() { $(this).html(urlToLink($(this).html())); });
+ self.$chatMsgs.scrollable();
+ var $form = self.$chat.find('form');
+ self.$chatMsgs[0].scrollTop = 9999999;
+ var $input = self.$chat.find('input.lichess_say').one("focus", function() {
+ $input.val('').removeClass('lichess_hint');
+ });
- // send a message
- $form.submit(function() {
- var text = $.trim($input.val());
- if (!text) return false;
- if (text.length > 140) {
- alert('Max length: 140 chars. ' + text.length + ' chars used.');
- return false;
- }
- $input.val('');
- lichess.socket.send('talk', text);
+ // send a message
+ $form.submit(function() {
+ var text = $.trim($input.val());
+ if (!text) return false;
+ if (text.length > 140) {
+ alert('Max length: 140 chars. ' + text.length + ' chars used.');
return false;
- });
+ }
+ $input.val('');
+ lichess.socket.send('talk', text);
+ return false;
+ });
- self.$chat.find('a.send').click(function() {
- $input.trigger('click');
- $form.submit();
- });
+ self.$chat.find('a.send').click(function() {
+ $input.trigger('click');
+ $form.submit();
+ });
- // toggle the chat
- self.$chat.find('input.toggle_chat').change(function() {
- self.$chat.toggleClass('hidden', ! $(this).attr('checked'));
- }).trigger('change');
- }
+ // toggle the chat
+ self.$chat.find('input.toggle_chat').change(function() {
+ self.$chat.toggleClass('hidden', ! $(this).attr('checked'));
+ }).trigger('change');
},
appendToChat: function(msg) {
- if (this.$chat.length) this.$chatMsgs.append(urlToLink(msg))[0].scrollTop = 9999999;
+ if (this.$chat.length) {
+ this.$chatMsgs.append(urlToLink(msg))[0].scrollTop = 9999999;
+ }
},
reloadTable: function(callback) {
var self = this;

No commit comments for this range

Something went wrong with that request. Please try again.