add correspondence move alarm desktop notification
This commit is contained in:
parent
a718def197
commit
91318fa8dd
|
@ -17,4 +17,6 @@ case class InsertGame(game: Game)
|
|||
|
||||
case class AbortedBy(pov: Pov)
|
||||
|
||||
case class CorresAlarmEvent(pov: Pov)
|
||||
|
||||
private[game] case object NewCaptcha
|
||||
|
|
|
@ -166,7 +166,6 @@ case class MoveEvent(
|
|||
alarmable: Boolean,
|
||||
opponentUserId: Option[String],
|
||||
simulId: Option[String])
|
||||
case class CorresAlarmEvent(gameId: String)
|
||||
case class NbRounds(nb: Int)
|
||||
case class Abort(gameId: String, byColor: String)
|
||||
case class Berserk(gameId: String, userId: String)
|
||||
|
|
|
@ -55,6 +55,7 @@ private object BSONHandlers {
|
|||
implicit val PlanExpireHandler = Macros.handler[PlanExpire]
|
||||
|
||||
implicit val RatingRefundHandler = Macros.handler[RatingRefund]
|
||||
implicit val CorresAlarmHandler = Macros.handler[CorresAlarm]
|
||||
|
||||
implicit val ColorBSONHandler = new BSONHandler[BSONBoolean, chess.Color] {
|
||||
def read(b: BSONBoolean) = chess.Color(b.value)
|
||||
|
@ -80,6 +81,7 @@ private object BSONHandlers {
|
|||
case x: RatingRefund => RatingRefundHandler.write(x)
|
||||
case ReportedBanned => $empty
|
||||
case CoachReview => $empty
|
||||
case x: CorresAlarm => CorresAlarmHandler.write(x)
|
||||
}
|
||||
} ++ $doc("type" -> notificationContent.key)
|
||||
|
||||
|
@ -115,6 +117,7 @@ private object BSONHandlers {
|
|||
case "ratingRefund" => RatingRefundHandler read reader.doc
|
||||
case "reportedBanned" => ReportedBanned
|
||||
case "coachReview" => CoachReview
|
||||
case "corresAlarm" => CorresAlarmHandler read reader.doc
|
||||
}
|
||||
|
||||
def writes(writer: Writer, n: NotificationContent): dsl.Bdoc = writeNotificationContent(n)
|
||||
|
|
|
@ -22,17 +22,25 @@ final class Env(
|
|||
repo = repo)
|
||||
|
||||
// api actor
|
||||
system.actorOf(Props(new Actor {
|
||||
system.lilaBus.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case lila.hub.actorApi.notify.Notified(userId) =>
|
||||
api markAllRead Notification.Notifies(userId)
|
||||
case lila.game.actorApi.CorresAlarmEvent(pov) => pov.player.userId ?? { userId =>
|
||||
api addNotification Notification.make(
|
||||
Notification.Notifies(userId),
|
||||
CorresAlarm(
|
||||
gameId = pov.gameId,
|
||||
opponent = lila.game.Namer.playerString(pov.opponent)(getLightUser)))
|
||||
}
|
||||
}
|
||||
}), name = ActorName)
|
||||
}), name = ActorName), 'corresAlarm)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current = "notify" boot new Env(db = lila.db.Env.current,
|
||||
lazy val current = "notify" boot new Env(
|
||||
db = lila.db.Env.current,
|
||||
config = lila.common.PlayApp loadConfig "notify",
|
||||
getLightUser = lila.user.Env.current.lightUser,
|
||||
system = lila.common.PlayApp.system)
|
||||
|
|
|
@ -46,6 +46,9 @@ final class JSONHandlers(
|
|||
case RatingRefund(perf, points) => Json.obj(
|
||||
"perf" -> perf,
|
||||
"points" -> points)
|
||||
case CorresAlarm(gameId, opponent) => Json.obj(
|
||||
"id" -> gameId,
|
||||
"op" -> opponent)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ object Notification {
|
|||
|
||||
sealed abstract class NotificationContent(val key: String)
|
||||
|
||||
case class MentionedInThread(mentionedBy: MentionedInThread.MentionedBy,
|
||||
case class MentionedInThread(
|
||||
mentionedBy: MentionedInThread.MentionedBy,
|
||||
topic: MentionedInThread.Topic,
|
||||
topidId: MentionedInThread.TopicId,
|
||||
category: MentionedInThread.Category,
|
||||
|
@ -49,7 +50,8 @@ object MentionedInThread {
|
|||
case class PostId(value: String) extends AnyVal with StringValue
|
||||
}
|
||||
|
||||
case class InvitedToStudy(invitedBy: InvitedToStudy.InvitedBy,
|
||||
case class InvitedToStudy(
|
||||
invitedBy: InvitedToStudy.InvitedBy,
|
||||
studyName: InvitedToStudy.StudyName,
|
||||
studyId: InvitedToStudy.StudyId) extends NotificationContent("invitedStudy")
|
||||
|
||||
|
@ -122,3 +124,7 @@ case object CoachReview extends NotificationContent("coachReview")
|
|||
|
||||
case class PlanStart(userId: String) extends NotificationContent("planStart")
|
||||
case class PlanExpire(userId: String) extends NotificationContent("planExpire")
|
||||
|
||||
case class CorresAlarm(
|
||||
gameId: lila.game.Game.ID,
|
||||
opponent: String) extends NotificationContent("corresAlarm")
|
||||
|
|
|
@ -47,12 +47,12 @@ final class Env(
|
|||
system.lilaBus.subscribe(system.actorOf(Props(new Actor {
|
||||
import akka.pattern.pipe
|
||||
def receive = {
|
||||
case lila.game.actorApi.FinishGame(game, _, _) => pushApi finish game
|
||||
case move: lila.hub.actorApi.round.MoveEvent => pushApi move move
|
||||
case lila.message.Event.NewMessage(t, p) => pushApi newMessage (t, p)
|
||||
case lila.challenge.Event.Create(c) => pushApi challengeCreate c
|
||||
case lila.challenge.Event.Accept(c, joinerId) => pushApi.challengeAccept(c, joinerId)
|
||||
case lila.hub.actorApi.round.CorresAlarmEvent(id) => pushApi corresAlarm id
|
||||
case lila.game.actorApi.FinishGame(game, _, _) => pushApi finish game
|
||||
case move: lila.hub.actorApi.round.MoveEvent => pushApi move move
|
||||
case lila.message.Event.NewMessage(t, p) => pushApi newMessage (t, p)
|
||||
case lila.challenge.Event.Create(c) => pushApi challengeCreate c
|
||||
case lila.challenge.Event.Accept(c, joinerId) => pushApi.challengeAccept(c, joinerId)
|
||||
case lila.game.actorApi.CorresAlarmEvent(pov) => pushApi corresAlarm pov
|
||||
}
|
||||
})), 'finishGame, 'moveEvent, 'newMessage, 'challenge, 'corresAlarm)
|
||||
}
|
||||
|
|
|
@ -78,29 +78,23 @@ private final class PushApi(
|
|||
}
|
||||
}
|
||||
|
||||
def corresAlarm(gameId: String): Funit = GameRepo game gameId flatMap {
|
||||
_ ?? { game =>
|
||||
val pov = Pov(game, game.turnColor)
|
||||
game.player(pov.color).userId ?? { userId =>
|
||||
IfAway(pov) {
|
||||
pushToAll(userId, _.corresAlarm, PushApi.Data(
|
||||
title = "Time is almost up!",
|
||||
body = s"You are about to lose on time against ${opponentName(pov)}",
|
||||
stacking = Stacking.GameMove,
|
||||
payload = Json.obj(
|
||||
"userId" -> userId,
|
||||
"userData" -> Json.obj(
|
||||
"type" -> "corresAlarm",
|
||||
"gameId" -> game.id,
|
||||
"fullId" -> pov.fullId,
|
||||
"color" -> pov.color.name,
|
||||
"fen" -> Forsyth.exportBoard(game.toChess.board),
|
||||
"lastMove" -> game.castleLastMoveTime.lastMoveString,
|
||||
"secondsLeft" -> pov.remainingSeconds))))
|
||||
}
|
||||
}
|
||||
def corresAlarm(pov: Pov): Funit =
|
||||
pov.player.userId ?? { userId =>
|
||||
pushToAll(userId, _.corresAlarm, PushApi.Data(
|
||||
title = "Time is almost up!",
|
||||
body = s"You are about to lose on time against ${opponentName(pov)}",
|
||||
stacking = Stacking.GameMove,
|
||||
payload = Json.obj(
|
||||
"userId" -> userId,
|
||||
"userData" -> Json.obj(
|
||||
"type" -> "corresAlarm",
|
||||
"gameId" -> pov.gameId,
|
||||
"fullId" -> pov.fullId,
|
||||
"color" -> pov.color.name,
|
||||
"fen" -> Forsyth.exportBoard(pov.game.toChess.board),
|
||||
"lastMove" -> pov.game.castleLastMoveTime.lastMoveString,
|
||||
"secondsLeft" -> pov.remainingSeconds))))
|
||||
}
|
||||
}
|
||||
|
||||
def newMessage(t: Thread, p: Post): Funit =
|
||||
lightUser(t.senderOf(p)) ?? { sender =>
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
package lila.round
|
||||
|
||||
import akka.actor._
|
||||
import akka.pattern.ask
|
||||
import org.joda.time.DateTime
|
||||
import play.api.libs.iteratee._
|
||||
import reactivemongo.api._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.game.GameRepo
|
||||
import lila.hub.actorApi.map.Ask
|
||||
import lila.hub.actorApi.round.IsOnGame
|
||||
import lila.game.{ GameRepo, Pov }
|
||||
import makeTimeout.short
|
||||
|
||||
private final class CorresAlarm(coll: Coll) extends Actor {
|
||||
private final class CorresAlarm(
|
||||
coll: Coll,
|
||||
roundSocketHub: ActorSelection) extends Actor {
|
||||
|
||||
object Schedule
|
||||
object Run
|
||||
|
@ -45,12 +51,17 @@ private final class CorresAlarm(coll: Coll) extends Actor {
|
|||
)).cursor[Alarm](ReadPreference.secondaryPreferred)
|
||||
.enumerator(100, Cursor.ContOnError())
|
||||
.|>>>(Iteratee.foldM[Alarm, Int](0) {
|
||||
case (count, alarm) => {
|
||||
context.system.lilaBus.publish(
|
||||
lila.hub.actorApi.round.CorresAlarmEvent(alarm._id),
|
||||
'corresAlarm)
|
||||
coll.remove($id(alarm._id))
|
||||
} inject (count + 1)
|
||||
case (count, alarm) => GameRepo.game(alarm._id).flatMap {
|
||||
_ ?? { game =>
|
||||
val pov = Pov(game, game.turnColor)
|
||||
roundSocketHub ? Ask(pov.gameId, IsOnGame(pov.color)) mapTo manifest[Boolean] addEffect {
|
||||
case true => // already looking at the game
|
||||
case false => context.system.lilaBus.publish(
|
||||
lila.game.actorApi.CorresAlarmEvent(pov),
|
||||
'corresAlarm)
|
||||
}
|
||||
}
|
||||
} >> coll.remove($id(alarm._id)) inject (count + 1)
|
||||
})
|
||||
.chronometer.mon(_.round.alarm.time).result
|
||||
.addEffect(c => lila.mon.round.alarm.count(c))
|
||||
|
|
|
@ -193,11 +193,11 @@ final class Env(
|
|||
scheduler.message(2.1 seconds)(roundMap -> actorApi.GetNbRounds)
|
||||
|
||||
system.actorOf(
|
||||
Props(classOf[Titivate], roundMap, hub.actor.bookmark, hub.actor.chat),
|
||||
Props(new Titivate(roundMap, hub.actor.bookmark, hub.actor.chat)),
|
||||
name = "titivate")
|
||||
|
||||
system.lilaBus.subscribe(system.actorOf(
|
||||
Props(classOf[CorresAlarm], db(CollectionAlarm)),
|
||||
Props(new CorresAlarm(db(CollectionAlarm), hub.socket.round)),
|
||||
name = "corres-alarm"), 'moveEvent, 'finishGame)
|
||||
|
||||
lazy val takebacker = new Takebacker(
|
||||
|
|
|
@ -327,7 +327,7 @@ object ApplicationBuild extends Build {
|
|||
reactivemongo.driver, reactivemongo.iteratees)
|
||||
)
|
||||
|
||||
lazy val notifyModule = project("notify", Seq(common, db, user, hub, relation)).settings(
|
||||
lazy val notifyModule = project("notify", Seq(common, db, game, user, hub, relation)).settings(
|
||||
libraryDependencies ++= provided(play.api, reactivemongo.driver)
|
||||
)
|
||||
|
||||
|
|
|
@ -255,6 +255,22 @@ var handlers = {
|
|||
return 'Refund: ' + n.content.points + ' ' + n.content.perf + ' rating points.'
|
||||
}
|
||||
},
|
||||
corresAlarm: {
|
||||
html: function(notification) {
|
||||
var url = '/' + notification.content.id;
|
||||
|
||||
return genericNotification(notification, url, ';', [
|
||||
m('span', [
|
||||
m('strong', 'Time is almost up!'),
|
||||
drawTime(notification)
|
||||
]),
|
||||
m('span', 'Game vs ' + notification.content.op)
|
||||
]);
|
||||
},
|
||||
text: function(n) {
|
||||
return 'Time is almost up!';
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function drawNotification(notification) {
|
||||
|
|
Loading…
Reference in a new issue