remove Boolean.fold - what's wrong with if-else?
parent
123d3a3c37
commit
40497b41e9
|
@ -42,20 +42,18 @@ object Auth extends LilaController {
|
|||
|
||||
def authenticateUser(u: UserModel, result: Option[String => Result] = None)(implicit ctx: Context): Fu[Result] = {
|
||||
implicit val req = ctx.req
|
||||
u.ipBan.fold(
|
||||
fuccess(Redirect(routes.Lobby.home)),
|
||||
api.saveAuthentication(u.id, ctx.mobileApiVersion) flatMap { sessionId =>
|
||||
negotiate(
|
||||
html = fuccess {
|
||||
val redirectTo = get("referrer").filter(goodReferrer) orElse
|
||||
req.session.get(api.AccessUri) getOrElse
|
||||
routes.Lobby.home.url
|
||||
result.fold(Redirect(redirectTo))(_(redirectTo))
|
||||
},
|
||||
api = _ => mobileUserOk(u, sessionId)
|
||||
) map authenticateCookie(sessionId)
|
||||
} recoverWith authRecovery
|
||||
)
|
||||
if (u.ipBan) fuccess(Redirect(routes.Lobby.home))
|
||||
else api.saveAuthentication(u.id, ctx.mobileApiVersion) flatMap { sessionId =>
|
||||
negotiate(
|
||||
html = fuccess {
|
||||
val redirectTo = get("referrer").filter(goodReferrer) orElse
|
||||
req.session.get(api.AccessUri) getOrElse
|
||||
routes.Lobby.home.url
|
||||
result.fold(Redirect(redirectTo))(_(redirectTo))
|
||||
},
|
||||
api = _ => mobileUserOk(u, sessionId)
|
||||
) map authenticateCookie(sessionId)
|
||||
} recoverWith authRecovery
|
||||
}
|
||||
|
||||
private def authenticateCookie(sessionId: String)(result: Result)(implicit req: RequestHeader) =
|
||||
|
@ -161,7 +159,10 @@ object Auth extends LilaController {
|
|||
else print.fold[Fu[MustConfirmEmail]](fuccess(YesBecausePrintMissing)) { fp =>
|
||||
api.recentByPrintExists(fp) flatMap { printFound =>
|
||||
if (printFound) fuccess(YesBecausePrintExists)
|
||||
else Env.security.ipTrust.isSuspicious(ip).map { _.fold(YesBecauseIpSusp, Nope) }
|
||||
else Env.security.ipTrust.isSuspicious(ip).map {
|
||||
case true => YesBecauseIpSusp
|
||||
case _ => Nope
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ object Challenge extends LilaController {
|
|||
} flatMap { res =>
|
||||
if (res.isDefined) jsonOkResult.fuccess
|
||||
else Env.bot.player.rematchAccept(id, me) flatMap {
|
||||
_.fold(jsonOkResult.fuccess, notFoundJson())
|
||||
case true => jsonOkResult.fuccess
|
||||
case _ => notFoundJson()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ object Challenge extends LilaController {
|
|||
implicit val req = ctx.req
|
||||
LilaCookie.cookie(
|
||||
AnonCookie.name,
|
||||
game.player(owner.fold(c.finalColor, !c.finalColor)).id,
|
||||
game.player(if (owner) c.finalColor else !c.finalColor).id,
|
||||
maxAge = AnonCookie.maxAge.some,
|
||||
httpOnly = false.some
|
||||
)
|
||||
|
@ -110,7 +111,8 @@ object Challenge extends LilaController {
|
|||
def apiDecline(id: String) = Scoped() { _ => me =>
|
||||
env.api.activeByIdFor(id, me) flatMap {
|
||||
case None => Env.bot.player.rematchDecline(id, me) flatMap {
|
||||
_.fold(jsonOkResult.fuccess, notFoundJson())
|
||||
case true => jsonOkResult.fuccess
|
||||
case _ => notFoundJson()
|
||||
}
|
||||
case Some(c) => env.api.decline(c) inject jsonOkResult
|
||||
}
|
||||
|
@ -153,7 +155,8 @@ object Challenge extends LilaController {
|
|||
lila.challenge.ChallengeDenied translated d
|
||||
}).fuccess
|
||||
case _ => env.api.sendRematchOf(g, me) map {
|
||||
_.fold(Ok, BadRequest(jsonError("Sorry, couldn't create the rematch.")))
|
||||
case true => Ok
|
||||
case _ => BadRequest(jsonError("Sorry, couldn't create the rematch."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,32 +10,32 @@ import lila.i18n.{ I18nKeys, I18nLangPicker, enLang }
|
|||
object Dasher extends LilaController {
|
||||
|
||||
private def translations(implicit ctx: Context) = lila.i18n.JsDump.keysToObject(
|
||||
ctx.isAnon.fold(
|
||||
(if (ctx.isAnon)
|
||||
List(
|
||||
I18nKeys.signIn,
|
||||
I18nKeys.signUp
|
||||
),
|
||||
I18nKeys.signIn,
|
||||
I18nKeys.signUp
|
||||
)
|
||||
else
|
||||
List(
|
||||
I18nKeys.profile,
|
||||
I18nKeys.inbox,
|
||||
I18nKeys.preferences,
|
||||
I18nKeys.logOut
|
||||
)
|
||||
) ::: List(
|
||||
I18nKeys.networkLagBetweenYouAndLichess,
|
||||
I18nKeys.timeToProcessAMoveOnLichessServer,
|
||||
I18nKeys.sound,
|
||||
I18nKeys.background,
|
||||
I18nKeys.light,
|
||||
I18nKeys.dark,
|
||||
I18nKeys.transparent,
|
||||
I18nKeys.backgroundImageUrl,
|
||||
I18nKeys.boardGeometry,
|
||||
I18nKeys.boardTheme,
|
||||
I18nKeys.boardSize,
|
||||
I18nKeys.pieceSet,
|
||||
I18nKeys.zenMode
|
||||
), lila.i18n.I18nDb.Site, ctx.lang
|
||||
)) ::: List(
|
||||
I18nKeys.networkLagBetweenYouAndLichess,
|
||||
I18nKeys.timeToProcessAMoveOnLichessServer,
|
||||
I18nKeys.sound,
|
||||
I18nKeys.background,
|
||||
I18nKeys.light,
|
||||
I18nKeys.dark,
|
||||
I18nKeys.transparent,
|
||||
I18nKeys.backgroundImageUrl,
|
||||
I18nKeys.boardGeometry,
|
||||
I18nKeys.boardTheme,
|
||||
I18nKeys.boardSize,
|
||||
I18nKeys.pieceSet,
|
||||
I18nKeys.zenMode
|
||||
), lila.i18n.I18nDb.Site, ctx.lang
|
||||
) ++ lila.i18n.JsDump.keysToObject(
|
||||
// the language settings should never be in a totally foreign language
|
||||
List(I18nKeys.language),
|
||||
|
|
|
@ -22,10 +22,8 @@ private[controllers] trait ForumController extends forum.Granter { self: LilaCon
|
|||
Env.team.api.owns(teamId, userId)
|
||||
|
||||
protected def CategGrantRead[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
|
||||
isGrantedRead(categSlug).fold(
|
||||
a,
|
||||
fuccess(Forbidden("You cannot access to this category"))
|
||||
)
|
||||
if (isGrantedRead(categSlug)) a
|
||||
else fuccess(Forbidden("You cannot access to this category"))
|
||||
|
||||
protected def CategGrantWrite[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
|
||||
isGrantedWrite(categSlug) flatMap { granted =>
|
||||
|
@ -35,9 +33,7 @@ private[controllers] trait ForumController extends forum.Granter { self: LilaCon
|
|||
|
||||
protected def CategGrantMod[A <: Result](categSlug: String)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
|
||||
isGrantedMod(categSlug) flatMap { granted =>
|
||||
(granted | isGranted(_.ModerateForum)) fold (
|
||||
a,
|
||||
fuccess(Forbidden("You cannot post to this category"))
|
||||
)
|
||||
if (granted | isGranted(_.ModerateForum)) a
|
||||
else fuccess(Forbidden("You cannot post to this category"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,10 @@ object ForumPost extends LilaController with ForumController {
|
|||
|
||||
def search(text: String, page: Int) = OpenBody { implicit ctx =>
|
||||
NotForKids {
|
||||
text.trim.isEmpty.fold(
|
||||
Redirect(routes.ForumCateg.index).fuccess,
|
||||
Env.forumSearch(text, page, isGranted(_.StaffForum), ctx.troll) map { paginator =>
|
||||
html.forum.search(text, paginator)
|
||||
}
|
||||
)
|
||||
if (text.trim.isEmpty) Redirect(routes.ForumCateg.index).fuccess
|
||||
else Env.forumSearch(text, page, isGranted(_.StaffForum), ctx.troll) map { paginator =>
|
||||
html.forum.search(text, paginator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@ object Insight extends LilaController {
|
|||
lila.user.UserRepo named username flatMap {
|
||||
_.fold(notFound) { u =>
|
||||
env.share.grant(u, ctx.me) flatMap {
|
||||
_.fold(f(u), fuccess(Forbidden(html.insight.forbidden(u))))
|
||||
case true => f(u)
|
||||
case _ => fuccess(Forbidden(html.insight.forbidden(u)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,17 +121,17 @@ private[controllers] trait LilaController
|
|||
|
||||
protected def Secure[A](parser: BodyParser[A])(perm: Permission)(f: Context => UserModel => Fu[Result]): Action[A] =
|
||||
Auth(parser) { implicit ctx => me =>
|
||||
isGranted(perm).fold(f(ctx)(me), authorizationFailed)
|
||||
if (isGranted(perm)) f(ctx)(me) else authorizationFailed
|
||||
}
|
||||
|
||||
protected def SecureF(s: UserModel => Boolean)(f: Context => UserModel => Fu[Result]): Action[AnyContent] =
|
||||
Auth(BodyParsers.parse.anyContent) { implicit ctx => me =>
|
||||
s(me).fold(f(ctx)(me), authorizationFailed)
|
||||
if (s(me)) f(ctx)(me) else authorizationFailed
|
||||
}
|
||||
|
||||
protected def SecureBody[A](parser: BodyParser[A])(perm: Permission)(f: BodyContext[A] => UserModel => Fu[Result]): Action[A] =
|
||||
AuthBody(parser) { implicit ctx => me =>
|
||||
isGranted(perm).fold(f(ctx)(me), authorizationFailed)
|
||||
if (isGranted(perm)) f(ctx)(me) else authorizationFailed
|
||||
}
|
||||
|
||||
protected def SecureBody(perm: Permission.type => Permission)(f: BodyContext[_] => UserModel => Fu[Result]): Action[AnyContent] =
|
||||
|
|
|
@ -26,25 +26,22 @@ object Accuracy {
|
|||
startedAtTurn = pov.game.chess.startedAtTurn
|
||||
)
|
||||
|
||||
def diffsList(pov: PovLike, analysis: Analysis): List[Int] =
|
||||
(pov.color == pov.startColor).fold(
|
||||
Info.start(pov.startedAtTurn) :: analysis.infos,
|
||||
analysis.infos
|
||||
).grouped(2).foldLeft(List[Int]()) {
|
||||
case (list, List(i1, i2)) =>
|
||||
makeDiff.lift(i1.cp, i1.mate, i2.cp, i2.mate).fold(list) { diff =>
|
||||
(if (pov.color.white) -diff else diff).max(0) :: list
|
||||
}
|
||||
case (list, _) => list
|
||||
}.reverse
|
||||
def diffsList(pov: PovLike, analysis: Analysis): List[Int] = {
|
||||
if (pov.color == pov.startColor) Info.start(pov.startedAtTurn) :: analysis.infos
|
||||
else analysis.infos
|
||||
}.grouped(2).foldLeft(List[Int]()) {
|
||||
case (list, List(i1, i2)) =>
|
||||
makeDiff.lift(i1.cp, i1.mate, i2.cp, i2.mate).fold(list) { diff =>
|
||||
(if (pov.color.white) -diff else diff).max(0) :: list
|
||||
}
|
||||
case (list, _) => list
|
||||
}.reverse
|
||||
|
||||
def prevColorInfos(pov: PovLike, analysis: Analysis): List[Info] = {
|
||||
(pov.color == pov.startColor).fold(
|
||||
Info.start(pov.startedAtTurn) :: analysis.infos,
|
||||
analysis.infos
|
||||
).zipWithIndex.collect {
|
||||
case (e, i) if (i % 2) == 0 => e
|
||||
}
|
||||
if (pov.color == pov.startColor) Info.start(pov.startedAtTurn) :: analysis.infos
|
||||
else analysis.infos
|
||||
}.zipWithIndex.collect {
|
||||
case (e, i) if (i % 2) == 0 => e
|
||||
}
|
||||
|
||||
def mean(pov: PovLike, analysis: Analysis): Option[Int] = {
|
||||
|
|
|
@ -45,10 +45,16 @@ private[api] final class GameApi(
|
|||
else $doc(
|
||||
G.playerUids -> user.id,
|
||||
G.status $gte chess.Status.Mate.id,
|
||||
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
|
||||
G.analysed -> analysed.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
}
|
||||
)
|
||||
} ++ $doc(
|
||||
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
|
||||
G.rated -> rated.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
}
|
||||
),
|
||||
projection = $empty,
|
||||
sort = $doc(G.createdAt -> -1),
|
||||
|
@ -57,7 +63,10 @@ private[api] final class GameApi(
|
|||
nbResults =
|
||||
if (~playing) gameCache.nbPlaying(user.id)
|
||||
else fuccess {
|
||||
rated.fold(user.count.game)(_.fold(user.count.rated, user.count.casual))
|
||||
rated.fold(user.count.game) {
|
||||
case true => user.count.rated
|
||||
case _ => user.count.casual
|
||||
}
|
||||
}
|
||||
),
|
||||
currentPage = page,
|
||||
|
@ -91,10 +100,16 @@ private[api] final class GameApi(
|
|||
if (~playing) lila.game.Query.nowPlayingVs(users._1.id, users._2.id)
|
||||
else lila.game.Query.opponents(users._1, users._2) ++ $doc(
|
||||
G.status $gte chess.Status.Mate.id,
|
||||
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
|
||||
G.analysed -> analysed.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
}
|
||||
)
|
||||
} ++ $doc(
|
||||
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
|
||||
G.rated -> rated.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
}
|
||||
),
|
||||
projection = $empty,
|
||||
sort = $doc(G.createdAt -> -1),
|
||||
|
@ -128,10 +143,16 @@ private[api] final class GameApi(
|
|||
if (~playing) lila.game.Query.nowPlayingVs(userIds)
|
||||
else lila.game.Query.opponents(userIds) ++ $doc(
|
||||
G.status $gte chess.Status.Mate.id,
|
||||
G.analysed -> analysed.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false)))
|
||||
G.analysed -> analysed.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
}
|
||||
)
|
||||
} ++ $doc(
|
||||
G.rated -> rated.map(_.fold[BSONValue](BSONBoolean(true), $doc("$exists" -> false))),
|
||||
G.rated -> rated.map[BSONValue] {
|
||||
case true => BSONBoolean(true)
|
||||
case _ => $doc("$exists" -> false)
|
||||
},
|
||||
G.createdAt $gte since
|
||||
),
|
||||
projection = $empty,
|
||||
|
|
|
@ -48,9 +48,9 @@ final class BotPlayer(
|
|||
GameRepo game id map {
|
||||
_.flatMap(Pov(_, me)).filter(_.opponent.isOfferingRematch) ?? { pov =>
|
||||
// delay so it feels more natural
|
||||
lila.common.Future.delay(accept.fold(100, 2000) millis) {
|
||||
lila.common.Future.delay(if (accept) 100.millis else 2.seconds) {
|
||||
fuccess {
|
||||
roundMap ! Tell(pov.gameId, accept.fold(RematchYes, RematchNo)(pov.playerId))
|
||||
roundMap ! Tell(pov.gameId, (if (accept) RematchYes else RematchNo)(pov.playerId))
|
||||
}
|
||||
}(system)
|
||||
true
|
||||
|
|
|
@ -57,7 +57,7 @@ final class BotJsonView(
|
|||
|
||||
def chatLine(username: String, text: String, player: Boolean) = Json.obj(
|
||||
"type" -> "chatLine",
|
||||
"room" -> player.fold("player", "spectator"),
|
||||
"room" -> (if (player) "player" else "spectator"),
|
||||
"username" -> username,
|
||||
"text" -> text
|
||||
)
|
||||
|
|
|
@ -83,7 +83,7 @@ object Challenge {
|
|||
}
|
||||
|
||||
case class Rating(int: Int, provisional: Boolean) {
|
||||
def show = s"$int${provisional.fold("?", "")}"
|
||||
def show = s"$int${if (provisional) "?" else ""}"
|
||||
}
|
||||
object Rating {
|
||||
def apply(p: lila.rating.Perf): Rating = Rating(p.intRating, p.provisional)
|
||||
|
@ -154,10 +154,9 @@ object Challenge {
|
|||
_id = randomId,
|
||||
status = Status.Created,
|
||||
variant = variant,
|
||||
initialFen = (variant == FromPosition).fold(
|
||||
initialFen,
|
||||
!variant.standardInitialPosition option FEN(variant.initialFen)
|
||||
),
|
||||
initialFen =
|
||||
if (variant == FromPosition) initialFen
|
||||
else !variant.standardInitialPosition option FEN(variant.initialFen),
|
||||
timeControl = timeControl,
|
||||
mode = finalMode,
|
||||
colorChoice = colorChoice,
|
||||
|
|
|
@ -36,8 +36,8 @@ private[challenge] final class Joiner(onStart: String => Unit) {
|
|||
chess = chessGame,
|
||||
whitePlayer = Player.make(chess.White, c.finalColor.fold(challengerUser, destUser), perfPicker),
|
||||
blackPlayer = Player.make(chess.Black, c.finalColor.fold(destUser, challengerUser), perfPicker),
|
||||
mode = chessGame.board.variant.fromPosition.fold(Mode.Casual, c.mode),
|
||||
source = chessGame.board.variant.fromPosition.fold(Source.Position, Source.Friend),
|
||||
mode = if (chessGame.board.variant.fromPosition) Mode.Casual else c.mode,
|
||||
source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Friend,
|
||||
daysPerTurn = c.daysPerTurn,
|
||||
pgnImport = None
|
||||
).copy(id = c.id).|> { g =>
|
||||
|
|
|
@ -29,10 +29,9 @@ case class UserChat(
|
|||
|
||||
val loginRequired = true
|
||||
|
||||
def forUser(u: Option[User]) = u.??(_.troll).fold(
|
||||
this,
|
||||
copy(lines = lines filterNot (_.troll))
|
||||
)
|
||||
def forUser(u: Option[User]): UserChat =
|
||||
if (u.??(_.troll)) this
|
||||
else copy(lines = lines filterNot (_.troll))
|
||||
|
||||
def markDeleted(u: User) = copy(
|
||||
lines = lines.map { l =>
|
||||
|
@ -64,13 +63,12 @@ case class MixedChat(
|
|||
|
||||
val loginRequired = false
|
||||
|
||||
def forUser(u: Option[User]) = u.??(_.troll).fold(
|
||||
this,
|
||||
copy(lines = lines filter {
|
||||
def forUser(u: Option[User]): MixedChat =
|
||||
if (u.??(_.troll)) this
|
||||
else copy(lines = lines filter {
|
||||
case l: UserLine => !l.troll
|
||||
case l: PlayerLine => true
|
||||
})
|
||||
)
|
||||
|
||||
def mapLines(f: Line => Line) = copy(lines = lines map f)
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ object Form {
|
|||
def trueish(v: Any) = v == 1 || v == "1" || v == "true" || v == "on" || v == "yes"
|
||||
|
||||
private def pluralize(pattern: String, nb: Int) =
|
||||
pattern.replace("{s}", (nb != 1).fold("s", ""))
|
||||
pattern.replace("{s}", if (nb == 1) "" else "s")
|
||||
|
||||
object formatter {
|
||||
def stringFormatter[A](from: A => String, to: String => A): Formatter[A] = new Formatter[A] {
|
||||
|
|
|
@ -15,8 +15,6 @@ final class PimpedBoolean(private val self: Boolean) extends AnyVal {
|
|||
|
||||
def !(f: => Unit) = if (self) f
|
||||
|
||||
def fold[A](t: => A, f: => A): A = if (self) t else f
|
||||
|
||||
def ?[X](t: => X) = new { def |(f: => X) = if (self) t else f }
|
||||
|
||||
def option[A](a: => A): Option[A] = if (self) Some(a) else None
|
||||
|
@ -64,4 +62,4 @@ final class PimpedDouble(private val self: Double) extends AnyVal {
|
|||
def atMost(topValue: Double): Double = min(self, topValue)
|
||||
|
||||
def squeeze(bottom: Double, top: Double): Double = max(min(self, top), bottom)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ case class PlayerAggregateAssessment(
|
|||
(percentCheatingGames(10) || percentLikelyCheatingGames(20))
|
||||
|
||||
val reportable: Boolean = isWorthLookingAt &&
|
||||
(cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (isNewRatedUser.fold(2, 4))) &&
|
||||
(cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (if (isNewRatedUser) 2 else 4)) &&
|
||||
(percentCheatingGames(5) || percentLikelyCheatingGames(10))
|
||||
|
||||
val bannable: Boolean = (relatedCheatersCount == relatedUsersCount) && relatedUsersCount >= 1
|
||||
|
|
|
@ -17,18 +17,18 @@ case class Categ(
|
|||
|
||||
def id = _id
|
||||
|
||||
def nbTopics(troll: Boolean): Int = troll.fold(nbTopicsTroll, nbTopics)
|
||||
def nbPosts(troll: Boolean): Int = troll.fold(nbPostsTroll, nbPosts)
|
||||
def lastPostId(troll: Boolean): String = troll.fold(lastPostIdTroll, lastPostId)
|
||||
def nbTopics(troll: Boolean): Int = if (troll) nbTopicsTroll else nbTopics
|
||||
def nbPosts(troll: Boolean): Int = if (troll) nbPostsTroll else nbPosts
|
||||
def lastPostId(troll: Boolean): String = if (troll) lastPostIdTroll else lastPostId
|
||||
|
||||
def isStaff = slug == Categ.staffId
|
||||
|
||||
def isTeam = team.nonEmpty
|
||||
|
||||
def withTopic(post: Post): Categ = copy(
|
||||
nbTopics = post.troll.fold(nbTopics, nbTopics + 1),
|
||||
nbPosts = post.troll.fold(nbPosts, nbPosts + 1),
|
||||
lastPostId = post.troll.fold(lastPostId, post.id),
|
||||
nbTopics = if (post.troll) nbTopics else nbTopics + 1,
|
||||
nbPosts = if (post.troll) nbPosts else nbPosts + 1,
|
||||
lastPostId = if (post.troll) lastPostId else post.id,
|
||||
nbTopicsTroll = nbTopicsTroll + 1,
|
||||
nbPostsTroll = nbPostsTroll + 1,
|
||||
lastPostIdTroll = post.id
|
||||
|
|
|
@ -11,10 +11,7 @@ trait Granter {
|
|||
protected def userOwnsTeam(teamId: String, userId: String): Fu[Boolean]
|
||||
|
||||
def isGrantedRead(categSlug: String)(implicit ctx: UserContext): Boolean =
|
||||
(categSlug == Categ.staffId).fold(
|
||||
ctx.me exists Master(Permission.StaffForum),
|
||||
true
|
||||
)
|
||||
categSlug != Categ.staffId || ctx.me.exists(Master(Permission.StaffForum))
|
||||
|
||||
def isGrantedWrite(categSlug: String)(implicit ctx: UserContext): Fu[Boolean] =
|
||||
ctx.me.filter(isOldEnoughToForum) ?? { me =>
|
||||
|
|
|
@ -56,17 +56,16 @@ final class PostApi(
|
|||
(!categ.quiet ?? (indexer ! InsertPost(post))) >>-
|
||||
(!categ.quiet ?? env.recent.invalidate) >>-
|
||||
ctx.userId.?? { userId =>
|
||||
shutup ! post.isTeam.fold(
|
||||
lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, post.text),
|
||||
lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, post.text)
|
||||
)
|
||||
shutup ! {
|
||||
if (post.isTeam) lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, post.text)
|
||||
else lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, post.text)
|
||||
}
|
||||
} >>- {
|
||||
(ctx.userId ifFalse post.troll ifFalse categ.quiet) ?? { userId =>
|
||||
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|>(prop =>
|
||||
post.isStaff.fold(
|
||||
prop toStaffFriendsOf userId,
|
||||
prop toFollowersOf userId toUsers topicUserIds exceptUser userId
|
||||
))
|
||||
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|> { prop =>
|
||||
if (post.isStaff) prop toStaffFriendsOf userId
|
||||
else prop toFollowersOf userId toUsers topicUserIds exceptUser userId
|
||||
}
|
||||
}
|
||||
lila.mon.forum.post.create()
|
||||
mentionNotifier.notifyMentionedUsers(post, topic)
|
||||
|
@ -187,14 +186,12 @@ final class PostApi(
|
|||
view ← optionT(view(post))
|
||||
_ ← optionT(for {
|
||||
first ← PostRepo.isFirstPost(view.topic.id, view.post.id)
|
||||
_ ← first.fold(
|
||||
env.topicApi.delete(view.categ, view.topic),
|
||||
env.postColl.remove(view.post) >>
|
||||
(env.topicApi denormalize view.topic) >>
|
||||
(env.categApi denormalize view.categ) >>-
|
||||
env.recent.invalidate >>-
|
||||
(indexer ! RemovePost(post.id))
|
||||
)
|
||||
_ ← if (first) env.topicApi.delete(view.categ, view.topic)
|
||||
else env.postColl.remove(view.post) >>
|
||||
(env.topicApi denormalize view.topic) >>
|
||||
(env.categApi denormalize view.categ) >>-
|
||||
env.recent.invalidate >>-
|
||||
(indexer ! RemovePost(post.id))
|
||||
_ ← MasterGranter(_.ModerateForum)(mod) ?? modLog.deletePost(mod.id, post.userId, post.author, post.ip,
|
||||
text = "%s / %s / %s".format(view.categ.name, view.topic.name, post.text))
|
||||
} yield true.some)
|
||||
|
|
|
@ -6,7 +6,7 @@ import reactivemongo.api.{ CursorProducer, ReadPreference }
|
|||
|
||||
object PostRepo extends PostRepo(false) {
|
||||
|
||||
def apply(troll: Boolean): PostRepo = troll.fold(PostRepoTroll, PostRepo)
|
||||
def apply(troll: Boolean): PostRepo = if (troll) PostRepoTroll else PostRepo
|
||||
}
|
||||
|
||||
object PostRepoTroll extends PostRepo(true)
|
||||
|
@ -18,7 +18,7 @@ sealed abstract class PostRepo(troll: Boolean) {
|
|||
// dirty
|
||||
private val coll = Env.current.postColl
|
||||
|
||||
private val trollFilter = troll.fold($empty, $doc("troll" -> false))
|
||||
private val trollFilter = !troll ?? $doc("troll" -> false)
|
||||
|
||||
def byIds(ids: List[Post.ID]) = coll.byIds[Post](ids)
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ private[forum] final class Recent(
|
|||
(user.map(_.id) ?? getTeams).map { teamIds =>
|
||||
user.fold("en")(_.langs.mkString(",")) :: {
|
||||
(user.??(_.troll) ?? List("[troll]")) :::
|
||||
(user ?? MasterGranter(Permission.StaffForum)).fold(staffCategIds, publicCategIds) :::
|
||||
(if (user ?? MasterGranter(Permission.StaffForum)) staffCategIds else publicCategIds) :::
|
||||
(teamIds.map(teamSlug)(scala.collection.breakOut): List[String])
|
||||
} mkString ";"
|
||||
}
|
||||
|
|
|
@ -24,10 +24,10 @@ case class Topic(
|
|||
|
||||
def id = _id
|
||||
|
||||
def updatedAt(troll: Boolean): DateTime = troll.fold(updatedAtTroll, updatedAt)
|
||||
def nbPosts(troll: Boolean): Int = troll.fold(nbPostsTroll, nbPosts)
|
||||
def updatedAt(troll: Boolean): DateTime = if (troll) updatedAtTroll else updatedAt
|
||||
def nbPosts(troll: Boolean): Int = if (troll) nbPostsTroll else nbPosts
|
||||
def nbReplies(troll: Boolean): Int = nbPosts(troll) - 1
|
||||
def lastPostId(troll: Boolean): String = troll.fold(lastPostIdTroll, lastPostId)
|
||||
def lastPostId(troll: Boolean): String = if (troll) lastPostIdTroll else lastPostId
|
||||
|
||||
def open = !closed
|
||||
def visibleOnHome = !hidden
|
||||
|
@ -37,9 +37,9 @@ case class Topic(
|
|||
def isStaff = categId == Categ.staffId
|
||||
|
||||
def withPost(post: Post): Topic = copy(
|
||||
nbPosts = post.troll.fold(nbPosts, nbPosts + 1),
|
||||
lastPostId = post.troll.fold(lastPostId, post.id),
|
||||
updatedAt = post.troll.fold(updatedAt, post.createdAt),
|
||||
nbPosts = if (post.troll) nbPosts else nbPosts + 1,
|
||||
lastPostId = if (post.troll) lastPostId else post.id,
|
||||
updatedAt = if (post.troll) updatedAt else post.createdAt,
|
||||
nbPostsTroll = nbPostsTroll + 1,
|
||||
lastPostIdTroll = post.id,
|
||||
updatedAtTroll = post.createdAt
|
||||
|
@ -54,7 +54,7 @@ object Topic {
|
|||
|
||||
def nameToId(name: String) = (lila.common.String slugify name) |> { slug =>
|
||||
// if most chars are not latin, go for random slug
|
||||
(slug.size > (name.size / 2)).fold(slug, Random nextString 8)
|
||||
if (slug.size > (name.size / 2)) slug else Random nextString 8
|
||||
}
|
||||
|
||||
val idSize = 8
|
||||
|
|
|
@ -70,15 +70,17 @@ private[forum] final class TopicApi(
|
|||
(!categ.quiet ?? (indexer ! InsertPost(post))) >>-
|
||||
(!categ.quiet ?? env.recent.invalidate) >>-
|
||||
ctx.userId.?? { userId =>
|
||||
val text = topic.name + " " + post.text
|
||||
shutup ! post.isTeam.fold(
|
||||
lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, text),
|
||||
lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, text)
|
||||
)
|
||||
val text = s"${topic.name} ${post.text}"
|
||||
shutup ! {
|
||||
if (post.isTeam) lila.hub.actorApi.shutup.RecordTeamForumMessage(userId, text)
|
||||
else lila.hub.actorApi.shutup.RecordPublicForumMessage(userId, text)
|
||||
}
|
||||
} >>- {
|
||||
(ctx.userId ifFalse post.troll ifFalse categ.quiet) ?? { userId =>
|
||||
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|>(prop =>
|
||||
post.isStaff.fold(prop toStaffFriendsOf userId, prop toFollowersOf userId))
|
||||
timeline ! Propagate(ForumPost(userId, topic.id.some, topic.name, post.id)).|> { prop =>
|
||||
if (post.isStaff) prop toStaffFriendsOf userId
|
||||
else prop toFollowersOf userId
|
||||
}
|
||||
}
|
||||
lila.mon.forum.post.create()
|
||||
} >>- {
|
||||
|
|
|
@ -4,7 +4,7 @@ import lila.db.dsl._
|
|||
|
||||
object TopicRepo extends TopicRepo(false) {
|
||||
|
||||
def apply(troll: Boolean): TopicRepo = troll.fold(TopicRepoTroll, TopicRepo)
|
||||
def apply(troll: Boolean): TopicRepo = if (troll) TopicRepoTroll else TopicRepo
|
||||
}
|
||||
|
||||
object TopicRepoTroll extends TopicRepo(true)
|
||||
|
@ -16,7 +16,7 @@ sealed abstract class TopicRepo(troll: Boolean) {
|
|||
// dirty
|
||||
private val coll = Env.current.topicColl
|
||||
|
||||
private val trollFilter = troll.fold($empty, $doc("troll" -> false))
|
||||
private val trollFilter = !troll ?? $doc("troll" -> false)
|
||||
private val notStickyQuery = $doc("sticky" $ne true)
|
||||
private val stickyQuery = $doc("sticky" -> true)
|
||||
|
||||
|
@ -47,11 +47,9 @@ sealed abstract class TopicRepo(troll: Boolean) {
|
|||
def nextSlug(categ: Categ, name: String, it: Int = 1): Fu[String] = {
|
||||
val slug = Topic.nameToId(name) + ~(it != 1).option("-" + it)
|
||||
// also take troll topic into accounts
|
||||
TopicRepoTroll.byTree(categ.slug, slug) flatMap {
|
||||
_.isDefined.fold(
|
||||
nextSlug(categ, name, it + 1),
|
||||
fuccess(slug)
|
||||
)
|
||||
TopicRepoTroll.byTree(categ.slug, slug) flatMap { found =>
|
||||
if (found.isDefined) nextSlug(categ, name, it + 1)
|
||||
else fuccess(slug)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,10 +232,10 @@ case class Game(
|
|||
blackPlayer = f(blackPlayer)
|
||||
)
|
||||
|
||||
def start = started.fold(this, copy(
|
||||
def start = if (started) this else copy(
|
||||
status = Status.Started,
|
||||
mode = Mode(mode.rated && userIds.distinct.size == 2)
|
||||
))
|
||||
)
|
||||
|
||||
def correspondenceClock: Option[CorrespondenceClock] = daysPerTurn map { days =>
|
||||
val increment = days * 24 * 60 * 60
|
||||
|
|
|
@ -24,7 +24,7 @@ final class PgnDump(
|
|||
tagsFuture map { ts =>
|
||||
val turns = flags.moves ?? {
|
||||
val fenSituation = ts.fen.map(_.value) flatMap Forsyth.<<<
|
||||
val moves2 = fenSituation.??(_.situation.color.black).fold(".." +: game.pgnMoves, game.pgnMoves)
|
||||
val moves2 = if (fenSituation.exists(_.situation.color.black)) ".." +: game.pgnMoves else game.pgnMoves
|
||||
makeTurns(
|
||||
moves2,
|
||||
fenSituation.map(_.fullMoveNumber) | 1,
|
||||
|
|
|
@ -101,7 +101,7 @@ object Query {
|
|||
def checkableOld = F.checkAt $lt DateTime.now.minusHours(1)
|
||||
|
||||
def variant(v: chess.variant.Variant) =
|
||||
$doc(F.variant -> v.standard.fold[BSONValue]($exists(false), $int(v.id)))
|
||||
$doc(F.variant -> (if (v.standard) $exists(false) else $int(v.id)))
|
||||
|
||||
lazy val variantStandard = variant(chess.variant.Standard)
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ private final class AggregationPipeline {
|
|||
MaterialRange.reversedButEqualAndLast.foldLeft[BSONValue](BSONInteger(MaterialRange.Up4.id)) {
|
||||
case (acc, mat) => $doc(
|
||||
"$cond" -> $arr(
|
||||
$doc(mat.negative.fold("$lt", "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)),
|
||||
$doc((if (mat.negative) "$lt" else "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)),
|
||||
mat.id,
|
||||
acc
|
||||
)
|
||||
|
|
|
@ -29,7 +29,7 @@ object Color {
|
|||
|
||||
object Random extends Color("random") {
|
||||
|
||||
def resolve = nextBoolean.fold(White, Black).resolve
|
||||
def resolve = chess.Color(nextBoolean)
|
||||
|
||||
def unary_! = this
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ object Seek {
|
|||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
implicit val lobbyPerfBSONHandler = new BSONHandler[BSONInteger, LobbyPerf] {
|
||||
def read(b: BSONInteger) = LobbyPerf(b.value.abs, b.value < 0)
|
||||
def write(x: LobbyPerf) = BSONInteger(x.rating * x.provisional.fold(-1, 1))
|
||||
def write(x: LobbyPerf) = BSONInteger(x.rating * (if (x.provisional) -1 else 1))
|
||||
}
|
||||
private[lobby] implicit val lobbyUserBSONHandler = Macros.handler[LobbyUser]
|
||||
private[lobby] implicit val seekBSONHandler = Macros.handler[Seek]
|
||||
|
|
|
@ -57,18 +57,20 @@ case class Thread(
|
|||
|
||||
def hasUser(user: User) = userIds contains user.id
|
||||
|
||||
def otherUserId(user: User) = isCreator(user).fold(invitedId, creatorId)
|
||||
def otherUserId(user: User) = if (isCreator(user)) invitedId else creatorId
|
||||
|
||||
def visibleOtherUserId(user: User) =
|
||||
isCreator(user).fold(invitedId, asMod.fold(Thread.lichess, creatorId))
|
||||
if (isCreator(user)) invitedId
|
||||
else if (asMod) Thread.lichess
|
||||
else creatorId
|
||||
|
||||
def senderOf(post: Post) = post.isByCreator.fold(creatorId, invitedId)
|
||||
def senderOf(post: Post) = if (post.isByCreator) creatorId else invitedId
|
||||
|
||||
def visibleSenderOf(post: Post) =
|
||||
if (post.isByCreator && asMod) Thread.lichess
|
||||
else senderOf(post)
|
||||
|
||||
def receiverOf(post: Post) = post.isByCreator.fold(invitedId, creatorId)
|
||||
def receiverOf(post: Post) = if (post.isByCreator) invitedId else creatorId
|
||||
|
||||
def visibleReceiverOf(post: Post) =
|
||||
if (!post.isByCreator && asMod) Thread.lichess
|
||||
|
|
|
@ -42,8 +42,8 @@ final class Gamify(
|
|||
|
||||
private def buildHistoryAfter(afterYear: Int, afterMonth: Int, until: DateTime): Funit =
|
||||
(afterYear to until.getYear).flatMap { year =>
|
||||
((year == afterYear).fold(afterMonth + 1, 1) to
|
||||
(year == until.getYear).fold(until.getMonthOfYear, 12)).map { month =>
|
||||
((if (year == afterYear) afterMonth + 1 else 1) to
|
||||
(if (year == until.getYear) until.getMonthOfYear else 12)).map { month =>
|
||||
mixedLeaderboard(
|
||||
after = new DateTime(year, month, 1, 0, 0).pp("compute mod history"),
|
||||
before = new DateTime(year, month, 1, 0, 0).plusMonths(1).some
|
||||
|
|
|
@ -24,9 +24,9 @@ case class PerfStat(
|
|||
val thisYear = pov.game.createdAt isAfter DateTime.now.minusYears(1)
|
||||
copy(
|
||||
highest = RatingAt.agg(highest, pov, 1),
|
||||
lowest = thisYear.fold(RatingAt.agg(lowest, pov, -1), lowest),
|
||||
bestWins = (~pov.win).fold(bestWins.agg(pov, -1), bestWins),
|
||||
worstLosses = (thisYear && ~pov.loss).fold(worstLosses.agg(pov, 1), worstLosses),
|
||||
lowest = if (thisYear) RatingAt.agg(lowest, pov, -1) else lowest,
|
||||
bestWins = if (~pov.win) bestWins.agg(pov, -1) else bestWins,
|
||||
worstLosses = if (thisYear && ~pov.loss) worstLosses.agg(pov, 1) else worstLosses,
|
||||
count = count(pov),
|
||||
resultStreak = resultStreak agg pov,
|
||||
playStreak = playStreak agg pov
|
||||
|
@ -94,7 +94,7 @@ object Streaks {
|
|||
val init = Streaks(Streak.init, Streak.init)
|
||||
}
|
||||
case class Streak(v: Int, from: Option[RatingAt], to: Option[RatingAt]) {
|
||||
def apply(cont: Boolean, pov: Pov)(v: Int) = cont.fold(inc(pov, v), Streak.init)
|
||||
def apply(cont: Boolean, pov: Pov)(v: Int) = if (cont) inc(pov, v) else Streak.init
|
||||
private def inc(pov: Pov, by: Int) = copy(
|
||||
v = v + by,
|
||||
from = from orElse pov.player.rating.map { RatingAt(_, pov.game.createdAt, pov.gameId) },
|
||||
|
@ -121,20 +121,20 @@ case class Count(
|
|||
) {
|
||||
def apply(pov: Pov) = copy(
|
||||
all = all + 1,
|
||||
rated = rated + pov.game.rated.fold(1, 0),
|
||||
win = win + pov.win.contains(true).fold(1, 0),
|
||||
loss = loss + pov.win.contains(false).fold(1, 0),
|
||||
draw = draw + pov.win.isEmpty.fold(1, 0),
|
||||
tour = tour + pov.game.isTournament.fold(1, 0),
|
||||
berserk = berserk + pov.player.berserk.fold(1, 0),
|
||||
rated = rated + (if (pov.game.rated) 1 else 0),
|
||||
win = win + (if (pov.win.contains(true)) 1 else 0),
|
||||
loss = loss + (if (pov.win.contains(false)) 1 else 0),
|
||||
draw = draw + (if (pov.win.isEmpty) 1 else 0),
|
||||
tour = tour + (if (pov.game.isTournament) 1 else 0),
|
||||
berserk = berserk + (if (pov.player.berserk) 1 else 0),
|
||||
opAvg = pov.opponent.stableRating.fold(opAvg)(opAvg.agg),
|
||||
seconds = seconds + (pov.game.durationSeconds match {
|
||||
case Some(s) if s <= 3 * 60 * 60 => s
|
||||
case _ => 0
|
||||
}),
|
||||
disconnects = disconnects + {
|
||||
~pov.loss && pov.game.status == chess.Status.Timeout
|
||||
}.fold(1, 0)
|
||||
if (~pov.loss && pov.game.status == chess.Status.Timeout) 1 else 0
|
||||
}
|
||||
)
|
||||
}
|
||||
object Count {
|
||||
|
|
|
@ -33,8 +33,8 @@ private final class GameStarter(
|
|||
(perfs.get(p1.userId) |@| perfs.get(p2.userId)).tupled ?? {
|
||||
case (perf1, perf2) => for {
|
||||
p1White <- UserRepo.firstGetsWhite(p1.userId, p2.userId)
|
||||
(whitePerf, blackPerf) = p1White.fold(perf1 -> perf2, perf2 -> perf1)
|
||||
(whiteMember, blackMember) = p1White.fold(p1 -> p2, p2 -> p1)
|
||||
(whitePerf, blackPerf) = if (p1White) perf1 -> perf2 else perf2 -> perf1
|
||||
(whiteMember, blackMember) = if (p1White) p1 -> p2 else p2 -> p1
|
||||
game = makeGame(
|
||||
pool,
|
||||
whiteMember.userId -> whitePerf,
|
||||
|
|
|
@ -108,19 +108,19 @@ object DataForm {
|
|||
object PrefData {
|
||||
def apply(pref: Pref): PrefData = PrefData(
|
||||
display = DisplayData(
|
||||
highlight = pref.highlight.fold(1, 0),
|
||||
destination = pref.destination.fold(1, 0),
|
||||
highlight = if (pref.highlight) 1 else 0,
|
||||
destination = if (pref.destination) 1 else 0,
|
||||
animation = pref.animation,
|
||||
coords = pref.coords,
|
||||
replay = pref.replay,
|
||||
captured = pref.captured.fold(1, 0),
|
||||
captured = if (pref.captured) 1 else 0,
|
||||
blindfold = pref.blindfold,
|
||||
zen = pref.zen.some,
|
||||
pieceNotation = pref.pieceNotation.some
|
||||
),
|
||||
behavior = BehaviorData(
|
||||
moveEvent = pref.moveEvent.some,
|
||||
premove = pref.premove.fold(1, 0),
|
||||
premove = if (pref.premove) 1 else 0,
|
||||
takeback = pref.takeback,
|
||||
autoQueen = pref.autoQueen,
|
||||
autoThreefold = pref.autoThreefold,
|
||||
|
@ -130,9 +130,9 @@ object DataForm {
|
|||
rookCastle = pref.rookCastle.some
|
||||
),
|
||||
clockTenths = pref.clockTenths,
|
||||
clockBar = pref.clockBar.fold(1, 0),
|
||||
clockSound = pref.clockSound.fold(1, 0),
|
||||
follow = pref.follow.fold(1, 0),
|
||||
clockBar = if (pref.clockBar) 1 else 0,
|
||||
clockSound = if (pref.clockSound) 1 else 0,
|
||||
follow = if (pref.follow) 1 else 0,
|
||||
challenge = pref.challenge,
|
||||
message = pref.message,
|
||||
studyInvite = pref.studyInvite.some,
|
||||
|
|
|
@ -3,13 +3,13 @@ package lila.puzzle
|
|||
case class AggregateVote(up: Int, down: Int, nb: Int, ratio: Int) {
|
||||
|
||||
def add(v: Boolean) = copy(
|
||||
up = up + v.fold(1, 0),
|
||||
down = down + v.fold(0, 1)
|
||||
up = up + (if (v) 1 else 0),
|
||||
down = down + (if (v) 0 else 1)
|
||||
).computeNbAndRatio
|
||||
|
||||
def change(from: Boolean, to: Boolean) = if (from == to) this else copy(
|
||||
up = up + to.fold(1, -1),
|
||||
down = down + to.fold(-1, 1)
|
||||
up = up + (if (to) 1 else -1),
|
||||
down = down + (if (to) -1 else 1)
|
||||
).computeNbAndRatio
|
||||
|
||||
def count = up + down
|
||||
|
|
|
@ -51,10 +51,10 @@ private final class GameJson(
|
|||
"color" -> p.color.name
|
||||
)
|
||||
}),
|
||||
"treeParts" -> onlyLast.fold(
|
||||
tree.mainlineNodeList.lastOption.map(minimalNodeJsonWriter.writes),
|
||||
partitionTreeJsonWriter.writes(tree).some
|
||||
)
|
||||
"treeParts" -> {
|
||||
if (onlyLast) tree.mainlineNodeList.lastOption.map(minimalNodeJsonWriter.writes)
|
||||
else partitionTreeJsonWriter.writes(tree).some
|
||||
}
|
||||
).add("clock", game.clock.map(_.config.show))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ private object RelayFetch {
|
|||
}
|
||||
|
||||
def maxChapters(relay: Relay) =
|
||||
lila.study.Study.maxChapters * relay.official.fold(2, 1)
|
||||
lila.study.Study.maxChapters * (if (relay.official) 2 else 1)
|
||||
|
||||
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
|
||||
private val cache: Cache[Upstream, GamesSeenBy] = Scaffeine()
|
||||
|
|
|
@ -83,7 +83,7 @@ final class JsonView(
|
|||
"animationDuration" -> animationDuration(pov, pref),
|
||||
"coords" -> pref.coords,
|
||||
"replay" -> pref.replay,
|
||||
"autoQueen" -> (pov.game.variant == chess.variant.Antichess).fold(Pref.AutoQueen.NEVER, pref.autoQueen),
|
||||
"autoQueen" -> (if (pov.game.variant == chess.variant.Antichess) Pref.AutoQueen.NEVER else pref.autoQueen),
|
||||
"clockTenths" -> pref.clockTenths,
|
||||
"moveEvent" -> pref.moveEvent
|
||||
).add("is3d" -> pref.is3d)
|
||||
|
@ -276,10 +276,10 @@ final class JsonView(
|
|||
}
|
||||
|
||||
private def animationDuration(pov: Pov, pref: Pref) = math.round {
|
||||
animationFactor(pref) * baseAnimationDuration.toMillis * pov.game.finished.fold(
|
||||
1,
|
||||
math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2))
|
||||
)
|
||||
animationFactor(pref) * baseAnimationDuration.toMillis * {
|
||||
if (pov.game.finished) 1
|
||||
else math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ import chess.format.{ Forsyth, FEN, Uci }
|
|||
import chess.{ MoveMetrics, Centis, Status, Color, MoveOrDrop }
|
||||
|
||||
import actorApi.round.{ HumanPlay, DrawNo, TooManyPlies, TakebackNo, ForecastPlay }
|
||||
import lila.hub.actorApi.round.BotPlay
|
||||
import akka.actor.ActorRef
|
||||
import lila.game.{ Game, Progress, Pov, UciMemo }
|
||||
import lila.hub.actorApi.round.BotPlay
|
||||
|
||||
private[round] final class Player(
|
||||
fishnetPlayer: lila.fishnet.Player,
|
||||
|
@ -73,17 +73,17 @@ private[round] final class Player(
|
|||
)(implicit proxy: GameProxy): Fu[Events] = {
|
||||
if (pov.game.hasAi) uciMemo.add(pov.game, moveOrDrop)
|
||||
notifyMove(moveOrDrop, progress.game)
|
||||
progress.game.finished.fold(
|
||||
moveFinish(progress.game, pov.color) dmap { progress.events ::: _ }, {
|
||||
if (progress.game.playableByAi) requestFishnet(progress.game, round)
|
||||
if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id)
|
||||
if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id)
|
||||
if (pov.game.forecastable) moveOrDrop.left.toOption.foreach { move =>
|
||||
round ! ForecastPlay(move)
|
||||
}
|
||||
fuccess(progress.events)
|
||||
val res = if (progress.game.finished) moveFinish(progress.game, pov.color) dmap { progress.events ::: _ }
|
||||
else {
|
||||
if (progress.game.playableByAi) requestFishnet(progress.game, round)
|
||||
if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id)
|
||||
if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id)
|
||||
if (pov.game.forecastable) moveOrDrop.left.toOption.foreach { move =>
|
||||
round ! ForecastPlay(move)
|
||||
}
|
||||
) >>- promiseOption.foreach(_.success(()))
|
||||
fuccess(progress.events)
|
||||
}
|
||||
res >>- promiseOption.foreach(_.success(()))
|
||||
}
|
||||
|
||||
private[round] def fishnet(game: Game, uci: Uci, currentFen: FEN, round: ActorRef)(implicit proxy: GameProxy): Fu[Events] =
|
||||
|
@ -95,11 +95,10 @@ private[round] final class Player(
|
|||
case MoveApplied(progress, moveOrDrop) =>
|
||||
proxy.save(progress) >>-
|
||||
uciMemo.add(progress.game, moveOrDrop) >>-
|
||||
notifyMove(moveOrDrop, progress.game) >>
|
||||
progress.game.finished.fold(
|
||||
moveFinish(progress.game, game.turnColor) dmap { progress.events ::: _ },
|
||||
fuccess(progress.events)
|
||||
)
|
||||
notifyMove(moveOrDrop, progress.game) >> {
|
||||
if (progress.game.finished) moveFinish(progress.game, game.turnColor) dmap { progress.events ::: _ }
|
||||
else fuccess(progress.events)
|
||||
}
|
||||
}
|
||||
else requestFishnet(game, round) >> fufail(FishnetError("Invalid AI move current FEN"))
|
||||
} else fufail(FishnetError("Not AI turn"))
|
||||
|
|
|
@ -71,7 +71,7 @@ private[round] final class Socket(
|
|||
}
|
||||
|
||||
def isGone: Fu[Boolean] = {
|
||||
time < (nowMillis - isBye.fold(ragequitTimeout, disconnectTimeout).toMillis) &&
|
||||
time < (nowMillis - (if (isBye) ragequitTimeout else disconnectTimeout).toMillis) &&
|
||||
!botConnected
|
||||
} ?? !isHostingSimul
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ private[round] final class Takebacker(
|
|||
private def IfAllowed[A](game: Game)(f: => Fu[A]): Fu[A] =
|
||||
if (!game.playable) fufail(ClientError("[takebacker] game is over " + game.id))
|
||||
else isAllowedByPrefs(game) flatMap {
|
||||
_.fold(f, fufail(ClientError("[takebacker] disallowed by preferences " + game.id)))
|
||||
case true => f
|
||||
case _ => fufail(ClientError("[takebacker] disallowed by preferences " + game.id))
|
||||
}
|
||||
|
||||
private def single(game: Game)(implicit proxy: GameProxy): Fu[Events] = for {
|
||||
|
|
|
@ -17,9 +17,9 @@ object Range {
|
|||
|
||||
def apply[A](a: Option[A], b: Option[A])(implicit o: Ordering[A]): Range[A] =
|
||||
(a, b) match {
|
||||
case (Some(aa), Some(bb)) => o.lt(aa, bb).fold(
|
||||
new Range(a, b), new Range(b, a)
|
||||
)
|
||||
case (Some(aa), Some(bb)) =>
|
||||
if (o.lt(aa, bb)) new Range(a, b)
|
||||
else new Range(b, a)
|
||||
case (x, y) => new Range(x, y)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ case class AiConfig(
|
|||
Player.make(chess.Black, user, perfPicker)
|
||||
),
|
||||
mode = chess.Mode.Casual,
|
||||
source = (chessGame.board.variant.fromPosition).fold(Source.Position, Source.Ai),
|
||||
source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Ai,
|
||||
daysPerTurn = makeDaysPerTurn,
|
||||
pgnImport = None
|
||||
)
|
||||
|
|
|
@ -36,14 +36,14 @@ private[setup] trait Config {
|
|||
|
||||
def makeGame: ChessGame = makeGame(variant)
|
||||
|
||||
def validClock = hasClock.fold(clockHasTime, true)
|
||||
def validClock = !hasClock || clockHasTime
|
||||
|
||||
def clockHasTime = time + increment > 0
|
||||
|
||||
def makeClock = hasClock option justMakeClock
|
||||
|
||||
protected def justMakeClock =
|
||||
Clock.Config((time * 60).toInt, clockHasTime.fold(increment, 1))
|
||||
Clock.Config((time * 60).toInt, if (clockHasTime) increment else 1)
|
||||
|
||||
def makeDaysPerTurn: Option[Int] = (timeMode == TimeMode.Correspondence) option days
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ case class FilterConfig(
|
|||
)
|
||||
|
||||
def nonEmpty = copy(
|
||||
variant = variant.isEmpty.fold(FilterConfig.default.variant, variant),
|
||||
mode = mode.isEmpty.fold(FilterConfig.default.mode, mode),
|
||||
speed = speed.isEmpty.fold(FilterConfig.default.speed, speed)
|
||||
variant = if (variant.isEmpty) FilterConfig.default.variant else variant,
|
||||
mode = if (mode.isEmpty) FilterConfig.default.mode else mode,
|
||||
speed = if (speed.isEmpty) FilterConfig.default.speed else speed
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ case class HookConfig(
|
|||
uid = uid,
|
||||
variant = variant,
|
||||
clock = clock,
|
||||
mode = lila.game.Game.allowRated(variant, clock.some).fold(mode, Mode.Casual),
|
||||
mode = if (lila.game.Game.allowRated(variant, clock.some)) mode else Mode.Casual,
|
||||
color = color.name,
|
||||
user = user,
|
||||
blocking = blocking,
|
||||
|
|
|
@ -34,7 +34,7 @@ case class AnaDrop(
|
|||
opening = Variant.openingSensibleVariants(variant) ?? {
|
||||
FullOpeningDB findByFen fen
|
||||
},
|
||||
drops = movable.fold(game.situation.drops, Some(Nil)),
|
||||
drops = if (movable) game.situation.drops else Some(Nil),
|
||||
crazyData = game.situation.board.crazyData
|
||||
)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ case class AnaMove(
|
|||
opening = (game.turns <= 30 && Variant.openingSensibleVariants(variant)) ?? {
|
||||
FullOpeningDB findByFen fen
|
||||
},
|
||||
drops = movable.fold(game.situation.drops, Some(Nil)),
|
||||
drops = if (movable) game.situation.drops else Some(Nil),
|
||||
crazyData = game.situation.board.crazyData
|
||||
)
|
||||
}
|
||||
|
|
|
@ -40,10 +40,9 @@ object Handler {
|
|||
case ("startWatching", o) => o str "d" foreach { ids =>
|
||||
hub.actor.moveBroadcast ! StartWatching(uid.value, member, ids.split(' ').toSet)
|
||||
}
|
||||
case ("moveLat", o) => hub.channel.roundMoveTime ! (~(o boolean "d")).fold(
|
||||
Channel.Sub(member),
|
||||
Channel.UnSub(member)
|
||||
)
|
||||
case ("moveLat", o) => hub.channel.roundMoveTime ! {
|
||||
if (~(o boolean "d")) Channel.Sub(member) else Channel.UnSub(member)
|
||||
}
|
||||
case ("anaMove", o) => AnaRateLimit(uid.value, member) {
|
||||
AnaMove parse o foreach { anaMove =>
|
||||
member push {
|
||||
|
|
|
@ -140,7 +140,7 @@ final class StudyRepo(private[study] val coll: Coll) {
|
|||
countLikes(studyId).flatMap {
|
||||
case None => fuccess(Study.Likes(0))
|
||||
case Some((prevLikes, createdAt)) =>
|
||||
val likes = Study.Likes(prevLikes.value + v.fold(1, -1))
|
||||
val likes = Study.Likes(prevLikes.value + (if (v) 1 else -1))
|
||||
coll.update(
|
||||
$id(studyId),
|
||||
$set(
|
||||
|
|
|
@ -38,7 +38,7 @@ private[team] final class DataForm(
|
|||
)(TeamEdit.apply)(TeamEdit.unapply)) fill TeamEdit(
|
||||
location = team.location,
|
||||
description = team.description,
|
||||
open = team.open.fold(1, 0)
|
||||
open = if (team.open) 1 else 0
|
||||
)
|
||||
|
||||
val request = Form(mapping(
|
||||
|
|
|
@ -70,6 +70,6 @@ object Team {
|
|||
|
||||
def nameToId(name: String) = (lila.common.String slugify name) |> { slug =>
|
||||
// if most chars are not latin, go for random slug
|
||||
(slug.size > (name.size / 2)).fold(slug, Random nextString 8)
|
||||
if (slug.size > (name.size / 2)) slug else Random nextString 8
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,8 @@ private[timeline] final class Push(
|
|||
private def makeEntry(users: List[String], data: Atom): Fu[Entry] = {
|
||||
val entry = Entry.make(data)
|
||||
entryApi.findRecent(entry.typ, DateTime.now minusMinutes 60, 1000) flatMap { entries =>
|
||||
entries.exists(_ similarTo entry) fold (
|
||||
fufail[Entry]("[timeline] a similar entry already exists"),
|
||||
entryApi insert Entry.ForUsers(entry, users) inject entry
|
||||
)
|
||||
if (entries.exists(_ similarTo entry)) fufail[Entry]("[timeline] a similar entry already exists")
|
||||
else entryApi insert Entry.ForUsers(entry, users) inject entry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,10 @@ object BSONHandlers {
|
|||
status = chess.Status(r int "s") err "tournament pairing status",
|
||||
user1 = user1,
|
||||
user2 = user2,
|
||||
winner = r boolO "w" map (_.fold(user1, user2)),
|
||||
winner = r boolO "w" map {
|
||||
case true => user1
|
||||
case _ => user2
|
||||
},
|
||||
turns = r intO "t",
|
||||
berserk1 = r.intO("b1").fold(r.boolD("b1"))(1 ==), // it used to be int = 0/1
|
||||
berserk2 = r.intO("b2").fold(r.boolD("b2"))(1 ==)
|
||||
|
|
|
@ -35,8 +35,8 @@ object PairingRepo {
|
|||
).sort(recentSort).cursor[Bdoc]().fold(Map.empty[User.ID, User.ID], nb) { (acc, doc) =>
|
||||
~doc.getAs[List[User.ID]]("u") match {
|
||||
case List(u1, u2) =>
|
||||
val acc1 = acc.contains(u1).fold(acc, acc.updated(u1, u2))
|
||||
acc.contains(u2).fold(acc1, acc1.updated(u2, u1))
|
||||
val acc1 = if (acc.contains(u1)) acc else acc.updated(u1, u2)
|
||||
if (acc.contains(u2)) acc1 else acc1.updated(u2, u1)
|
||||
}
|
||||
} map Pairing.LastOpponents.apply
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ final class Authenticator(
|
|||
def compare(auth: AuthData, p: ClearPassword): Boolean = {
|
||||
val newP = auth.salt.fold(p) { s =>
|
||||
val salted = s"${p.value}{$s}" // BC
|
||||
ClearPassword((~auth.sha512).fold(salted.sha512, salted.sha1))
|
||||
ClearPassword(if (~auth.sha512) salted.sha512 else salted.sha1)
|
||||
}
|
||||
passHasher.check(auth.bpass, newP)
|
||||
}
|
||||
|
|
|
@ -32,17 +32,16 @@ final class NoteApi(
|
|||
def get(user: User, me: User, myFriendIds: Set[String], isMod: Boolean): Fu[List[Note]] =
|
||||
coll.find(
|
||||
$doc("to" -> user.id) ++
|
||||
me.troll.fold($empty, $doc("troll" -> false)) ++
|
||||
isMod.fold(
|
||||
$or(
|
||||
"from" $in (myFriendIds + me.id),
|
||||
"mod" $eq true
|
||||
),
|
||||
(!me.troll ?? $doc("troll" -> false)) ++
|
||||
(if (isMod) $or(
|
||||
"from" $in (myFriendIds + me.id),
|
||||
"mod" $eq true
|
||||
)
|
||||
else
|
||||
$doc(
|
||||
"from" $in (myFriendIds + me.id),
|
||||
"mod" -> false
|
||||
)
|
||||
)
|
||||
))
|
||||
).sort($doc("date" -> -1)).list[Note](20)
|
||||
|
||||
def forMod(id: User.ID): Fu[List[Note]] =
|
||||
|
|
|
@ -124,8 +124,8 @@ object UserRepo {
|
|||
doc.getAs[User.ID]("_id") contains u1
|
||||
}
|
||||
}.addEffect { v =>
|
||||
incColor(u1, v.fold(1, -1))
|
||||
incColor(u2, v.fold(-1, 1))
|
||||
incColor(u1, if (v) 1 else -1)
|
||||
incColor(u2, if (v) -1 else 1)
|
||||
}
|
||||
|
||||
def firstGetsWhite(u1O: Option[User.ID], u2O: Option[User.ID]): Fu[Boolean] =
|
||||
|
@ -183,9 +183,9 @@ object UserRepo {
|
|||
coll.primitiveOne[User.PlayTime]($id(id), F.playTime)
|
||||
|
||||
val enabledSelect = $doc(F.enabled -> true)
|
||||
def engineSelect(v: Boolean) = $doc(F.engine -> v.fold[BSONValue]($boolean(true), $ne(true)))
|
||||
def trollSelect(v: Boolean) = $doc(F.troll -> v.fold[BSONValue]($boolean(true), $ne(true)))
|
||||
def boosterSelect(v: Boolean) = $doc(F.booster -> v.fold[BSONValue]($boolean(true), $ne(true)))
|
||||
def engineSelect(v: Boolean) = $doc(F.engine -> (if (v) $boolean(true) else $ne(true)))
|
||||
def trollSelect(v: Boolean) = $doc(F.troll -> (if (v) $boolean(true) else $ne(true)))
|
||||
def boosterSelect(v: Boolean) = $doc(F.booster -> (if (v) $boolean(true) else $ne(true)))
|
||||
def stablePerfSelect(perf: String) = $doc(
|
||||
s"perfs.$perf.nb" -> $gte(30),
|
||||
s"perfs.$perf.gl.d" -> $lt(lila.rating.Glicko.provisionalDeviation)
|
||||
|
|
Loading…
Reference in New Issue