chat starts working

This commit is contained in:
Thibault Duplessis 2014-02-01 02:02:32 +01:00
parent a34df7ceb4
commit 05e020a068
13 changed files with 68 additions and 41 deletions

View file

@ -6,7 +6,7 @@ import reactivemongo.bson.BSONDocument
import lila.db.Types.Coll
import lila.user.{ User, UserRepo }
private[chat] final class ChatApi(
final class ChatApi(
coll: Coll,
flood: lila.security.Flood,
maxLinesPerChat: Int,
@ -61,9 +61,9 @@ private[chat] final class ChatApi(
private def pushLine(chatId: ChatId, line: Line) = coll.update(
BSONDocument("_id" -> chatId),
BSONDocument("$push" -> BSONDocument(
"messages" -> BSONDocument(
"$each" -> line,
"$slice" -> maxLinesPerChat)
Chat.BSONFields.lines -> BSONDocument(
"$each" -> List(line),
"$slice" -> -maxLinesPerChat)
)),
upsert = true)

View file

@ -3,7 +3,7 @@ package lila.chat
import akka.actor._
import chess.Color
import lila.hub.actorApi.chat._
import actorApi._
private[chat] final class FrontActor(api: ChatApi) extends Actor {
@ -13,18 +13,19 @@ private[chat] final class FrontActor(api: ChatApi) extends Actor {
def receive = {
case UserTalk(chatId, userId, text) api.userChat.write(chatId, userId, text) foreach publish(chatId)
case UserTalk(chatId, userId, text, replyTo)
api.userChat.write(chatId, userId, text) foreach publish(chatId, replyTo)
case PlayerTalk(chatId, color, text) api.playerChat.write(chatId, Color(color), text) foreach publish(chatId)
case PlayerTalk(chatId, color, text, replyTo)
api.playerChat.write(chatId, Color(color), text) foreach publish(chatId, replyTo)
case SystemTalk(chatId, text) api.userChat.system(chatId, text) foreach publish(chatId)
case msg: NotifyLine bus.publish(msg, 'chatOut)
case SystemTalk(chatId, text, replyTo)
api.userChat.system(chatId, text) foreach publish(chatId, replyTo)
}
def publish(chatId: String)(lineOption: Option[Line]) {
def publish(chatId: String, replyTo: ActorRef)(lineOption: Option[Line]) {
lineOption foreach { line
self ! NotifyLine(chatId, Line toJson line)
replyTo ! ChatLine(chatId, line)
}
}
}

View file

@ -29,7 +29,7 @@ object Line {
def write(x: Line) = BSONString(lineToStr(x))
}
private val UserLineRegex = """^([\w-]{2,})[\s!](.+)$""".r
private val UserLineRegex = """^([\w-]{2,})(\s|\!)(.+)$""".r
def strToUserLine(str: String): Option[UserLine] = str match {
case UserLineRegex(username, " ", text) UserLine(username, text, false).some
case UserLineRegex(username, "!", text) UserLine(username, text, true).some

View file

@ -0,0 +1,9 @@
package lila.chat
package actorApi
import akka.actor.ActorRef
case class UserTalk(chatId: String, userId: String, text: String, replyTo: ActorRef)
case class PlayerTalk(chatId: String, white: Boolean, text: String, replyTo: ActorRef)
case class SystemTalk(chatId: String, text: String, replyTo: ActorRef)
case class ChatLine(chatId: String, line: Line)

View file

@ -1,8 +1,8 @@
package lila.game
import org.apache.commons.lang3.StringEscapeUtils.escapeXml
import play.api.libs.json._
import lila.chat.{ Line, UserLine, PlayerLine }
import chess.Pos.{ piotr, allPiotrs }
import chess.{ PromotableRole, Pos, Color, Situation, Move ChessMove, Clock ChessClock }
@ -107,20 +107,20 @@ object Event {
def data = JsString(pos.key)
}
case class Message(author: String, text: String, t: Boolean) extends Event {
case class PlayerMessage(line: PlayerLine) extends Event {
def typ = "message"
def data = Json.obj("u" -> author, "t" -> escapeXml(text))
def data = Line toJson line
override def owner = true
override def troll = t
override def troll = false
}
// it *IS* a username, and not a user ID
// immediately used for rendering
case class WatcherMessage(username: Option[String], text: String, t: Boolean) extends Event {
case class UserMessage(line: UserLine, w: Boolean) extends Event {
def typ = "message"
def data = Json.obj("u" -> username, "t" -> escapeXml(text))
override def watcher = true
override def troll = t
def data = Line toJson line
override def troll = line.troll
override def watcher = w
}
object End extends Empty {

View file

@ -35,13 +35,6 @@ case class WithUserIds(f: Iterable[String] ⇒ Unit)
case object GetUids
package chat {
case class UserTalk(chatId: String, userId: String, text: String)
case class PlayerTalk(chatId: String, white: Boolean, text: String)
case class SystemTalk(chatId: String, text: String)
case class NotifyLine(chatId: String, json: JsObject)
}
package report {
case class Cheater(userId: String, text: String)
case class Check(userId: String)

View file

@ -59,7 +59,7 @@ final class Env(
}), name = ActorMapName)
private val socketHub = system.actorOf(
Props(new lila.socket.SocketHubActor.Default[Socket] {
Props(new lila.socket.SocketHubActor[Socket] {
def mkActor(id: String) = new Socket(
gameId = id,
history = history(),
@ -68,6 +68,10 @@ final class Env(
socketTimeout = SocketTimeout,
disconnectTimeout = PlayerDisconnectTimeout,
ragequitTimeout = PlayerRagequitTimeout)
def receive: Receive = ({
case msg@lila.chat.actorApi.ChatLine(id, line)
self ! lila.hub.actorApi.map.Tell(id take 8, msg).pp
}: Receive) orElse socketHubReceive
}),
name = SocketName)
@ -113,6 +117,7 @@ final class Env(
lazy val messenger = new Messenger(
bus = system.lilaBus,
socketHub = socketHub,
i18nKeys = i18nKeys)
lazy val fenUrlWatch = new FenUrlWatch(

View file

@ -2,17 +2,18 @@ package lila.round
import lila.common.Bus
import lila.game.Game
import lila.hub.actorApi.chat._
import lila.chat.actorApi._
import lila.i18n.I18nKey.{ Select SelectI18nKey }
import lila.i18n.I18nKeys
final class Messenger(
bus: Bus,
socketHub: akka.actor.ActorRef,
i18nKeys: I18nKeys) {
def apply(game: Game, message: SelectI18nKey, args: Any*) {
val translated = message(i18nKeys).en(args: _*)
bus.publish(SystemTalk(game.id + "/w", translated), 'chatIn)
if (game.nonAi) bus.publish(SystemTalk(game.id, translated), 'chatIn)
bus.publish(SystemTalk(game.id + "/w", translated, socketHub), 'chatIn)
if (game.nonAi) bus.publish(SystemTalk(game.id, translated, socketHub), 'chatIn)
}
}

View file

@ -26,6 +26,8 @@ private[round] final class Socket(
disconnectTimeout: Duration,
ragequitTimeout: Duration) extends SocketActor[Member](uidTimeout) {
context.system.lilaBus.subscribe(self, 'chatOut)
private val timeBomb = new TimeBomb(socketTimeout)
private final class Player(color: Color) {
@ -87,8 +89,13 @@ private[round] final class Socket(
sender ! Connected(enumerator, member)
}
case Nil
case events: Events notify(events)
case Nil
case events: Events notify(events)
case lila.chat.actorApi.ChatLine(chatId, line) notify(List(line match {
case l: lila.chat.UserLine Event.UserMessage(l, chatId endsWith "/w")
case l: lila.chat.PlayerLine Event.PlayerMessage(l)
}))
case AnalysisAvailable notifyAll("analysisAvailable", true)

View file

@ -8,6 +8,7 @@ import chess.Color
import play.api.libs.json.{ JsObject, Json }
import actorApi._, round._
import lila.chat.actorApi._
import lila.common.PimpedJson._
import lila.game.{ Game, Pov, PovRef, PlayerRef, GameRepo }
import lila.hub.actorApi.map._
@ -37,6 +38,11 @@ private[round] final class SocketHandler(
case ("liveGames", o) o str "d" foreach { ids
socket ! LiveGames(uid, ids.split(' ').toList)
}
case ("talk", o) o str "d" foreach { text
member.userId foreach { userId =>
bus.publish(UserTalk(gameId + "/w", userId, text, socket), 'chatIn)
}
}
}) { playerId
{
case ("p", o) o int "v" foreach { v socket ! PingVersion(uid, v) }
@ -70,8 +76,8 @@ private[round] final class SocketHandler(
}
case ("talk", o) o str "d" foreach { text
bus.publish(member.userId match {
case Some(userId) lila.hub.actorApi.chat.UserTalk(uid, userId, text)
case None lila.hub.actorApi.chat.PlayerTalk(uid, member.color.white, text)
case Some(userId) UserTalk(gameId, userId, text, socket)
case None PlayerTalk(gameId, member.color.white, text, socket)
}, 'chatIn)
}
}

View file

@ -90,7 +90,7 @@ object ApplicationBuild extends Build {
play.api, play.test, RM, PRM, hasher)
)
lazy val game = project("game", Seq(common, memo, db, hub, user, chess)).settings(
lazy val game = project("game", Seq(common, memo, db, hub, user, chess, chat)).settings(
libraryDependencies ++= provided(
play.api, RM, PRM)
)
@ -106,7 +106,7 @@ object ApplicationBuild extends Build {
)
lazy val round = project("round", Seq(
common, db, memo, hub, socket, chess, game, user, i18n, ai, pref)).settings(
common, db, memo, hub, socket, chess, game, user, i18n, ai, pref, chat)).settings(
libraryDependencies ++= provided(play.api, RM, PRM)
)

View file

@ -348,6 +348,11 @@ var storage = {
});
}
},
message: function(msg) {
$('div.lichess_chat').each(function() {
$(this).chat("append", msg);
});
},
nbm: function(e) {
$('#nb_messages').text(e || "0").toggleClass("unread", e > 0);
},
@ -1584,11 +1589,12 @@ var storage = {
if (!$toggle[0].checked) {
self.element.addClass('hidden');
}
if (self.options.messages.length > 0) self._appendMany(self.options.messages);
},
append: function(msg) {
this._appendHtml(this._render(msg));
},
appendMany: function(objs) {
_appendMany: function(objs) {
var self = this,
html = "";
$.each(objs, function() {
@ -1605,7 +1611,7 @@ var storage = {
} else {
user = '<span class="user">' + $.userLinkLimit(msg.u, 14) + '</span>';
}
return '<li class="' + (u == 'system' ? ' trans_me' : '') + (msg.r ? ' troll' : '') + '">' + urlToLink(msg.t) + '</li>';
return '<li class="' + (msg.u == 'system' ? ' trans_me' : '') + (msg.r ? ' troll' : '') + '">' + user + urlToLink(msg.t) + '</li>';
},
_appendHtml: function(html) {
this.$msgs.append(html);

View file

@ -2,7 +2,6 @@ div.lichess_board_wrap {
float: left;
border: 1px solid #ccc;
position: relative;
display: none;
}
span.board_mark {
position: absolute;