game reminders for everybody
This commit is contained in:
parent
67f07bb9ab
commit
3ed0552b0f
|
@ -27,6 +27,7 @@ final class Env(
|
|||
leaderboard = Env.user.cached.topRatingDay.apply,
|
||||
progress = Env.user.cached.topProgressDay.apply,
|
||||
timelineEntries = Env.timeline.getter.userEntries _,
|
||||
nowPlaying = Env.round.nowPlaying,
|
||||
dailyPuzzle = Env.puzzle.daily)
|
||||
|
||||
lazy val userInfo = mashup.UserInfo(
|
||||
|
|
|
@ -28,9 +28,10 @@ final class Preload(
|
|||
leaderboard: Int => Fu[List[User]],
|
||||
progress: Int => Fu[List[User]],
|
||||
timelineEntries: String => Fu[List[Entry]],
|
||||
nowPlaying: (User, Int) => Fu[List[Pov]],
|
||||
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], Option[Pov])
|
||||
private type RightResponse = (JsObject, List[Entry], List[PostLiteView], List[Created], Option[Game], List[User], List[User], Option[lila.puzzle.DailyPuzzle], List[Pov])
|
||||
private type Response = Either[Call, RightResponse]
|
||||
|
||||
def apply(
|
||||
|
@ -46,7 +47,7 @@ final class Preload(
|
|||
leaderboard(10) zip
|
||||
progress(10) zip
|
||||
dailyPuzzle() zip
|
||||
(ctx.me ?? GameRepo.lastPlayingByUser) zip
|
||||
(ctx.me ?? { nowPlaying(_, 3) }) zip
|
||||
filter map {
|
||||
case ((((((((((hooks, posts), tours), feat), blocks), entries), leaderboard), progress), puzzle), playing), filter) =>
|
||||
(Right((Json.obj(
|
||||
|
|
|
@ -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], playing: Option[Pov])(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: List[Pov])(implicit ctx: Context)
|
||||
|
||||
@underchat = {
|
||||
<div id="featured_game" title="@trans.watchLichessTV()">
|
||||
|
@ -22,10 +22,14 @@
|
|||
|
||||
@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>
|
||||
@if(playing.nonEmpty) {
|
||||
<div id="now_playing">
|
||||
@playing.map { p =>
|
||||
<a class="is button" href="@routes.Round.player(p.fullId)">
|
||||
@playerUsername(p.opponent)<br />@trans.yourTurn()
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div id="timeline" data-href="@routes.Lobby.timeline">
|
||||
@timeline.entries(userTimeline)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 441e66ad6e5dda456dd0e12ab2427406b0613210
|
||||
Subproject commit 49ed2315372c230a938b7120272dd5de65ee5735
|
|
@ -70,11 +70,6 @@ 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)
|
||||
)
|
||||
|
|
|
@ -39,6 +39,7 @@ final class Env(
|
|||
val ActorName = config getString "actor.name"
|
||||
val HijackEnabled = config getBoolean "hijack.enabled"
|
||||
val HijackSalt = config getString "hijack.salt"
|
||||
val CollectionReminder = config getString "collection.reminder"
|
||||
}
|
||||
import settings._
|
||||
|
||||
|
@ -107,6 +108,7 @@ final class Env(
|
|||
bus = system.lilaBus,
|
||||
finisher = finisher,
|
||||
cheatDetector = cheatDetector,
|
||||
reminder = reminder,
|
||||
uciMemo = uciMemo)
|
||||
|
||||
// public access to AI play, for setup.Processor usage
|
||||
|
@ -135,6 +137,9 @@ final class Env(
|
|||
def version(gameId: String): Fu[Int] =
|
||||
socketHub ? Ask(gameId, GetVersion) mapTo manifest[Int]
|
||||
|
||||
private lazy val reminder = new Reminder(db(CollectionReminder))
|
||||
def nowPlaying = reminder.nowPlaying
|
||||
|
||||
private[round] def animationDelay = AnimationDelay
|
||||
private[round] def moretimeSeconds = Moretime.toSeconds
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ private[round] final class Player(
|
|||
bus: lila.common.Bus,
|
||||
finisher: Finisher,
|
||||
cheatDetector: CheatDetector,
|
||||
reminder: Reminder,
|
||||
uciMemo: UciMemo) {
|
||||
|
||||
def human(play: HumanPlay, round: ActorRef)(pov: Pov): Fu[Events] = play match {
|
||||
|
@ -31,6 +32,7 @@ private[round] final class Player(
|
|||
case (progress, move) =>
|
||||
(GameRepo save progress) >>-
|
||||
(pov.game.hasAi ! uciMemo.add(pov.game, move)) >>-
|
||||
(reminder remind progress.game) >>-
|
||||
notifyProgress(move, progress, ip) >>
|
||||
progress.game.finished.fold(
|
||||
moveFinish(progress.game, color) map { progress.events ::: _ }, {
|
||||
|
|
51
modules/round/src/main/Reminder.scala
Normal file
51
modules/round/src/main/Reminder.scala
Normal file
|
@ -0,0 +1,51 @@
|
|||
package lila.round
|
||||
|
||||
import lila.db.Types._
|
||||
import lila.game.{ Game, Pov, GameRepo }
|
||||
import lila.user.User
|
||||
import reactivemongo.bson._
|
||||
|
||||
private final class Reminder(coll: Coll) {
|
||||
|
||||
private case class Remind(_id: String, g: List[String])
|
||||
|
||||
private implicit val remindBSONHandler = Macros.handler[Remind]
|
||||
|
||||
val nowPlaying: (User, Int) => Fu[List[Pov]] = (user, max) =>
|
||||
coll.find(BSONDocument("_id" -> user.id)).one[Remind] flatMap {
|
||||
case None => fuccess(Nil)
|
||||
case Some(r) =>
|
||||
val ids = scala.util.Random.shuffle(r.g).take(max).sorted
|
||||
GameRepo games ids map2 { (g: Game) =>
|
||||
if (remindable(g) && g.playable && g.turnOf(user)) Some(g)
|
||||
else {
|
||||
remove(user.id, g.id)
|
||||
none
|
||||
}
|
||||
} map { _.flatten flatMap { Pov(_, user) } }
|
||||
|
||||
}
|
||||
|
||||
private[round] def remind(game: Game) {
|
||||
if (remindable(game)) {
|
||||
game.players foreach { player =>
|
||||
player.userId foreach { userId =>
|
||||
if (game.playable && game.turnOf(player)) add(userId, game.id)
|
||||
else remove(userId, game.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def remindable(game: Game) =
|
||||
!game.hasAi && game.clock.fold(true)(chess.Speed.isUnlimited)
|
||||
|
||||
private def add(userId: String, gameId: String) = coll.update(
|
||||
BSONDocument("_id" -> userId),
|
||||
BSONDocument("$addToSet" -> BSONDocument("g" -> gameId)),
|
||||
upsert = true)
|
||||
|
||||
private def remove(userId: String, gameId: String) = coll.update(
|
||||
BSONDocument("_id" -> userId),
|
||||
BSONDocument("$pull" -> BSONDocument("g" -> gameId)))
|
||||
}
|
|
@ -1954,13 +1954,16 @@ div.lichess_overboard.joining .mini_board {
|
|||
font-size: 1.3em;
|
||||
}
|
||||
#now_playing {
|
||||
margin: 2em 0 2em -30px;
|
||||
margin: 2em 0 1em -30px;
|
||||
}
|
||||
#now_playing .button {
|
||||
display: block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
padding-left: 45px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#now_playing::before {
|
||||
#now_playing .button::before {
|
||||
content: 'U';
|
||||
font-size: 32px;
|
||||
position: absolute;
|
||||
|
|
Loading…
Reference in a new issue