diff --git a/app/Lila.scala b/app/Lila.scala index b98bb8b0034c2..54647dde208ea 100644 --- a/app/Lila.scala +++ b/app/Lila.scala @@ -1,6 +1,6 @@ package lila.app -import java.io._ +import java.io.* import play.api.{ Application, Environment, Play, Configuration, Mode } import play.core.server.{ RealServerProcess, ServerProcess, Server, ServerStartException, ServerConfig } @@ -96,7 +96,7 @@ object Lila: val address = configuration.getOptional[String]("play.server.http.address").getOrElse("0.0.0.0") val mode = - if (configuration.getOptional[String]("play.mode").contains("prod")) Mode.Prod + if configuration.getOptional[String]("play.mode").contains("prod") then Mode.Prod else Mode.Dev ServerConfig(rootDir, httpPort, address, mode, process.properties, configuration) diff --git a/app/LoggerConfigurator.scala b/app/LoggerConfigurator.scala index 3b0df5592d950..b67d87184ee50 100644 --- a/app/LoggerConfigurator.scala +++ b/app/LoggerConfigurator.scala @@ -3,12 +3,12 @@ package lila.app import java.io.File import java.net.URL -import ch.qos.logback.classic._ +import ch.qos.logback.classic.* import ch.qos.logback.classic.jul.LevelChangePropagator import ch.qos.logback.classic.util.ContextInitializer -import ch.qos.logback.core.util._ +import ch.qos.logback.core.util.* import org.slf4j.{ LoggerFactory, ILoggerFactory } -import org.slf4j.bridge._ +import org.slf4j.bridge.* private object LoggerConfigurator: @@ -20,7 +20,7 @@ private object LoggerConfigurator: new File(sys.props.get("logger.file").getOrElse("conf/logger.dev.xml")).toURI.toURL ) - def configure(properties: Map[String, String], configUrl: URL): Unit = { + def configure(properties: Map[String, String], configUrl: URL): Unit = // Touching LoggerContext is not thread-safe, and so if you run several // application tests at the same time (spec2 / scalatest with "new WithApplication()") // then you will see NullPointerException as the array list loggerContextListenerList @@ -71,7 +71,6 @@ private object LoggerConfigurator: StatusPrinter.printIfErrorsOccured(ctx) // } - } def shutdown(): Unit = val ctx = loggerFactory.asInstanceOf[LoggerContext] diff --git a/app/controllers/Api.scala b/app/controllers/Api.scala index 4eb5eeeb65437..793b342b90b93 100644 --- a/app/controllers/Api.scala +++ b/app/controllers/Api.scala @@ -215,7 +215,7 @@ final class Api( val result = if csv then csvDownload(lila.tournament.TournamentCsv(source)) else jsonDownload(source.map(lila.tournament.JsonView.playerResultWrites.writes)) - result.pipe(asAttachment(env.api.gameApiV2.filename(tour, if (csv) "csv" else "ndjson"))) + result.pipe(asAttachment(env.api.gameApiV2.filename(tour, if csv then "csv" else "ndjson"))) } def tournamentTeams(id: TourId) = Anon: @@ -306,7 +306,7 @@ final class Api( transform: String => Option[Id] )(f: Set[Id] => Result): Result = val ids = req.body.split(',').view.filter(_.nonEmpty).flatMap(s => transform(s.trim)).toSet - if (ids.size > max) JsonBadRequest(jsonError(s"Too many ids: ${ids.size}, expected up to $max")) + if ids.size > max then JsonBadRequest(jsonError(s"Too many ids: ${ids.size}, expected up to $max")) else f(ids) val cloudEval = diff --git a/app/controllers/Auth.scala b/app/controllers/Auth.scala index 68c86263ffdd0..fad94cce8868e 100644 --- a/app/controllers/Auth.scala +++ b/app/controllers/Auth.scala @@ -88,7 +88,7 @@ final class Auth( def authenticate = OpenBody: NoCrawlers: Firewall: - def redirectTo(url: String) = if (HTTPRequest isXhr ctx.req) Ok(s"ok:$url") else Redirect(url) + def redirectTo(url: String) = if HTTPRequest isXhr ctx.req then Ok(s"ok:$url") else Redirect(url) val referrer = get("referrer").filterNot(env.api.referrerRedirect.sillyLoginReferrers) api.loginForm .bindFromRequest() @@ -204,7 +204,7 @@ final class Auth( ctx: Context ): Funit = garbageCollect(user)(email) - if (sendWelcomeEmail) env.mailer.automaticEmail.welcomeEmail(user, email) + if sendWelcomeEmail then env.mailer.automaticEmail.welcomeEmail(user, email) env.mailer.automaticEmail.welcomePM(user) env.pref.api.saveNewUserPrefs(user, ctx.req) @@ -382,7 +382,7 @@ final class Auth( def magicLinkApply = OpenBody: Firewall: env.security.hcaptcha.verify() flatMap { captcha => - if (captcha.ok) + if captcha.ok then forms.magicLink flatMap { _.form .bindFromRequest() @@ -401,8 +401,7 @@ final class Auth( } ) } - else - renderMagicLink(none, fail = true) map { BadRequest(_) } + else renderMagicLink(none, fail = true) map { BadRequest(_) } } def magicLinkSent = Open: diff --git a/app/controllers/Challenge.scala b/app/controllers/Challenge.scala index dc2d69fbd6408..1fa6072eeb38a 100644 --- a/app/controllers/Challenge.scala +++ b/app/controllers/Challenge.scala @@ -129,7 +129,7 @@ final class Challenge( _ map { game => env.lilaCookie.cookie( AnonCookie.name, - game.player(if (owner) c.finalColor else !c.finalColor).id.value, + game.player(if owner then c.finalColor else !c.finalColor).id.value, maxAge = AnonCookie.maxAge.some, httpOnly = false.some ) diff --git a/app/controllers/Clas.scala b/app/controllers/Clas.scala index 51ff080747c0d..89383f550d4f0 100644 --- a/app/controllers/Clas.scala +++ b/app/controllers/Clas.scala @@ -10,7 +10,7 @@ import views.* import lila.app.{ given, * } import lila.clas.ClasInvite -import lila.clas.Clas.{ Id => ClasId } +import lila.clas.Clas.{ Id as ClasId } final class Clas(env: Env, authC: Auth) extends LilaController(env): @@ -107,7 +107,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env): else Found(env.clas.api.clas.byId(id)): clas => env.clas.api.student.activeWithUsers(clas) flatMap { students => - if (students.exists(_.student is me)) forStudent(clas, students) + if students.exists(_.student is me) then forStudent(clas, students) else orDefault(ctx) } } @@ -173,7 +173,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env): env.clas.api.student.activeWithUsers(clas) flatMap { students => Reasonable(clas, students, "notify"): val url = routes.Clas.show(clas.id.value).url - val full = if (text contains url) text else s"$text\n\n${env.net.baseUrl}$url" + val full = if text contains url then text else s"$text\n\n${env.net.baseUrl}$url" env.msg.api .multiPost(Source(students.map(_.user.id)), full) .addEffect: nb => diff --git a/app/controllers/Dasher.scala b/app/controllers/Dasher.scala index 454d6d41e0f54..13586e6ad01a3 100644 --- a/app/controllers/Dasher.scala +++ b/app/controllers/Dasher.scala @@ -43,12 +43,12 @@ final class Dasher(env: Env)(using ws: StandaloneWSClient) extends LilaControlle private def translations(using Context) = lila.i18n.JsDump.keysToObject( - if (ctx.isAnon) translationsAnon else translationsAuth, + if ctx.isAnon then translationsAnon else translationsAuth, ctx.lang ) ++ lila.i18n.JsDump.keysToObject( // the language settings should never be in a totally foreign language List(trans.language), - if (I18nLangPicker.allFromRequestHeaders(ctx.req).has(ctx.lang)) ctx.lang + if I18nLangPicker.allFromRequestHeaders(ctx.req).has(ctx.lang) then ctx.lang else I18nLangPicker.bestFromRequestHeaders(ctx.req) | enLang ) diff --git a/app/controllers/Editor.scala b/app/controllers/Editor.scala index de10189225a59..7c9e8fc4b6ab2 100644 --- a/app/controllers/Editor.scala +++ b/app/controllers/Editor.scala @@ -48,7 +48,7 @@ final class Editor(env: Env) extends LilaController(env): else editorUrl(get("fen").fold(Fen.write(game.chess))(Fen.Epd.clean), game.variant) private[controllers] def editorUrl(fen: Fen.Epd, variant: Variant): String = - if (fen == Fen.initial && variant.standard) routes.Editor.index.url + if fen == Fen.initial && variant.standard then routes.Editor.index.url else val params = variant.exotic so s"?variant=${variant.key}" routes.Editor.load(lila.common.String.underscoreFen(fen)).url + params diff --git a/app/controllers/Export.scala b/app/controllers/Export.scala index 1cbe4dc567aca..fae66c5236abd 100644 --- a/app/controllers/Export.scala +++ b/app/controllers/Export.scala @@ -38,7 +38,7 @@ final class Export(env: Env) extends LilaController(env): g.fen, Theme(theme).name, PieceSet.get(piece).name - ) pipe stream(cacheSeconds = if (g.game.finishedOrAborted) 3600 * 24 else 10) + ) pipe stream(cacheSeconds = if g.game.finishedOrAborted then 3600 * 24 else 10) } def legacyGameThumbnail(id: GameId, theme: Option[String], piece: Option[String]) = Anon: @@ -47,7 +47,7 @@ final class Export(env: Env) extends LilaController(env): def gameThumbnail(id: GameId, theme: Option[String], piece: Option[String]) = exportImageOf(env.game.gameRepo game id) { game => env.game.gifExport.gameThumbnail(game, Theme(theme).name, PieceSet.get(piece).name) pipe - stream(cacheSeconds = if (game.finishedOrAborted) 3600 * 24 else 10) + stream(cacheSeconds = if game.finishedOrAborted then 3600 * 24 else 10) } def puzzleThumbnail(id: PuzzleId, theme: Option[String], piece: Option[String]) = diff --git a/app/controllers/ForumController.scala b/app/controllers/ForumController.scala index c70318a6634db..14bdba201b937 100644 --- a/app/controllers/ForumController.scala +++ b/app/controllers/ForumController.scala @@ -5,7 +5,8 @@ import play.api.mvc.* import lila.app.{ given, * } import lila.forum.ForumTopic -private[controllers] trait ForumController { self: LilaController => +private[controllers] trait ForumController: + self: LilaController => protected def categApi = env.forum.categApi protected def topicApi = env.forum.topicApi @@ -55,4 +56,3 @@ private[controllers] trait ForumController { self: LilaController => else Forbidden("You cannot moderate this forum") } } -} diff --git a/app/controllers/ForumPost.scala b/app/controllers/ForumPost.scala index 1543a039b823e..b18f27c5e75f7 100644 --- a/app/controllers/ForumPost.scala +++ b/app/controllers/ForumPost.scala @@ -97,8 +97,8 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController topic <- topicRepo.forUser(me.some).byId(post.topicId) reason <- reasonOpt.filter(MsgPreset.forumDeletion.presets.contains) preset = - if (isGranted(_.ModerateForum)) MsgPreset.forumDeletion.byModerator - else if (topic.exists(_ isUblogAuthor me)) + if isGranted(_.ModerateForum) then MsgPreset.forumDeletion.byModerator + else if topic.exists(_ isUblogAuthor me) then MsgPreset.forumDeletion.byBlogAuthor(me.username) else MsgPreset.forumDeletion.byTeamLeader(categId) do env.msg.api.systemPost(userId, preset(reason)) diff --git a/app/controllers/Game.scala b/app/controllers/Game.scala index 317f582fbe1e3..dbd05ca1c10b5 100644 --- a/app/controllers/Game.scala +++ b/app/controllers/Game.scala @@ -35,7 +35,7 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env): case None => NotFound case Some(game) => val config = GameApiV2.OneConfig( - format = if (HTTPRequest acceptsJson req) GameApiV2.Format.JSON else GameApiV2.Format.PGN, + format = if HTTPRequest acceptsJson req then GameApiV2.Format.JSON else GameApiV2.Format.PGN, imported = getBool("imported"), flags = requestPgnFlags(extended = true), playerFile = get("players") @@ -72,7 +72,8 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env): color = get("color") flatMap chess.Color.fromName, analysed = getBoolOpt("analysed"), flags = requestPgnFlags(extended = false), - sort = if (get("sort") has "dateAsc") GameApiV2.GameSort.DateAsc else GameApiV2.GameSort.DateDesc, + sort = + if get("sort") has "dateAsc" then GameApiV2.GameSort.DateAsc else GameApiV2.GameSort.DateDesc, perSecond = MaxPerSecond(ctx.me match case Some(m) if m is lila.user.User.explorerId => env.apiExplorerGamesPerSecond.get() case Some(m) if m is user.id => 60 diff --git a/app/controllers/I18n.scala b/app/controllers/I18n.scala index 104c4065a7012..cb86cd7f51421 100644 --- a/app/controllers/I18n.scala +++ b/app/controllers/I18n.scala @@ -31,7 +31,7 @@ final class I18n(env: Env) extends LilaController(env): val pageUrl = new java.net.URI(str).parseServerAuthority().toURL() val path = pageUrl.getPath val query = pageUrl.getQuery - if (query == null) path + if query == null then path else path + "?" + query catch case _: Exception => routes.Lobby.home.url if ctx.isAnon diff --git a/app/controllers/Main.scala b/app/controllers/Main.scala index b3d1b11f09df2..ea44b710e8bc1 100644 --- a/app/controllers/Main.scala +++ b/app/controllers/Main.scala @@ -39,7 +39,7 @@ final class Main( def captchaCheck(id: GameId) = Open: import makeTimeout.long env.hub.captcher.actor ? ValidCaptcha(id, ~get("solution")) map { case valid: Boolean => - Ok(if (valid) 1 else 0) + Ok(if valid then 1 else 0) } def webmasters = Open: diff --git a/app/controllers/Mod.scala b/app/controllers/Mod.scala index 51adf77537525..130fab5c9f100 100644 --- a/app/controllers/Mod.scala +++ b/app/controllers/Mod.scala @@ -185,7 +185,7 @@ final class Mod( case _ if Granter(_.BoostHunter) => ModDomain.Boost case _ => ModDomain.Admin , - room = if (report.isSpontaneous) "Spontaneous inquiry" else report.room.name + room = if report.isSpontaneous then "Spontaneous inquiry" else report.room.name ) inject NoContent } } @@ -301,10 +301,10 @@ final class Mod( .flashFailure(s"Currently processed by ${mod.name}") case _ => val f = - if (isAppeal) env.report.api.inquiries.appeal + if isAppeal then env.report.api.inquiries.appeal else env.report.api.inquiries.spontaneous f(Suspect(user)) inject { - if (isAppeal) Redirect(s"${appeal.routes.Appeal.show(user.username)}#appeal-actions") + if isAppeal then Redirect(s"${appeal.routes.Appeal.show(user.username)}#appeal-actions") else redirect(user.username, mod = true) } } diff --git a/app/controllers/Opening.scala b/app/controllers/Opening.scala index 075a1200646af..500b103b8d8c7 100644 --- a/app/controllers/Opening.scala +++ b/app/controllers/Opening.scala @@ -31,10 +31,9 @@ final class Opening(env: Env) extends LilaController(env): case None => Redirect(routes.Opening.index(key.some)) case Some(page) => val query = page.query.query - if (query.key.isEmpty) Redirect(routes.Opening.index(key.some)) - else if (query.key != key) - Redirect(routes.Opening.byKeyAndMoves(query.key, moves)) - else if (moves.nonEmpty && page.query.pgnUnderscored != moves && !getBool("r")) + if query.key.isEmpty then Redirect(routes.Opening.index(key.some)) + else if query.key != key then Redirect(routes.Opening.byKeyAndMoves(query.key, moves)) + else if moves.nonEmpty && page.query.pgnUnderscored != moves && !getBool("r") then Redirect: s"${routes.Opening.byKeyAndMoves(query.key, page.query.pgnUnderscored)}?r=1" else diff --git a/app/controllers/Puzzle.scala b/app/controllers/Puzzle.scala index 735e0377ec926..cc86abae739ea 100644 --- a/app/controllers/Puzzle.scala +++ b/app/controllers/Puzzle.scala @@ -163,7 +163,7 @@ final class Puzzle(env: Env, apiC: => Api) extends LilaController(env): "voted" -> round.vote ) else - (data.replayDays, angle.asTheme) match { + (data.replayDays, angle.asTheme) match case (Some(replayDays), Some(theme)) => for _ <- env.puzzle.replay.onComplete(round, replayDays, angle) @@ -187,12 +187,11 @@ final class Puzzle(env: Env, apiC: => Api) extends LilaController(env): "round" -> env.puzzle.jsonView.roundJson.web(round, perf)(using me), "next" -> nextJson ) - } yield json } case None => env.puzzle.finisher.incPuzzlePlays(id) - if (mobileBc) fuccess(Json.obj("user" -> false)) + if mobileBc then fuccess(Json.obj("user" -> false)) else nextPuzzleForMe(angle, data.color map some) .flatMap: diff --git a/app/controllers/RelayRound.scala b/app/controllers/RelayRound.scala index c005dc0b0309c..5d73506884862 100644 --- a/app/controllers/RelayRound.scala +++ b/app/controllers/RelayRound.scala @@ -95,11 +95,10 @@ final class RelayRound( val sc = if rt.round.sync.ongoing then env.study.chapterRepo relaysAndTagsByStudyId rt.round.studyId flatMap { chapters => - chapters.find(_.looksAlive) orElse chapters.headOption match { + chapters.find(_.looksAlive) orElse chapters.headOption match case Some(chapter) => env.study.api.byIdWithChapterOrFallback(rt.round.studyId, chapter.id) case None => env.study.api byIdWithChapter rt.round.studyId - } } else env.study.api byIdWithChapter rt.round.studyId sc orNotFound { doShow(rt, _) } diff --git a/app/controllers/Report.scala b/app/controllers/Report.scala index d05bc1567913e..2970478573ca8 100644 --- a/app/controllers/Report.scala +++ b/app/controllers/Report.scala @@ -60,8 +60,8 @@ final class Report( } private def onInquiryStart(inquiry: ReportModel): Result = - if (inquiry.isRecentComm) Redirect(controllers.routes.Mod.communicationPrivate(inquiry.user)) - else if (inquiry.isComm) Redirect(controllers.routes.Mod.communicationPublic(inquiry.user)) + if inquiry.isRecentComm then Redirect(controllers.routes.Mod.communicationPrivate(inquiry.user)) + else if inquiry.isComm then Redirect(controllers.routes.Mod.communicationPublic(inquiry.user)) else modC.redirect(inquiry.user) protected[controllers] def onModAction(goTo: Suspect)(using ctx: BodyContext[?], me: Me): Fu[Result] = @@ -131,7 +131,7 @@ final class Report( def form = Auth { _ ?=> _ ?=> getUserStr("username") so env.user.repo.byId flatMap { user => - if (user.map(_.id) has UserModel.lichessId) Redirect(controllers.routes.Main.contact) + if user.map(_.id) has UserModel.lichessId then Redirect(controllers.routes.Main.contact) else Ok.pageAsync: val form = env.report.forms.create diff --git a/app/controllers/Round.scala b/app/controllers/Round.scala index c98a94b7d3657..482d5c0970e0c 100644 --- a/app/controllers/Round.scala +++ b/app/controllers/Round.scala @@ -138,7 +138,7 @@ final class Round( playablePovForReq(pov.game) match case Some(player) if userTv.isEmpty => renderPlayer(pov withColor player.color) case _ if pov.game.variant == chess.variant.RacingKings && pov.color.black => - if (userTv.isDefined) watch(!pov, userTv) + if userTv.isDefined then watch(!pov, userTv) else Redirect(routes.Round.watcher(pov.gameId, "white")) case _ => negotiateApi( diff --git a/app/controllers/Simul.scala b/app/controllers/Simul.scala index fdbf988b5677d..6ab0ae5914a01 100644 --- a/app/controllers/Simul.scala +++ b/app/controllers/Simul.scala @@ -143,7 +143,7 @@ final class Simul(env: Env) extends LilaController(env): def withdraw(id: SimulId) = Auth { ctx ?=> me ?=> env.simul.api.removeApplicant(id, me) inject { - if (HTTPRequest isXhr ctx.req) jsonOkResult + if HTTPRequest isXhr ctx.req then jsonOkResult else Redirect(routes.Simul.show(id)) } } diff --git a/app/controllers/Storm.scala b/app/controllers/Storm.scala index 8d4ab1a330549..902f98896fbe8 100644 --- a/app/controllers/Storm.scala +++ b/app/controllers/Storm.scala @@ -49,7 +49,7 @@ final class Storm(env: Env) extends LilaController(env): def apiDashboardOf(username: UserStr, days: Int) = Open: lila.user.User.validateId(username).so { userId => - if (days < 0 || days > 365) notFoundJson("Invalid days parameter") + if days < 0 || days > 365 then notFoundJson("Invalid days parameter") else ((days > 0) so env.storm.dayApi.apiHistory(userId, days)) zip env.storm.highApi.get(userId) map { case (history, high) => Ok(env.storm.json.apiDashboard(high, history)) diff --git a/app/controllers/Streamer.scala b/app/controllers/Streamer.scala index 1070d29b14d1b..70e3d33903934 100644 --- a/app/controllers/Streamer.scala +++ b/app/controllers/Streamer.scala @@ -105,7 +105,7 @@ final class Streamer(env: Env, apiC: => Api) extends LilaController(env): BadRequest.page(html.streamer.edit(sws, error, forMod)), data => api.update(sws.streamer, data, isGranted(_.Streamers)) flatMap { change => - if (change.decline) logApi.streamerDecline(s.user.id) + if change.decline then logApi.streamerDecline(s.user.id) change.list foreach { logApi.streamerList(s.user.id, _) } change.tier foreach { logApi.streamerTier(s.user.id, _) } if data.approval.flatMap(_.quick).isDefined @@ -115,7 +115,7 @@ final class Streamer(env: Env, apiC: => Api) extends LilaController(env): nextId.fold(s"${routes.Streamer.index()}?requests=1"): id => s"${routes.Streamer.edit.url}?u=$id" else - val next = if (sws.streamer is me) "" else s"?u=${sws.user.id}" + val next = if sws.streamer is me then "" else s"?u=${sws.user.id}" Redirect(s"${routes.Streamer.edit.url}$next") } ) diff --git a/app/controllers/Study.scala b/app/controllers/Study.scala index cf1ecd8732d02..cb5c02bb31112 100644 --- a/app/controllers/Study.scala +++ b/app/controllers/Study.scala @@ -393,7 +393,7 @@ final class Study( ) def cloneApply(id: StudyId) = Auth { ctx ?=> me ?=> - val cost = if (isGranted(_.Coach) || me.hasTitle) 1 else 3 + val cost = if isGranted(_.Coach) || me.hasTitle then 1 else 3 CloneLimitPerUser(me, rateLimited, cost = cost): CloneLimitPerIP(ctx.ip, rateLimited, cost = cost): Found(env.study.api.byId(id)) { prev => @@ -483,7 +483,7 @@ final class Study( akka.stream.ActorAttributes.supervisionStrategy(akka.stream.Supervision.resumingDecider) apiC.GlobalConcurrencyLimitPerIpAndUserOption(userId.some)(makeStream): source => Ok.chunked(source) - .pipe(asAttachmentStream(s"${name}-${if (isMe) "all" else "public"}-studies.pgn")) + .pipe(asAttachmentStream(s"${name}-${if isMe then "all" else "public"}-studies.pgn")) .as(pgnContentType) def apiListByOwner(username: UserStr) = OpenOrScoped(_.Study.Read): ctx ?=> diff --git a/app/controllers/TheftPrevention.scala b/app/controllers/TheftPrevention.scala index 3a9dd51f2fcf4..88a74a1d84a3a 100644 --- a/app/controllers/TheftPrevention.scala +++ b/app/controllers/TheftPrevention.scala @@ -4,7 +4,8 @@ import lila.app.{ given, * } import lila.game.{ AnonCookie, Game as GameModel, Pov } import play.api.mvc.* -private[controllers] trait TheftPrevention { self: LilaController => +private[controllers] trait TheftPrevention: + self: LilaController => protected def PreventTheft(pov: Pov)(ok: => Fu[Result])(using Context): Fu[Result] = if isTheft(pov) then Redirect(routes.Round.watcher(pov.gameId, pov.color.name)) @@ -38,4 +39,3 @@ private[controllers] trait TheftPrevention { self: LilaController => protected lazy val theftResponse = Unauthorized( jsonError("This game requires authentication") ) as JSON -} diff --git a/app/controllers/Tournament.scala b/app/controllers/Tournament.scala index fb0400fea6711..c6fd3b4713c42 100644 --- a/app/controllers/Tournament.scala +++ b/app/controllers/Tournament.scala @@ -25,10 +25,10 @@ final class Tournament(env: Env, apiC: => Api)(using akka.stream.Materializer) e private[controllers] val upcomingCache = env.memo.cacheApi.unit[(VisibleTournaments, List[Tour])] { _.refreshAfterWrite(3.seconds) .buildAsyncFuture { _ => - for { + for visible <- api.fetchVisibleTournaments scheduled <- repo.allScheduledDedup - } yield (visible, scheduled) + yield (visible, scheduled) } } diff --git a/app/controllers/TournamentCrud.scala b/app/controllers/TournamentCrud.scala index dc12bc99c2cd4..27973c21dfaa4 100644 --- a/app/controllers/TournamentCrud.scala +++ b/app/controllers/TournamentCrud.scala @@ -42,7 +42,7 @@ final class TournamentCrud(env: Env) extends LilaController(env): data => crud.create(data, me.value) map { tour => Redirect { - if (tour.isTeamBattle) routes.Tournament.teamBattleEdit(tour.id) + if tour.isTeamBattle then routes.Tournament.teamBattleEdit(tour.id) else routes.TournamentCrud.edit(tour.id) }.flashSuccess } diff --git a/app/controllers/Tv.scala b/app/controllers/Tv.scala index cdd9f5cde5fe9..ab3c087cd8706 100644 --- a/app/controllers/Tv.scala +++ b/app/controllers/Tv.scala @@ -39,7 +39,7 @@ final class Tv(env: Env, apiC: => Api, gameC: => Game) extends LilaController(en Found(env.tv.tv getGameAndHistory channel): (game, history) => val flip = getBool("flip") val natural = Pov naturalOrientation game - val pov = if (flip) !natural else natural + val pov = if flip then !natural else natural val onTv = lila.round.OnTv.Lichess(channel.key, flip) negotiateApi( html = for diff --git a/app/controllers/Ublog.scala b/app/controllers/Ublog.scala index 29717a565155b..e3bc2863f2849 100644 --- a/app/controllers/Ublog.scala +++ b/app/controllers/Ublog.scala @@ -222,7 +222,7 @@ final class Ublog(env: Env) extends LilaController(env): case ByHref.Redir(code) => Redirect(routes.Ublog.communityLang(code, page)) case ByHref.Refused(lang) => communityIndex(lang.some, page) case ByHref.Found(lang) => - if (ctx.isAuth) communityIndex(lang.some, page) + if ctx.isAuth then communityIndex(lang.some, page) else communityIndex(lang.some, page)(using ctx.withLang(lang)) def communityAll(page: Int) = Open: diff --git a/app/http/ContentSecurityPolicy.scala b/app/http/ContentSecurityPolicy.scala index 75b888bcf8768..85dfb27f1fd48 100644 --- a/app/http/ContentSecurityPolicy.scala +++ b/app/http/ContentSecurityPolicy.scala @@ -71,7 +71,7 @@ case class ContentSecurityPolicy( def withPeer = copy(connectSrc = "wss://0.peerjs.com" :: connectSrc) private def withPrismicEditor(maybe: Boolean): ContentSecurityPolicy = - if (maybe) + if maybe then copy( scriptSrc = "https://static.cdn.prismic.io" :: scriptSrc, frameSrc = "https://lichess.prismic.io" :: "https://lichess.cdn.prismic.io" :: frameSrc, diff --git a/app/http/HttpFilter.scala b/app/http/HttpFilter.scala index f47312387a4d0..4dd2e96fe22de 100644 --- a/app/http/HttpFilter.scala +++ b/app/http/HttpFilter.scala @@ -44,7 +44,7 @@ final class HttpFilter(env: Env)(using val mat: Materializer)(using Executor) !HTTPRequest.isProgrammatic(req) && // asset request going through the CDN, don't redirect !(req.host == env.net.assetDomain.value && HTTPRequest.hasFileExtension(req)) - } option Results.MovedPermanently(s"http${if (req.secure) "s" else ""}://${env.net.domain}${req.uri}") + } option Results.MovedPermanently(s"http${if req.secure then "s" else ""}://${env.net.domain}${req.uri}") private def addApiResponseHeaders(req: RequestHeader)(result: Result) = if HTTPRequest.isApiOrApp(req) diff --git a/app/http/PageCache.scala b/app/http/PageCache.scala index a023cbd76f811..f1a2b066a94ed 100644 --- a/app/http/PageCache.scala +++ b/app/http/PageCache.scala @@ -12,10 +12,9 @@ final class PageCache(cacheApi: lila.memo.CacheApi): } def apply(compute: () => Fu[Result])(using ctx: Context): Fu[Result] = - if (ctx.isAnon && langs(ctx.lang.language) && defaultPrefs(ctx.req) && !hasCookies(ctx.req)) + if ctx.isAnon && langs(ctx.lang.language) && defaultPrefs(ctx.req) && !hasCookies(ctx.req) then cache.getFuture(cacheKey(ctx), _ => compute()) - else - compute() + else compute() private def cacheKey(ctx: Context) = s"${HTTPRequest actionName ctx.req}(${ctx.lang.language})" diff --git a/app/mashup/TeamInfo.scala b/app/mashup/TeamInfo.scala index f989be2f899b8..7d122d4bfbf4f 100644 --- a/app/mashup/TeamInfo.scala +++ b/app/mashup/TeamInfo.scala @@ -65,7 +65,7 @@ final class TeamInfoApi( } def apply(team: Team, me: Option[User], withForum: Boolean => Boolean): Fu[TeamInfo] = - for { + for requests <- (team.enabled && me.exists(m => team.leaders(m.id))) so api.requestsWithUsers(team) mine <- me.so(m => api.belongsTo(team.id, m.id)) myRequest <- !mine so me.so(m => requestRepo.find(team.id, m.id)) @@ -73,7 +73,7 @@ final class TeamInfoApi( forumPosts <- withForum(mine) soFu forumRecent(team.id) tours <- tournaments(team, 5, 5) simuls <- simulApi.byTeamLeaders(team.id, team.leaders.toSeq) - } yield TeamInfo( + yield TeamInfo( mine = mine, ledByMe = me.exists(m => team.leaders(m.id)), myRequest = myRequest, diff --git a/app/router.scala b/app/router.scala index d3b509d18227e..73a0fa99551f8 100644 --- a/app/router.scala +++ b/app/router.scala @@ -1,6 +1,6 @@ package router -import lila.app._ +import lila.app.* import lila.rating.Perf import lila.puzzle.PuzzleTheme import lila.report.Report diff --git a/app/templating/AiHelper.scala b/app/templating/AiHelper.scala index 421596135962a..ad5dfc54a5fcd 100644 --- a/app/templating/AiHelper.scala +++ b/app/templating/AiHelper.scala @@ -5,11 +5,11 @@ import play.api.i18n.Lang import lila.app.ui.ScalatagsTemplate.* -trait AiHelper { self: I18nHelper => +trait AiHelper: + self: I18nHelper => def aiName(level: Int)(using Lang): String = trans.aiNameLevelAiLevel.txt("Stockfish", level) def aiNameFrag(level: Int)(using Lang) = raw(aiName(level).replace(" ", " ")) -} diff --git a/app/templating/AssetHelper.scala b/app/templating/AssetHelper.scala index ecba8740f618b..4e6d7cbfc86c8 100644 --- a/app/templating/AssetHelper.scala +++ b/app/templating/AssetHelper.scala @@ -8,7 +8,8 @@ import lila.app.ui.ScalatagsTemplate.* import lila.common.AssetVersion import lila.common.String.html.safeJsonValue -trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper => +trait AssetHelper extends HasEnv: + self: I18nHelper with SecurityHelper => private lazy val netDomain = env.net.domain private lazy val assetDomain = env.net.assetDomain @@ -32,7 +33,7 @@ trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper => cssTagWithDirAndTheme(name, isRTL, ctx.pref.currentBg) def cssTagWithDirAndTheme(name: String, isRTL: Boolean, theme: String): Frag = - if (theme == "system") + if theme == "system" then frag( cssTagWithDirAndSimpleTheme(name, isRTL, "light")(media := "(prefers-color-scheme: light)"), cssTagWithDirAndSimpleTheme(name, isRTL, "dark")(media := "(prefers-color-scheme: dark)") @@ -40,10 +41,12 @@ trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper => else cssTagWithDirAndSimpleTheme(name, isRTL, theme) private def cssTagWithDirAndSimpleTheme(name: String, isRTL: Boolean, theme: String): Tag = - cssAt(s"css/$name.${if (isRTL) "rtl" else "ltr"}.$theme.${if (minifiedAssets) "min" else "dev"}.css") + cssAt( + s"css/$name.${if isRTL then "rtl" else "ltr"}.$theme.${if minifiedAssets then "min" else "dev"}.css" + ) def cssTagNoTheme(name: String): Frag = - cssAt(s"css/$name.${if (minifiedAssets) "min" else "dev"}.css") + cssAt(s"css/$name.${if minifiedAssets then "min" else "dev"}.css") private def cssAt(path: String): Tag = link(href := assetUrl(path), rel := "stylesheet") @@ -128,4 +131,3 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') def embedJsUnsafeLoadThen(js: String, nonce: lila.api.Nonce): Frag = embedJsUnsafe(s"""lichess.load.then(()=>{$js})""", nonce) -} diff --git a/app/templating/ChessgroundHelper.scala b/app/templating/ChessgroundHelper.scala index 67a5828f5b53b..2f5adbde39deb 100644 --- a/app/templating/ChessgroundHelper.scala +++ b/app/templating/ChessgroundHelper.scala @@ -17,7 +17,7 @@ trait ChessgroundHelper: wrap { cgBoard { raw { - if (ctx.pref.is3d) "" + if ctx.pref.is3d then "" else def top(p: Square) = orient.fold(7 - p.rank.index, p.rank.index) * 12.5 def left(p: Square) = orient.fold(p.file.index, 7 - p.file.index) * 12.5 @@ -25,7 +25,7 @@ trait ChessgroundHelper: s"""""" } mkString "" val pieces = - if (ctx.pref.isBlindfold) "" + if ctx.pref.isBlindfold then "" else board.pieces.map { case (pos, piece) => val klass = s"${piece.color.name} ${piece.role.name}" diff --git a/app/templating/DateHelper.scala b/app/templating/DateHelper.scala index 71977c50e8904..ffd43a370a4ea 100644 --- a/app/templating/DateHelper.scala +++ b/app/templating/DateHelper.scala @@ -9,7 +9,8 @@ import java.time.{ Duration, LocalDate } import lila.app.ui.ScalatagsTemplate.* import lila.i18n.PeriodLocales -trait DateHelper { self: I18nHelper with StringHelper with NumberHelper => +trait DateHelper: + self: I18nHelper with StringHelper with NumberHelper => export PeriodLocales.showDuration @@ -62,7 +63,7 @@ trait DateHelper { self: I18nHelper with StringHelper with NumberHelper => private val oneDayMillis = 1000 * 60 * 60 * 24 def momentFromNow(instant: Instant, alwaysRelative: Boolean = false, once: Boolean = false): Tag = - if (!alwaysRelative && (instant.toMillis - nowMillis) > oneDayMillis) absClientInstant(instant) + if !alwaysRelative && (instant.toMillis - nowMillis) > oneDayMillis then absClientInstant(instant) else timeTag(cls := s"timeago${once so " once"}", datetimeAttr := isoDateTime(instant))(nbsp) def momentFromNowWithPreload( @@ -93,11 +94,10 @@ trait DateHelper { self: I18nHelper with StringHelper with NumberHelper => lazy val months = days / 30 lazy val years = days / 365 val preposition = if inFuture then " from now" else " ago" - if (minutes == 0) "right now" - else if (hours == 0) s"${pluralize("minute", minutes)}$preposition" - else if (days < 2) s"${pluralize("hour", hours)}$preposition" - else if (weeks == 0) s"${pluralize("day", days)}$preposition" - else if (months == 0) s"${pluralize("week", weeks)}$preposition" - else if (years == 0) s"${pluralize("month", months)}$preposition" + if minutes == 0 then "right now" + else if hours == 0 then s"${pluralize("minute", minutes)}$preposition" + else if days < 2 then s"${pluralize("hour", hours)}$preposition" + else if weeks == 0 then s"${pluralize("day", days)}$preposition" + else if months == 0 then s"${pluralize("week", weeks)}$preposition" + else if years == 0 then s"${pluralize("month", months)}$preposition" else s"${pluralize("year", years)}$preposition" -} diff --git a/app/templating/Environment.scala b/app/templating/Environment.scala index 431cf77f90f48..c975782797646 100644 --- a/app/templating/Environment.scala +++ b/app/templating/Environment.scala @@ -29,7 +29,7 @@ object Environment export lila.common.licon private var envVar: Option[Env] = None - def setEnv(e: Env) = { envVar = Some(e) } + def setEnv(e: Env) = envVar = Some(e) def env: Env = envVar.get type FormWithCaptcha = (play.api.data.Form[?], lila.common.Captcha) @@ -40,10 +40,10 @@ object Environment given lila.common.config.NetDomain = env.net.domain lazy val siteName: String = - if (env.net.siteName == "localhost:9663") "lichess.dev" + if env.net.siteName == "localhost:9663" then "lichess.dev" else env.net.siteName lazy val siteNameFrag: Frag = - if (siteName == "lichess.org") frag("lichess", span(".org")) + if siteName == "lichess.org" then frag("lichess", span(".org")) else frag(siteName) def apiVersion = lila.api.Mobile.Api.currentVersion diff --git a/app/templating/FlashHelper.scala b/app/templating/FlashHelper.scala index a4db2be638337..0f426be04e7d7 100644 --- a/app/templating/FlashHelper.scala +++ b/app/templating/FlashHelper.scala @@ -3,7 +3,8 @@ package templating import lila.app.ui.ScalatagsTemplate.* -trait FlashHelper { self: I18nHelper => +trait FlashHelper: + self: I18nHelper => def standardFlash(using Context): Option[Tag] = successFlash orElse warningFlash orElse failureFlash @@ -17,13 +18,13 @@ trait FlashHelper { self: I18nHelper => def warningFlash(using ctx: Context): Option[Tag] = ctx.flash("warning").map { msg => flashMessage("warning"): - if (msg.isEmpty) "Warning" else msg + if msg.isEmpty then "Warning" else msg } def failureFlash(using ctx: Context): Option[Tag] = ctx.flash("failure").map { msg => flashMessage("failure"): - if (msg.isEmpty) "Failure" else msg + if msg.isEmpty then "Failure" else msg } def flashMessage(color: String)(content: Modifier*): Tag = @@ -31,4 +32,3 @@ trait FlashHelper { self: I18nHelper => def flashMessageWith(modifiers: Modifier*)(content: Modifier*): Tag = div(modifiers)(div(cls := "flash__content")(content)) -} diff --git a/app/templating/FormHelper.scala b/app/templating/FormHelper.scala index e56c4a3f83e3c..6dd09272edc58 100644 --- a/app/templating/FormHelper.scala +++ b/app/templating/FormHelper.scala @@ -8,7 +8,8 @@ import lila.app.ui.ScalatagsTemplate.{ *, given } import lila.i18n.I18nKey import lila.common.licon -trait FormHelper { self: I18nHelper => +trait FormHelper: + self: I18nHelper => def errMsg(form: Field)(using Lang): Frag = errMsg(form.errors) @@ -266,4 +267,3 @@ trait FormHelper { self: I18nHelper => def image(name: String): Frag = st.input(tpe := "file", st.name := name, accept := "image/png, image/jpeg") def pgn(name: String): Frag = st.input(tpe := "file", st.name := name, accept := ".pgn") -} diff --git a/app/templating/GameHelper.scala b/app/templating/GameHelper.scala index f246b3e76b599..678e2ce028e87 100644 --- a/app/templating/GameHelper.scala +++ b/app/templating/GameHelper.scala @@ -95,7 +95,8 @@ trait GameHelper: withRating option frag( " (", player.rating.fold(frag("?")) { rating => - if (player.provisional.yes) abbr(title := trans.perfStat.notEnoughRatedGames.txt())(rating, "?") + if player.provisional.yes then + abbr(title := trans.perfStat.notEnoughRatedGames.txt())(rating, "?") else rating }, ")" @@ -130,11 +131,11 @@ trait GameHelper: case None => val klass = cssClass.so(" " + _) span(cls := s"user-link$klass")( - (player.aiLevel, player.name) match { + (player.aiLevel, player.name) match case (Some(level), _) => aiNameFrag(level) case (_, Some(name)) => name case _ => trans.anonymous() - }, + , player.rating.ifTrue(withRating && ctx.pref.showRatings) map { rating => s" ($rating)" }, statusIcon ) @@ -142,7 +143,7 @@ trait GameHelper: frag( (if link then a else span) ( cls := userClass(user.id, cssClass, withOnline), - (if link then href else dataHref) := s"${routes.User show user.name}${if (mod) "?mod" else ""}" + (if link then href else dataHref) := s"${routes.User show user.name}${if mod then "?mod" else ""}" )( withOnline option frag(lineIcon(user), " "), playerUsername(player.light, withRating && ctx.pref.showRatings), @@ -182,7 +183,7 @@ trait GameHelper: frag( (if link then a else span) ( cls := userClass(user.id, cssClass, withOnline), - (if link then href else dataHref) := s"${routes.User show user.name}${if (mod) "?mod" else ""}" + (if link then href else dataHref) := s"${routes.User show user.name}${if mod then "?mod" else ""}" )( withOnline option frag(lineIcon(user), " "), playerUsername(player, withRating && ctx.pref.showRatings), @@ -202,7 +203,7 @@ trait GameHelper: case S.Aborted => trans.gameAborted.txt() case S.Mate => trans.checkmate.txt() case S.Resign => - (if (game.loser.exists(_.color.white)) trans.whiteResigned else trans.blackResigned).txt() + (if game.loser.exists(_.color.white) then trans.whiteResigned else trans.blackResigned).txt() case S.UnknownFinish => trans.finished.txt() case S.Stalemate => trans.stalemate.txt() case S.Timeout => @@ -211,7 +212,7 @@ trait GameHelper: case (Some(_), _) => trans.blackLeftTheGame.txt() case (None, White) => trans.whiteLeftTheGame.txt() + " • " + trans.draw.txt() case (None, Black) => trans.blackLeftTheGame.txt() + " • " + trans.draw.txt() - case S.Draw => { + case S.Draw => import lila.game.DrawReason.* game.drawReason match case Some(MutualAgreement) => trans.drawByMutualAgreement.txt() @@ -219,7 +220,6 @@ trait GameHelper: case Some(ThreefoldRepetition) => trans.threefoldRepetition.txt() + " • " + trans.draw.txt() case Some(InsufficientMaterial) => trans.insufficientMaterial.txt() + " • " + trans.draw.txt() case _ => trans.draw.txt() - } case S.Outoftime => (game.turnColor, game.loser) match case (White, Some(_)) => trans.whiteTimeOut.txt() @@ -227,7 +227,7 @@ trait GameHelper: case (Black, Some(_)) => trans.blackTimeOut.txt() case (Black, None) => trans.blackTimeOut.txt() + " • " + trans.draw.txt() case S.NoStart => - (if (game.loser.exists(_.color.white)) trans.whiteDidntMove else trans.blackDidntMove).txt() + (if game.loser.exists(_.color.white) then trans.whiteDidntMove else trans.blackDidntMove).txt() case S.Cheat => trans.cheatDetected.txt() case S.VariantEnd => game.variant match @@ -272,7 +272,7 @@ trait GameHelper: s"${titleNameOrId(reg.id)}${ctx.pref.showRatings so s" (${reg.rating.show})"}" } val players = - if (c.isOpen) "Open challenge" + if c.isOpen then "Open challenge" else c.destUser.fold(s"Challenge from $challenger") { dest => s"$challenger challenges ${titleNameOrId(dest.id)}${ctx.pref.showRatings so s" (${dest.rating.show})"}" diff --git a/app/templating/NumberHelper.scala b/app/templating/NumberHelper.scala index 83e504ec15e76..ca77254e7f874 100644 --- a/app/templating/NumberHelper.scala +++ b/app/templating/NumberHelper.scala @@ -5,7 +5,8 @@ import java.text.NumberFormat import java.util.concurrent.ConcurrentHashMap import play.api.i18n.Lang -trait NumberHelper { self: I18nHelper => +trait NumberHelper: + self: I18nHelper => private val formatters = new ConcurrentHashMap[String, NumberFormat] @@ -19,4 +20,3 @@ trait NumberHelper { self: I18nHelper => extension (e: Int) def localize(using Lang): String = formatter format e extension (e: Long) def localize(using Lang): String = formatter format e -} diff --git a/app/templating/SetupHelper.scala b/app/templating/SetupHelper.scala index 482ccfbf3a906..229539ad9fa27 100644 --- a/app/templating/SetupHelper.scala +++ b/app/templating/SetupHelper.scala @@ -10,7 +10,8 @@ import lila.pref.Pref import lila.report.Reason import lila.setup.TimeMode -trait SetupHelper { self: I18nHelper => +trait SetupHelper: + self: I18nHelper => type SelectChoice = (String, String, Option[String]) @@ -325,4 +326,3 @@ trait SetupHelper { self: I18nHelper => false -> trans.no.txt(), true -> trans.yes.txt() ) -} diff --git a/app/templating/StringHelper.scala b/app/templating/StringHelper.scala index 7456117731c0e..6cb883304260e 100644 --- a/app/templating/StringHelper.scala +++ b/app/templating/StringHelper.scala @@ -4,15 +4,16 @@ package templating import play.api.i18n.Lang import ui.ScalatagsTemplate.* -trait StringHelper { self: I18nHelper with NumberHelper => +trait StringHelper: + self: I18nHelper with NumberHelper => export lila.common.String.{ slugify, shorten, urlencode, addQueryParam, addQueryParams, underscoreFen } - def pluralize(s: String, n: Int) = s"$n $s${if (n != 1) "s" else ""}" + def pluralize(s: String, n: Int) = s"$n $s${if n != 1 then "s" else ""}" - def pluralizeLocalize(s: String, n: Int)(using Lang) = s"${n.localize} $s${if (n != 1) "s" else ""}" + def pluralizeLocalize(s: String, n: Int)(using Lang) = s"${n.localize} $s${if n != 1 then "s" else ""}" - def showNumber(n: Int): String = if (n > 0) s"+$n" else n.toString + def showNumber(n: Int): String = if n > 0 then s"+$n" else n.toString private val NumberFirstRegex = """(\d++)\s(.+)""".r private val NumberLastRegex = """\s(\d++)$""".r.unanchored @@ -45,4 +46,3 @@ trait StringHelper { self: I18nHelper with NumberHelper => extension (e: String) def active(other: String, one: String = "active") = if e == other then one else "" def activeO(other: String, one: String = "active") = e == other option one -} diff --git a/app/templating/TeamHelper.scala b/app/templating/TeamHelper.scala index b51b5fedf9034..34c857cc761b1 100644 --- a/app/templating/TeamHelper.scala +++ b/app/templating/TeamHelper.scala @@ -8,7 +8,8 @@ import controllers.routes import lila.app.ui.ScalatagsTemplate.{ *, given } import lila.hub.LightTeam.TeamName -trait TeamHelper { self: HasEnv with RouterHelper => +trait TeamHelper: + self: HasEnv with RouterHelper => def isMyTeamSync(teamId: TeamId)(using ctx: Context): Boolean = ctx.userId.so { env.team.api.syncBelongsTo(teamId, _) } @@ -31,4 +32,3 @@ trait TeamHelper { self: HasEnv with RouterHelper => lila.team.Team.variants.view.mapValues { team => (team, teamLink(team.id, team.name, true)) }.toMap -} diff --git a/app/templating/TournamentHelper.scala b/app/templating/TournamentHelper.scala index 5c7a94ac2ac99..b1906a68fa0dd 100644 --- a/app/templating/TournamentHelper.scala +++ b/app/templating/TournamentHelper.scala @@ -32,7 +32,7 @@ trait TournamentHelper extends HasEnv: def tournamentLink(tour: Tournament)(using Lang): Frag = a( dataIcon := licon.Trophy.value, - cls := (if (tour.isScheduled) "text is-gold" else "text"), + cls := (if tour.isScheduled then "text is-gold" else "text"), href := routes.Tournament.show(tour.id.value).url )(tour.name()) diff --git a/app/templating/UserHelper.scala b/app/templating/UserHelper.scala index a2dab17e57915..7d4c504bda4bb 100644 --- a/app/templating/UserHelper.scala +++ b/app/templating/UserHelper.scala @@ -12,13 +12,14 @@ import lila.i18n.{ I18nKey, I18nKeys as trans } import lila.rating.{ Perf, PerfType } import lila.user.{ User, UserPerfs } -trait UserHelper extends HasEnv { self: I18nHelper with StringHelper with NumberHelper with DateHelper => +trait UserHelper extends HasEnv: + self: I18nHelper with StringHelper with NumberHelper with DateHelper => given Conversion[User.WithPerfs, User] = _.user def ratingProgress(progress: IntRatingDiff): Option[Frag] = - if (progress > 0) goodTag(cls := "rp")(progress).some - else if (progress < 0) badTag(cls := "rp")(math.abs(progress.value)).some + if progress > 0 then goodTag(cls := "rp")(progress).some + else if progress < 0 then badTag(cls := "rp")(math.abs(progress.value)).some else none val topBarSortedPerfTypes: List[PerfType] = List( @@ -49,7 +50,7 @@ trait UserHelper extends HasEnv { self: I18nHelper with StringHelper with Number dataIcon := icon, cls := "text" )( - if clueless then frag(nbsp, nbsp, nbsp, if (nb < 1) "-" else "?") + if clueless then frag(nbsp, nbsp, nbsp, if nb < 1 then "-" else "?") else frag(rating, provisional.yes option "?") ) @@ -163,7 +164,7 @@ trait UserHelper extends HasEnv { self: I18nHelper with StringHelper with Number cls := userClass(userId, cssClass, withOnline), href := userUrl(username, params = params) )( - withOnline so (if (modIcon) moderatorIcon else lineIcon(isPatron)), + withOnline so (if modIcon then moderatorIcon else lineIcon(isPatron)), titleTag(title), truncate.fold(username.value)(username.value.take) ) @@ -236,16 +237,16 @@ trait UserHelper extends HasEnv { self: I18nHelper with StringHelper with Number withOnline: Boolean, withPowerTip: Boolean = true ): List[(String, Boolean)] = - if (User isGhost userId) List("user-link" -> true, ~cssClass -> cssClass.isDefined) + if User isGhost userId then List("user-link" -> true, ~cssClass -> cssClass.isDefined) else - (withOnline so List((if (isOnline(userId)) "online" else "offline") -> true)) ::: List( + (withOnline so List((if isOnline(userId) then "online" else "offline") -> true)) ::: List( "user-link" -> true, ~cssClass -> cssClass.isDefined, "ulpt" -> withPowerTip ) def userGameFilterTitle(u: User, nbs: UserInfo.NbGames, filter: GameFilter)(using Lang): Frag = - if (filter == GameFilter.Search) frag(iconTag(licon.Search), br, trans.search.advancedSearch()) + if filter == GameFilter.Search then frag(iconTag(licon.Search), br, trans.search.advancedSearch()) else splitNumber(userGameFilterTitleNoTag(u, nbs, filter)) private def transLocalize(key: I18nKey, number: Int)(using Lang) = key.pluralSameTxt(number) @@ -278,9 +279,8 @@ trait UserHelper extends HasEnv { self: I18nHelper with StringHelper with Number def patronIcon(using Lang): Frag = i(cls := "line patron", title := trans.patron.lichessPatron.txt()) val moderatorIcon: Frag = i(cls := "line moderator", title := "Lichess Mod") - private def lineIcon(patron: Boolean)(using Lang): Frag = if (patron) patronIcon else lineIcon + private def lineIcon(patron: Boolean)(using Lang): Frag = if patron then patronIcon else lineIcon private def lineIcon(user: Option[LightUser])(using Lang): Frag = lineIcon(user.so(_.isPatron)) def lineIcon(user: LightUser)(using Lang): Frag = lineIcon(user.isPatron) def lineIcon(user: User)(using Lang): Frag = lineIcon(user.isPatron) - def lineIconChar(user: User): Frag = if (user.isPatron) patronIconChar else lineIconChar -} + def lineIconChar(user: User): Frag = if user.isPatron then patronIconChar else lineIconChar diff --git a/app/ui/scalatags.scala b/app/ui/scalatags.scala index 2de80532ad4a5..8e46dad89c7e7 100644 --- a/app/ui/scalatags.scala +++ b/app/ui/scalatags.scala @@ -144,7 +144,7 @@ trait ScalatagsExtensions: given AttrValue[List[(String, Boolean)]] with def apply(t: Builder, a: Attr, m: List[(String, Boolean)]): Unit = val cls = m collect { case (s, true) => s } mkString " " - if (cls.nonEmpty) t.setAttr(a.name, Builder.GenericAttrValueSource(cls)) + if cls.nonEmpty then t.setAttr(a.name, Builder.GenericAttrValueSource(cls)) val emptyFrag: Frag = RawFrag("") given Zero[Frag] = Zero(emptyFrag) diff --git a/app/views/account/close.scala b/app/views/account/close.scala index 5b640343d6ccb..f353c0d40d6d1 100644 --- a/app/views/account/close.scala +++ b/app/views/account/close.scala @@ -17,8 +17,7 @@ object close: ) { div(cls := "account box box-pad")( boxTop(h1(cls := "text", dataIcon := licon.CautionCircle)(closeAccount())), - if (managed) - p(managedAccountCannotBeClosed()) + if managed then p(managedAccountCannotBeClosed()) else postForm(cls := "form3", action := routes.Account.closeConfirm)( div(cls := "form-group")(closeAccountExplanation()), diff --git a/app/views/account/kid.scala b/app/views/account/kid.scala index d3138b560ca8e..c11c21d0580e4 100644 --- a/app/views/account/kid.scala +++ b/app/views/account/kid.scala @@ -20,8 +20,7 @@ object kid: br, br, br, - if (managed) - p(trans.askYourChessTeacherAboutLiftingKidMode()) + if managed then p(trans.askYourChessTeacherAboutLiftingKidMode()) else postForm(cls := "form3", action := s"${routes.Account.kidPost}?v=${!u.kid}")( form3.passwordModified(form("passwd"), trans.password())(autofocus, autocomplete := "off"), @@ -30,8 +29,9 @@ object kid: "button" -> true, "button-red" -> u.kid ) - )(if (u.kid) trans.disableKidMode.txt() else trans.enableKidMode.txt()) - ), + )(if u.kid then trans.disableKidMode.txt() else trans.enableKidMode.txt()) + ) + , br, br, p(trans.inKidModeTheLichessLogoGetsIconX(span(cls := "kiddo", title := trans.kidMode.txt())(":)"))) diff --git a/app/views/account/notification.scala b/app/views/account/notification.scala index 0e841dbd7224d..ffd28b6cf9b8a 100644 --- a/app/views/account/notification.scala +++ b/app/views/account/notification.scala @@ -5,7 +5,7 @@ import lila.app.templating.Environment.{ given, * } import lila.app.ui.ScalatagsTemplate.{ *, given } import controllers.routes -object notification { +object notification: import bits.* import trans.preferences.* @@ -52,17 +52,16 @@ object notification { ) } - private def makeRow(form: play.api.data.Form[_])(transFrag: Frag, filterName: String) = + private def makeRow(form: play.api.data.Form[?])(transFrag: Frag, filterName: String) = tr( td(transFrag), Seq("bell", "push") map { allow => val name = s"$filterName.$allow" val checked = form.data(name).contains("true") td( - if (!hiddenFields(s"$filterName.$allow")) + if !hiddenFields(s"$filterName.$allow") then div(cls := "toggle", form3.cmnToggle(name, name, checked)) - else if (!checked) - div(iconTag(licon.X)) + else if !checked then div(iconTag(licon.X)) else div( cls := "always-on", @@ -82,4 +81,3 @@ object notification { "gameEvent.bell", "challenge.bell" ) -} diff --git a/app/views/account/security.scala b/app/views/account/security.scala index 56b6e5a1d37dc..d020bae02fea5 100644 --- a/app/views/account/security.scala +++ b/app/views/account/security.scala @@ -55,8 +55,8 @@ object security: tr( td(cls := "icon")( span( - cls := curSessionId.map { cur => s"is-${if (cur == s.session.id) "gold" else "green"}" }, - dataIcon := (if (s.session.isMobile) licon.PhoneMobile else licon.ScreenDesktop) + cls := curSessionId.map { cur => s"is-${if cur == s.session.id then "gold" else "green"}" }, + dataIcon := (if s.session.isMobile then licon.PhoneMobile else licon.ScreenDesktop) ) ), td(cls := "info")( @@ -87,13 +87,12 @@ object security: td(cls := "info")( strong(client.origin), p(cls := "ua")( - if (client.scopes.nonEmpty) + if client.scopes.nonEmpty then frag( "Third party application with permissions: ", client.scopes.map(_.name.txt()).mkString(", ") ) - else - frag("Third party application using only public data.") + else frag("Third party application using only public data.") ), client.usedAt map { usedAt => p(cls := "date")( diff --git a/app/views/activity.scala b/app/views/activity.scala index 2599cc6e3028d..e4d6e81ddb2fb 100644 --- a/app/views/activity.scala +++ b/app/views/activity.scala @@ -41,13 +41,13 @@ object activity: } ) - private def subCount(count: Int) = if (count >= maxSubEntries) s"$count+" else s"$count" + private def subCount(count: Int) = if count >= maxSubEntries then s"$count+" else s"$count" private def renderPatron(p: Patron)(using Context) = div(cls := "entry plan")( iconTag(licon.Wings), div( - if (p.months == 0) a(href := routes.Plan.index)("Lifetime Patron!") + if p.months == 0 then a(href := routes.Plan.index)("Lifetime Patron!") else trans.activity.supportedNbMonths.plural(p.months, p.months, a(href := routes.Plan.index)("Patron")) ) @@ -59,10 +59,9 @@ object activity: iconTag(licon.Bullseye), div( ps.headOption map onePractice, - ps match { + ps match case _ :: rest if rest.nonEmpty => subTag(rest map onePractice) case _ => emptyFrag - } ) ) @@ -224,7 +223,7 @@ object activity: div( List(all.in.map(_ -> true), all.out.map(_ -> false)).flatten map { (f, in) => frag( - if (in) trans.activity.gainedNbFollowers.pluralSame(f.actualNb) + if in then trans.activity.gainedNbFollowers.pluralSame(f.actualNb) else trans.activity.followedNbPlayers.pluralSame(f.actualNb), subTag( fragList(f.ids.map(id => userIdLink(id.some))), @@ -243,7 +242,7 @@ object activity: div( simuls.groupBy(_.isHost(u.some)).toSeq.map { (isHost, simuls) => frag( - if (isHost) trans.activity.hostedNbSimuls.pluralSame(simuls.size) + if isHost then trans.activity.hostedNbSimuls.pluralSame(simuls.size) else trans.activity.joinedNbSimuls.pluralSame(simuls.size), subTag( simuls.map: s => @@ -254,7 +253,7 @@ object activity: " simul by ", userIdLink(s.hostId.some) ), - if (isHost) scoreFrag(Score(s.wins, s.losses, s.draws, none)) + if isHost then scoreFrag(Score(s.wins, s.losses, s.draws, none)) else scoreFrag(Score(win.has(true) so 1, win.has(false) so 1, win.isEmpty so 1, none)) ) ) @@ -360,7 +359,7 @@ object activity: ctx.pref.showRatings option ratingTag(r.after.value, ratingProgress(r.diff)) private def scoreStr(tag: String, p: Int, name: lila.i18n.I18nKey)(using Context) = - if (p == 0) "" + if p == 0 then "" else s"""<$tag>${wrapNumber(name.pluralSameTxt(p))}""" private val wrapNumberRegex = """(\d++)""".r diff --git a/app/views/analyse/replay.scala b/app/views/analyse/replay.scala index 76fd6c840fd76..94fba2f93de14 100644 --- a/app/views/analyse/replay.scala +++ b/app/views/analyse/replay.scala @@ -171,7 +171,7 @@ object replay: ), div(cls := "analyse__underboard__panels")( game.analysable option div(cls := "computer-analysis")( - if (analysis.isDefined || analysisStarted) div(id := "acpl-chart") + if analysis.isDefined || analysisStarted then div(id := "acpl-chart") else postForm( cls := s"future-game-analysis${ctx.isAnon so " must-login"}", diff --git a/app/views/appeal/discussion.scala b/app/views/appeal/discussion.scala index c8292af18bd10..11a49202e9016 100644 --- a/app/views/appeal/discussion.scala +++ b/app/views/appeal/discussion.scala @@ -44,14 +44,14 @@ object discussion: main(cls := "box box-pad appeal")( renderAppeal(appeal, textForm, Left(modData)), div(cls := "appeal__actions", id := "appeal-actions")( - modData.inquiry match { + modData.inquiry match case None => postForm(action := routes.Mod.spontaneousInquiry(appeal.id))( submitButton(cls := "button")("Handle this appeal") ) case Some(Inquiry(mod, _)) if ctx.userId has mod => postForm(action := appealRoutes.mute(modData.suspect.user.username))( - if (appeal.isMuted) + if appeal.isMuted then submitButton("Un-mute")( title := "Be notified about user replies again", cls := "button button-green button-thin" @@ -63,7 +63,7 @@ object discussion: ) ) case Some(Inquiry(mod, _)) => frag(userIdLink(mod.some), nbsp, "is handling this.") - }, + , postForm( action := appealRoutes.sendToZulip(modData.suspect.user.id), cls := "appeal__actions__slack" @@ -107,10 +107,10 @@ object discussion: standardFlash, div(cls := "body")( appeal.msgs.map: msg => - div(cls := s"appeal__msg appeal__msg--${if (appeal isByMod msg) "mod" else "suspect"}")( + div(cls := s"appeal__msg appeal__msg--${if appeal isByMod msg then "mod" else "suspect"}")( div(cls := "appeal__msg__header")( renderUser(appeal, msg.by, as.isLeft), - if (as.isRight) momentFromNowOnce(msg.at) + if as.isRight then momentFromNowOnce(msg.at) else momentFromNowServer(msg.at) ), div(cls := "appeal__msg__text")(richText(msg.text, expandImg = false)) @@ -119,12 +119,12 @@ object discussion: .exists(_.markedByMe) option div(dataIcon := licon.CautionTriangle, cls := "marked-by-me text")( "You have marked this user. Appeal should be handled by another moderator" ), - if (as.isRight && !appeal.canAddMsg) p("Please wait for a moderator to reply.") + if as.isRight && !appeal.canAddMsg then p("Please wait for a moderator to reply.") else as.fold(_.inquiry.isDefined, _ => true) option renderForm( textForm, action = - if (as.isLeft) appealRoutes.reply(appeal.id).url + if as.isLeft then appealRoutes.reply(appeal.id).url else appealRoutes.post.url, isNew = false, presets = as.left.toOption.map(_.presets) @@ -134,15 +134,15 @@ object discussion: private def renderMark(suspect: User)(using ctx: PageContext) = val query = isGranted(_.Appeals) so ctx.req.queryString.toMap - if (suspect.enabled.no || query.contains("alt")) tree.closedByModerators - else if (suspect.marks.engine || query.contains("engine")) tree.engineMarked - else if (suspect.marks.boost || query.contains("boost")) tree.boosterMarked - else if (suspect.marks.troll || query.contains("shadowban")) tree.accountMuted - else if (suspect.marks.rankban || query.contains("rankban")) tree.excludedFromLeaderboards + if suspect.enabled.no || query.contains("alt") then tree.closedByModerators + else if suspect.marks.engine || query.contains("engine") then tree.engineMarked + else if suspect.marks.boost || query.contains("boost") then tree.boosterMarked + else if suspect.marks.troll || query.contains("shadowban") then tree.accountMuted + else if suspect.marks.rankban || query.contains("rankban") then tree.excludedFromLeaderboards else tree.cleanAllGood private def renderUser(appeal: Appeal, userId: UserId, asMod: Boolean)(using PageContext) = - if (appeal isAbout userId) userIdLink(userId.some, params = asMod so "?mod") + if appeal isAbout userId then userIdLink(userId.some, params = asMod so "?mod") else span( userIdLink(User.lichessId.some), @@ -160,7 +160,7 @@ object discussion: form3.globalError(form), form3.group( form("text"), - if (isNew) "Create an appeal" else "Add something to the appeal", + if isNew then "Create an appeal" else "Add something to the appeal", help = !isGranted(_.Appeals) option frag("Please be concise. Maximum 1000 chars.") )(f => form3.textarea(f.copy(constraints = Seq.empty))(rows := 6, maxlength := Appeal.maxLengthClient)), presets.map { ps => diff --git a/app/views/appeal/tree.scala b/app/views/appeal/tree.scala index 8f6d8c0a1fea6..cfbfaa42f2c9f 100644 --- a/app/views/appeal/tree.scala +++ b/app/views/appeal/tree.scala @@ -281,16 +281,16 @@ object tree: val isMarked = playban || me.marks.engine || me.marks.boost || me.marks.troll || me.marks.rankban main(cls := "page page-small box box-pad appeal force-ltr")( h1(cls := "box__top")("Appeal"), - div(cls := s"nav-tree${if (isMarked) " marked" else ""}")( - if ((me.enabled.no && !me.marks.anyVisible) || query.contains("alt")) altScreen + div(cls := s"nav-tree${if isMarked then " marked" else ""}")( + if (me.enabled.no && !me.marks.anyVisible) || query.contains("alt") then altScreen else renderNode( { - if (me.marks.engine || query.contains("engine")) engineMenu - else if (me.marks.boost || query.contains("boost")) boostMenu - else if (me.marks.troll || query.contains("shadowban")) muteMenu - else if (playban || query.contains("playban")) playbanMenu - else if (me.marks.rankban || query.contains("rankban")) rankBanMenu + if me.marks.engine || query.contains("engine") then engineMenu + else if me.marks.boost || query.contains("boost") then boostMenu + else if me.marks.troll || query.contains("shadowban") then muteMenu + else if playban || query.contains("playban") then playbanMenu + else if me.marks.rankban || query.contains("rankban") then rankBanMenu else cleanMenu }, none, diff --git a/app/views/auth/bits.scala b/app/views/auth/bits.scala index 894d833ef49a3..9227e22c3b692 100644 --- a/app/views/auth/bits.scala +++ b/app/views/auth/bits.scala @@ -17,7 +17,7 @@ object bits: frag( form3.group( username, - if (register) trans.username() else trans.usernameOrEmail(), + if register then trans.username() else trans.usernameOrEmail(), help = register option trans.signupUsernameHint() ) { f => frag( @@ -26,7 +26,7 @@ object bits: ) }, form3.passwordModified(password, trans.password())( - autocomplete := (if (register) "new-password" else "current-password") + autocomplete := (if register then "new-password" else "current-password") ), register option form3.passwordComplexityMeter(trans.newPasswordStrength()), email.map { email => @@ -81,11 +81,11 @@ object bits: ) { main(cls := "page-small box box-pad")( boxTop( - (ok match { + (ok match case Some(true) => h1(cls := "is-green text", dataIcon := licon.Checkmark) case Some(false) => h1(cls := "is-red text", dataIcon := licon.X) case _ => h1 - })( + )( userLink(me, withOnline = false), " - ", trans.changePassword() diff --git a/app/views/auth/checkYourEmail.scala b/app/views/auth/checkYourEmail.scala index 111890a4df4bf..cf8a93e7e5141 100644 --- a/app/views/auth/checkYourEmail.scala +++ b/app/views/auth/checkYourEmail.scala @@ -18,7 +18,7 @@ object checkYourEmail: moreCss = cssTag("email-confirm") ) { main( - cls := s"page-small box box-pad email-confirm ${if (form.exists(_.hasErrors)) "error" else "anim"}" + cls := s"page-small box box-pad email-confirm ${if form.exists(_.hasErrors) then "error" else "anim"}" )( boxTop(h1(cls := "is-green text", dataIcon := licon.Checkmark)(trans.checkYourEmail())), p(trans.weHaveSentYouAnEmailClickTheLink()), diff --git a/app/views/base/captcha.scala b/app/views/base/captcha.scala index a47469da82a2e..f602b4bcb2189 100644 --- a/app/views/base/captcha.scala +++ b/app/views/base/captcha.scala @@ -18,7 +18,7 @@ object captcha: frag( form3.hidden(form("gameId"), captcha.gameId.value.some), if ctx.blind then form3.hidden(form("move"), captcha.solutions.head.some) - else { + else val url = netBaseUrl + routes.Round.watcher(captcha.gameId.value, captcha.color.name) div( @@ -41,7 +41,7 @@ object captcha: ), div(cls := "captcha-explanation")( label(cls := "form-label")( - if (captcha.color.white) trans.whiteCheckmatesInOneMove() + if captcha.color.white then trans.whiteCheckmatesInOneMove() else trans.blackCheckmatesInOneMove() ), br, @@ -59,7 +59,6 @@ object captcha: form3.hidden(form("move")) ) ) - } ) def hiddenEmpty(form: lila.common.Form.FormLike) = frag( diff --git a/app/views/base/topnav.scala b/app/views/base/topnav.scala index 37eaca302228d..56c9acf05a4b9 100644 --- a/app/views/base/topnav.scala +++ b/app/views/base/topnav.scala @@ -9,7 +9,7 @@ import lila.app.ui.ScalatagsTemplate.{ *, given } object topnav: private def linkTitle(url: String, name: Frag)(using ctx: Context) = - if (ctx.blind) h3(name) else a(href := url)(name) + if ctx.blind then h3(name) else a(href := url)(name) private def canSeeClasMenu(using ctx: PageContext) = ctx.hasClas || ctx.me.exists(u => u.hasTitle || u.roles.contains("ROLE_COACH")) @@ -25,7 +25,7 @@ object topnav: ) ), div(role := "group")( - if (ctx.noBot) a(href := s"${langHref("/")}?any#hook")(trans.createAGame()) + if ctx.noBot then a(href := s"${langHref("/")}?any#hook")(trans.createAGame()) else a(href := "/?any#friend")(trans.playWithAFriend()), ctx.noBot option frag( a(href := langHref(routes.Tournament.home))(trans.arena.arenaTournaments()), diff --git a/app/views/board/bits.scala b/app/views/board/bits.scala index b9c4f68451151..697fd3a0dbfb7 100644 --- a/app/views/board/bits.scala +++ b/app/views/board/bits.scala @@ -12,7 +12,7 @@ object bits: private val dataState = attr("data-state") private def miniOrientation(pov: Pov): chess.Color = - if (pov.game.variant == chess.variant.RacingKings) chess.White else pov.player.color + if pov.game.variant == chess.variant.RacingKings then chess.White else pov.player.color def mini(pov: Pov): Tag => Tag = mini( diff --git a/app/views/challenge/mine.scala b/app/views/challenge/mine.scala index d50f7d4ccda5f..7bf2929baeba2 100644 --- a/app/views/challenge/mine.scala +++ b/app/views/challenge/mine.scala @@ -28,11 +28,11 @@ object mine: ) { val challengeLink = s"$netBaseUrl${routes.Round.watcher(c.id, "white")}" main(cls := s"page-small challenge-page box box-pad challenge--${c.status.name}")( - c.status match { + c.status match case Status.Created | Status.Offline => div(id := "ping-challenge")( h1(cls := "box__top")( - if (c.isOpen) c.name | "Open challenge" else trans.challenge.challengeToPlay.txt() + if c.isOpen then c.name | "Open challenge" else trans.challenge.challengeToPlay.txt() ), bits.details(c, color), c.destUserId.map { destId => @@ -42,7 +42,7 @@ object mine: p(trans.waitingForOpponent()) ) } getOrElse { - if (c.isOpen) + if c.isOpen then div(cls := "waiting")( spinner, p(trans.waitingForOpponent()) @@ -119,6 +119,5 @@ object mine: bits.details(c, color), a(cls := "button button-fat", href := routes.Lobby.home)(trans.newOpponent()) ) - } ) } diff --git a/app/views/challenge/theirs.scala b/app/views/challenge/theirs.scala index 33bf4f7b4d463..f57bf0e796da0 100644 --- a/app/views/challenge/theirs.scala +++ b/app/views/challenge/theirs.scala @@ -41,12 +41,12 @@ object theirs: fragList((~c.open.flatMap(_.userIdList)).map(uid => userIdLink(uid.some)), " and "), " to start the game." ) - else if (color.map(Challenge.ColorChoice.apply).has(c.colorChoice)) + else if color.map(Challenge.ColorChoice.apply).has(c.colorChoice) then badTag( // very rare message, don't translate s"You have the wrong color link for this open challenge. The ${color.so(_.name)} player has already joined." ) - else if (!c.mode.rated || ctx.isAuth) { + else if !c.mode.rated || ctx.isAuth then frag( (c.mode.rated && c.unlimited) option badTag(trans.bewareTheGameIsRatedButHasNoClock()), @@ -56,7 +56,7 @@ object theirs: ) ) ) - } else + else frag( hr, badTag( diff --git a/app/views/clas/bits.scala b/app/views/clas/bits.scala index 98c416fe74f74..f3445bded3695 100644 --- a/app/views/clas/bits.scala +++ b/app/views/clas/bits.scala @@ -18,7 +18,7 @@ object bits: moreCss = cssTag("clas"), moreJs = jsModule("clas") )( - if (isGranted(_.Teacher)) + if isGranted(_.Teacher) then main(cls := "page-menu")( st.nav(cls := "page-menu__menu subnav")( a(cls := active.toOption.map(_.active("classes")), href := routes.Clas.index)( diff --git a/app/views/clas/clas.scala b/app/views/clas/clas.scala index 044c5a7b6f944..9470e35179494 100644 --- a/app/views/clas/clas.scala +++ b/app/views/clas/clas.scala @@ -41,7 +41,7 @@ object clas: def teacherIndex(classes: List[Clas], closed: Boolean)(using PageContext) = val (active, archived) = classes.partition(_.isActive) - val (current, others) = if (closed) (archived, active) else (active, archived) + val (current, others) = if closed then (archived, active) else (active, archived) bits.layout(trans.clas.lichessClasses.txt(), Right("classes"))( cls := "clas-index", div(cls := "box__top")( @@ -53,16 +53,14 @@ object clas: dataIcon := licon.PlusButton ) ), - if (current.isEmpty) - frag(hr, p(cls := "box__pad classes__empty")(trans.clas.noClassesYet())) - else - renderClasses(current), + if current.isEmpty then frag(hr, p(cls := "box__pad classes__empty")(trans.clas.noClassesYet())) + else renderClasses(current), (closed || others.nonEmpty) option div(cls := "clas-index__others")( a(href := s"${clasRoutes.index}?closed=${!closed}")( "And ", others.size.localize, " ", - if (closed) "active" else "archived", + if closed then "active" else "archived", " classes" ) ) @@ -152,7 +150,7 @@ object clas: frag(trans.clas.classDescription()), help = trans.clas.visibleByBothStudentsAndTeachers().some )(form3.textarea(_)(rows := 5)), - clas match { + clas match case None => form3.hidden(form("teachers"), UserId raw ctx.userId) case Some(_) => form3.group( @@ -160,7 +158,7 @@ object clas: trans.clas.teachersOfTheClass(), help = trans.clas.addLichessUsernames().some )(form3.textarea(_)(rows := 4)) - }, + , form3.actions( a(href := clas.fold(clasRoutes.index)(c => clasRoutes.show(c.id.value)))(trans.cancel()), form3.submit(trans.apply()) diff --git a/app/views/clas/invite.scala b/app/views/clas/invite.scala index 0abe032343b7e..b82d759bb0ff8 100644 --- a/app/views/clas/invite.scala +++ b/app/views/clas/invite.scala @@ -31,7 +31,7 @@ object invite: invite.accepted.fold(true)(false.==) option postForm(cls := "form3", action := clasRoutes.invitationAccept(invite._id.value))( form3.actions( - if (!invite.accepted.has(false)) + if !invite.accepted.has(false) then form3.submit( trans.decline(), nameValue = ("v" -> false.toString).some, diff --git a/app/views/clas/studentDashboard.scala b/app/views/clas/studentDashboard.scala index 689f84c8761a6..eb21777e56b8f 100644 --- a/app/views/clas/studentDashboard.scala +++ b/app/views/clas/studentDashboard.scala @@ -95,7 +95,7 @@ object studentDashboard: ) private def challengeTd(user: lila.user.User)(using ctx: PageContext) = - if (ctx is user) td + if ctx is user then td else val online = isOnline(user.id) td( diff --git a/app/views/clas/teacherDashboard.scala b/app/views/clas/teacherDashboard.scala index b7cebf26fa7e1..bc6516ed50d7e 100644 --- a/app/views/clas/teacherDashboard.scala +++ b/app/views/clas/teacherDashboard.scala @@ -131,8 +131,8 @@ object teacherDashboard: trans.clas.variantXOverLastY(progress.perfType.trans, trans.nbDays.txt(progress.days)), dataSortNumberTh(trans.rating()), dataSortNumberTh(trans.clas.progress()), - dataSortNumberTh(if (progress.isPuzzle) trans.puzzles() else trans.games()), - if (progress.isPuzzle) dataSortNumberTh(trans.clas.winrate()) + dataSortNumberTh(if progress.isPuzzle then trans.puzzles() else trans.games()), + if progress.isPuzzle then dataSortNumberTh(trans.clas.winrate()) else dataSortNumberTh(trans.clas.timePlaying()), th ) @@ -149,10 +149,10 @@ object teacherDashboard: ratingProgress(prog.ratingProgress) | trans.clas.na.txt() ), td(prog.nb), - if (progress.isPuzzle) td(dataSort := prog.winRate)(prog.winRate, "%") + if progress.isPuzzle then td(dataSort := prog.winRate)(prog.winRate, "%") else td(dataSort := prog.millis)(showDuration(prog.duration)), td( - if (progress.isPuzzle) + if progress.isPuzzle then a(href := routes.Puzzle.dashboard(progress.days, "home", user.username.value.some))( trans.puzzle.puzzleDashboard() ) diff --git a/app/views/clas/wall.scala b/app/views/clas/wall.scala index 85c4f008acc4c..b9561469de722 100644 --- a/app/views/clas/wall.scala +++ b/app/views/clas/wall.scala @@ -27,10 +27,8 @@ object wall: trans.clas.notifyAllStudents() ) ), - if (c.wall.value.isEmpty) - div(cls := "box__pad clas-wall clas-wall--empty")(trans.clas.nothingHere()) - else - div(cls := "box__pad clas-wall")(rawHtml(html)) + if c.wall.value.isEmpty then div(cls := "box__pad clas-wall clas-wall--empty")(trans.clas.nothingHere()) + else div(cls := "box__pad clas-wall")(rawHtml(html)) ) def edit(c: Clas, students: List[Student.WithUser], form: Form[?])(using PageContext) = diff --git a/app/views/coach/edit.scala b/app/views/coach/edit.scala index e7dddfa87af19..3fb8e50530a43 100644 --- a/app/views/coach/edit.scala +++ b/app/views/coach/edit.scala @@ -40,7 +40,7 @@ object edit: div(cls := "account coach-edit box")( div(cls := "top")( div(cls := "picture_wrap")( - if (c.coach.hasPicture) + if c.coach.hasPicture then a( cls := "upload_picture", href := routes.Coach.picture, diff --git a/app/views/coach/index.scala b/app/views/coach/index.scala index 3ae4113436949..275aa802e3a75 100644 --- a/app/views/coach/index.scala +++ b/app/views/coach/index.scala @@ -46,7 +46,7 @@ object index: p( areYouCoach(a(href := "https://lichess.org/help/master")(nmOrFideTitle())), br, - if (!ctx.me.exists(_.hasTitle)) a(href := routes.Main.verifyTitle)(confirmTitle()) + if !ctx.me.exists(_.hasTitle) then a(href := routes.Main.verifyTitle)(confirmTitle()) else sendApplication(a(href := s"mailto:$contactEmailInClear")(contactEmailInClear)) ) ), diff --git a/app/views/coach/show.scala b/app/views/coach/show.scala index eaab4c4126fcc..8076c256beab0 100644 --- a/app/views/coach/show.scala +++ b/app/views/coach/show.scala @@ -44,9 +44,9 @@ object show: a(cls := "button button-empty", href := routes.User.show(c.user.username))( viewXProfile(c.user.username) ), - if (ctx.me.exists(_ is c.coach)) + if ctx.me.exists(_ is c.coach) then frag( - if (c.coach.listed.value) p("This page is now public.") + if c.coach.listed.value then p("This page is now public.") else "This page is not public yet. ", a(href := routes.Coach.edit, cls := "text", dataIcon := licon.Pencil)("Edit my coach profile") ) diff --git a/app/views/coach/widget.scala b/app/views/coach/widget.scala index 8da5e3d55330b..931c6abab991b 100644 --- a/app/views/coach/widget.scala +++ b/app/views/coach/widget.scala @@ -22,13 +22,15 @@ object widget: val profile = c.user.profileOrDefault frag( link option a(cls := "overlay", href := routes.Coach.show(c.user.username)), - picture.thumbnail(c, if (link) 300 else 350), + picture.thumbnail(c, if link then 300 else 350), div(cls := "overview")( - (if (link) h2 else h1) (cls := "coach-name")(titleName(c)), + (if link then h2 else h1) (cls := "coach-name")(titleName(c)), c.coach.profile.headline .map: h => p( - cls := s"headline ${if (h.length < 60) "small" else if (h.length < 120) "medium" else "large"}" + cls := s"headline ${ + if h.length < 60 then "small" else if h.length < 120 then "medium" else "large" + }" )(h), table( tbody( diff --git a/app/views/dev.scala b/app/views/dev.scala index 0dd436f0e63f5..5e25d8613e2cd 100644 --- a/app/views/dev.scala +++ b/app/views/dev.scala @@ -23,10 +23,10 @@ object dev: settings.map { s => postForm(action := routes.Dev.settingsPost(s.id))( p(s.text | s.id), - s.form.value match { + s.form.value match case Some(v: Boolean) => div(span(cls := "form-check-input")(form3.cmnToggle(s.id, "v", v))) case v => input(name := "v", value := v.map(_.toString)) - }, + , submitButton(cls := "button button-empty", dataIcon := licon.Checkmark) ) } diff --git a/app/views/dgt.scala b/app/views/dgt.scala index 984b89f2eb08a..98611ebb521b7 100644 --- a/app/views/dgt.scala +++ b/app/views/dgt.scala @@ -90,7 +90,7 @@ object dgt: form(action := routes.DgtCtrl.generateToken, method := "post")( st.section( h2("Lichess connectivity"), - if (token.isDefined) + if token.isDefined then p(cls := "text", dataIcon := licon.Checkmark)( "You have an OAuth token suitable for DGT play.", br, diff --git a/app/views/event.scala b/app/views/event.scala index 07d4bf2ad7a30..752ae6306ccea 100644 --- a/app/views/event.scala +++ b/app/views/event.scala @@ -64,8 +64,8 @@ object event: e.description.map { d => div(cls := "desc")(markdown(e, d)) }, - if (e.isFinished) p(cls := "desc")("The event is finished.") - else if (e.isNow) a(href := e.url, cls := "button button-fat")(trans.eventInProgress()) + if e.isFinished then p(cls := "desc")("The event is finished.") + else if e.isNow then a(href := e.url, cls := "button button-fat")(trans.eventInProgress()) else ul(cls := "countdown", dataSeconds := (~e.secondsToStart + 1))( List("Days", "Hours", "Minutes", "Seconds") map { t => diff --git a/app/views/forum/post.scala b/app/views/forum/post.scala index 83ae5180fba93..7a25531eeebf0 100644 --- a/app/views/forum/post.scala +++ b/app/views/forum/post.scala @@ -71,7 +71,7 @@ object post: ).some else frag( - if (canModCateg || topic.isUblogAuthor(me)) + if canModCateg || topic.isUblogAuthor(me) then a( cls := "mod delete button button-empty", href := routes.ForumPost.delete(categ.slug, post.id), @@ -144,7 +144,7 @@ object post: title := { if size > 0 then val who = - if (size > 10) s"${users take 8 mkString ", "} and ${size - 8} others" + if size > 10 then s"${users take 8 mkString ", "} and ${size - 8} others" else users mkString ", " s"$who reacted with $r" else r.key diff --git a/app/views/forum/search.scala b/app/views/forum/search.scala index f95bf4b5b492b..0849dd94d0f97 100644 --- a/app/views/forum/search.scala +++ b/app/views/forum/search.scala @@ -35,7 +35,7 @@ object search: bits.authorLink(view.post) ) tr(cls := "paginated")( - if (viewWithRead.canRead) + if viewWithRead.canRead then frag( td( a(cls := "post", href := routes.ForumPost.redirect(view.post.id))( diff --git a/app/views/forum/topic.scala b/app/views/forum/topic.scala index 27c0731fa6969..5f16b981ad41b 100644 --- a/app/views/forum/topic.scala +++ b/app/views/forum/topic.scala @@ -127,11 +127,9 @@ object topic: ), pager, div(cls := "forum-topic__actions")( - if (topic.isOld) - p(trans.thisTopicIsArchived()) - else if (formWithCaptcha.isDefined) - h2(id := "reply")(trans.replyToThisTopic()) - else if (topic.closed) p(trans.thisTopicIsNowClosed()) + if topic.isOld then p(trans.thisTopicIsArchived()) + else if formWithCaptcha.isDefined then h2(id := "reply")(trans.replyToThisTopic()) + else if topic.closed then p(trans.thisTopicIsNowClosed()) else teamOnly.map { teamId => p( @@ -140,13 +138,14 @@ object topic: ) ) } orElse { - if (ctx.me.exists(_.isBot)) p("Bots cannot post in the forum.").some + if ctx.me.exists(_.isBot) then p("Bots cannot post in the forum.").some else ctx.isAuth option p(trans.youCannotPostYetPlaySomeGames()) - }, + } + , div( unsub.map { uns => postForm( - cls := s"unsub ${if (uns) "on" else "off"}", + cls := s"unsub ${if uns then "on" else "off"}", action := routes.Timeline.unsub(s"forum:${topic.id}") )( button(cls := "button button-empty text on", dataIcon := licon.Eye, bits.dataUnsub := "off")( @@ -160,13 +159,13 @@ object topic: canModCateg || (topic.isUblog && ctx.me.exists(topic.isAuthor)) option postForm(action := routes.ForumTopic.close(categ.slug, topic.slug))( button(cls := "button button-empty button-red")( - if (topic.closed) "Reopen" else "Close" + if topic.closed then "Reopen" else "Close" ) ), canModCateg option postForm(action := routes.ForumTopic.sticky(categ.slug, topic.slug))( button(cls := "button button-empty button-brag")( - if (topic.isSticky) "Unsticky" else "Sticky" + if topic.isSticky then "Unsticky" else "Sticky" ) ), canModCateg || ctx.me.exists(topic.isAuthor) option deleteModal diff --git a/app/views/game/bits.scala b/app/views/game/bits.scala index 06fc343c3dac5..26a34610de225 100644 --- a/app/views/game/bits.scala +++ b/app/views/game/bits.scala @@ -55,7 +55,7 @@ object bits: case v => routes.ContentPage.variant(v.key).url , title = variant.title, - name = (if (shortName && variant == chess.variant.KingOfTheHill) variant.shortName + name = (if shortName && variant == chess.variant.KingOfTheHill then variant.shortName else variant.name).toUpperCase ) else if perfType == Correspondence then diff --git a/app/views/game/crosstable.scala b/app/views/game/crosstable.scala index d3486bc469d8c..b3b478aac1a8d 100644 --- a/app/views/game/crosstable.scala +++ b/app/views/game/crosstable.scala @@ -39,7 +39,9 @@ object crosstable: matchup.map: m => div(cls := "crosstable__matchup force-ltr", title := trans.currentMatchScore.txt()): ct.users.toList.map: u => - span(cls := m.users.winnerId.map(w => if (w == u.id) "win" else "loss"))(m.users.showScore(u.id)) + span(cls := m.users.winnerId.map(w => if w == u.id then "win" else "loss"))( + m.users.showScore(u.id) + ) , div(cls := "crosstable__users"): ct.users.toList.map: u => @@ -47,5 +49,5 @@ object crosstable: , div(cls := "crosstable__score force-ltr", title := trans.lifetimeScore.txt()): ct.users.toList.map: u => - span(cls := ct.users.winnerId.map(w => if (w == u.id) "win" else "loss"))(ct.showScore(u.id)) + span(cls := ct.users.winnerId.map(w => if w == u.id then "win" else "loss"))(ct.showScore(u.id)) ) diff --git a/app/views/game/mini.scala b/app/views/game/mini.scala index 0a076f9cad8a8..b91f477a89ec4 100644 --- a/app/views/game/mini.scala +++ b/app/views/game/mini.scala @@ -29,7 +29,7 @@ object mini: ) def noCtx(pov: Pov, tv: Boolean = false): Tag = - val link = if (tv) routes.Tv.index else routes.Round.watcher(pov.gameId, pov.color.name) + val link = if tv then routes.Tv.index else routes.Round.watcher(pov.gameId, pov.color.name) renderMini(pov, link.url.some)(using defaultLang) private def renderMini( @@ -39,7 +39,7 @@ object mini: )(using Lang): Tag = val game = pov.game val isLive = game.isBeingPlayed - val tag = if (link.isDefined) a else span + val tag = if link.isDefined then a else span tag( href := link, cls := s"mini-game mini-game-${game.id} mini-game--init ${game.variant.key} is2d", @@ -60,14 +60,14 @@ object mini: playerUsername(pov.player.light, withRating = false), withRating option span(cls := "rating")(lila.game.Namer ratingString pov.player) ), - if (pov.game.finished) renderResult(pov) + if pov.game.finished then renderResult(pov) else pov.game.clock.map { renderClock(_, pov.color) } ) private def renderResult(pov: Pov) = span(cls := "mini-game__result")( pov.game.winnerColor.fold("½") { c => - if (c == pov.color) "1" else "0" + if c == pov.color then "1" else "0" } ) diff --git a/app/views/game/widgets.scala b/app/views/game/widgets.scala index 13a9a320d986e..c5194f8c0ea04 100644 --- a/app/views/game/widgets.scala +++ b/app/views/game/widgets.scala @@ -63,10 +63,10 @@ object widgets: gamePlayer(g.blackPlayer) ), div(cls := "result")( - if (g.isBeingPlayed) trans.playingRightNow() - else { - if (g.finishedOrAborted) - span(cls := g.winner.flatMap(w => fromPlayer.map(p => if (p == w) "win" else "loss")))( + if g.isBeingPlayed then trans.playingRightNow() + else + if g.finishedOrAborted then + span(cls := g.winner.flatMap(w => fromPlayer.map(p => if p == w then "win" else "loss")))( gameEndStatus(g), g.winner.map { winner => frag( @@ -76,9 +76,8 @@ object widgets: } ) else g.turnColor.fold(trans.whitePlays(), trans.blackPlays()) - } ), - if (g.playedTurns > 0) { + if g.playedTurns > 0 then div(cls := "opening")( (!g.fromPosition so g.opening) map { opening => strong(opening.opening.name) @@ -92,7 +91,7 @@ object widgets: g.ply > 6 option s" ... ${1 + (g.ply.value - 1) / 2} moves " ) ) - } else frag(br, br), + else frag(br, br), notes get g.id map { note => div(cls := "notes")(strong("Notes: "), note) }, diff --git a/app/views/irwin.scala b/app/views/irwin.scala index 80f7bfab24668..b8f6266dbceb7 100644 --- a/app/views/irwin.scala +++ b/app/views/irwin.scala @@ -25,7 +25,7 @@ object irwin: boxTop( h1( "Irwin status: ", - if (dashboard.seenRecently) span(cls := "up")("Operational") + if dashboard.seenRecently then span(cls := "up")("Operational") else span(cls := "down")( dashboard.lastSeenAt.map { seenAt => diff --git a/app/views/kaladin.scala b/app/views/kaladin.scala index 8201316a49f09..6b06878079455 100644 --- a/app/views/kaladin.scala +++ b/app/views/kaladin.scala @@ -25,7 +25,7 @@ object kaladin: boxTop( h1( "Kaladin status: ", - if (dashboard.seenRecently) span(cls := "up")("Operational") + if dashboard.seenRecently then span(cls := "up")("Operational") else span(cls := "down")( dashboard.lastSeenAt.map { seenAt => @@ -61,10 +61,9 @@ object kaladin: td(cls := "little")(entry.startedAt map { momentFromNow(_) }), td(cls := "little completed")(entry.response.map(_.at) map { momentFromNow(_) }), td { - entry.queuedBy match { + entry.queuedBy match case KaladinUser.Requester.Mod(id) => userIdLink(id.some) case requester => em(requester.name) - } }, entry.response.fold(td) { res => res.pred diff --git a/app/views/lobby/bits.scala b/app/views/lobby/bits.scala index 07760154470b7..c50721bc10244 100644 --- a/app/views/lobby/bits.scala +++ b/app/views/lobby/bits.scala @@ -40,7 +40,7 @@ object bits: ) ) ), - div(cls := s"lobby__box ${if (ctx.pref.showRatings) "lobby__winners" else "lobby__wide-winners"}")( + div(cls := s"lobby__box ${if ctx.pref.showRatings then "lobby__winners" else "lobby__wide-winners"}")( div(cls := "lobby__box__top")( h2(cls := "title text", dataIcon := licon.Trophy)(trans.tournamentWinners()), a(cls := "more", href := routes.Tournament.leaderboard)(trans.more(), " »") @@ -165,7 +165,7 @@ object bits: br, postForm(action := routes.Round.resign(current.pov.fullId))( button(cls := "text button button-red", dataIcon := licon.X)( - if (current.pov.game.abortableByUser) trans.abortTheGame() else trans.resignTheGame() + if current.pov.game.abortableByUser then trans.abortTheGame() else trans.resignTheGame() ) ), br, @@ -182,7 +182,7 @@ object bits: def spotlight(e: lila.event.Event)(using PageContext) = a( - href := (if (e.isNow || !e.countdown) e.url else routes.Event.show(e.id).url), + href := (if e.isNow || !e.countdown then e.url else routes.Event.show(e.id).url), cls := List( s"tour-spotlight event-spotlight id_${e.id}" -> true, "invert" -> e.isNowOrSoon @@ -193,7 +193,7 @@ object bits: span(cls := "name")(e.title), span(cls := "headline")(e.headline), span(cls := "more")( - if (e.isNow) trans.eventInProgress() else momentFromNow(e.startsAt) + if e.isNow then trans.eventInProgress() else momentFromNow(e.startsAt) ) ) ) diff --git a/app/views/mod/activity.scala b/app/views/mod/activity.scala index 64f1ba35cf471..19f0ff41e45cd 100644 --- a/app/views/mod/activity.scala +++ b/app/views/mod/activity.scala @@ -37,7 +37,7 @@ object activity: views.html.base.bits .mselect( s"mod-activity__who-select box__top__actions", - span(if (p.who == Who.Team) "Team" else "My"), + span(if p.who == Who.Team then "Team" else "My"), List( a( cls := (p.who == Who.Team).option("current"), diff --git a/app/views/mod/chatPanic.scala b/app/views/mod/chatPanic.scala index 53dc35862cac3..534f61e637e6d 100644 --- a/app/views/mod/chatPanic.scala +++ b/app/views/mod/chatPanic.scala @@ -33,7 +33,7 @@ object chatPanic: } getOrElse badTag(cls := "text", dataIcon := licon.X)(strong("DISABLED")) ), div(cls := "forms")( - if (state.isDefined) + if state.isDefined then frag( postForm(action := s"${routes.Mod.chatPanicPost}?v=0")( submitButton(cls := "button button-fat button-red text", dataIcon := licon.X)("Disable") diff --git a/app/views/mod/communication.scala b/app/views/mod/communication.scala index 8683077a46716..099db0394bc6c 100644 --- a/app/views/mod/communication.scala +++ b/app/views/mod/communication.scala @@ -48,7 +48,7 @@ object communication: dataIcon := licon.Agent ), isGranted(_.ViewPrivateComms) option { - if (priv) + if priv then a(cls := "priv button active", href := routes.Mod.communicationPublic(u.username))("PMs") else a( @@ -98,7 +98,7 @@ object communication: ) ), h2("Dubious public chats"), - if (publicLines.isEmpty) strong("None!") + if publicLines.isEmpty then strong("None!") else ul(cls := "public_chats")( publicLines.reverse.map: line => @@ -116,7 +116,8 @@ object communication: nbsp, span(cls := "message")(highlightBad(line.text)) ) - ), + ) + , priv option frag( h2("Recent private chats"), div(cls := "player_chats")( @@ -170,7 +171,7 @@ object communication: val author = msg.user == u.id tr(cls := List("post" -> true, "author" -> author))( td(momentFromNowServer(msg.date)), - td(strong(if (author) u.username else modConvo.contact.username)), + td(strong(if author then u.username else modConvo.contact.username)), td(cls := "message")(highlightBad(msg.text)) ) ) @@ -184,7 +185,7 @@ object communication: // incompatible with richText def highlightBad(text: String): Frag = val words = Analyser(text).badWords - if (words.isEmpty) frag(text) + if words.isEmpty then frag(text) else val regex = ("""(?iu)\b""" + words.mkString("(", "|", ")") + """\b""").r def tag(word: String) = s"$word" diff --git a/app/views/mod/emailConfirm.scala b/app/views/mod/emailConfirm.scala index 99a69ae377e20..bc777e8fbd4ae 100644 --- a/app/views/mod/emailConfirm.scala +++ b/app/views/mod/emailConfirm.scala @@ -59,8 +59,8 @@ this.setSelectionRange(this.value.length, this.value.length); td(momentFromNow(u.createdAt)), td(u.seenAt.map(momentFromNow(_))), td(style := "font-size:2em")( - if (!u.everLoggedIn) iconTag(licon.Checkmark)(cls := "is-green") - else iconTag(licon.X)(cls := "is-red") + if !u.everLoggedIn then iconTag(licon.Checkmark)(cls := "is-green") + else iconTag(licon.X)(cls := "is-red") ) ) ) diff --git a/app/views/mod/games.scala b/app/views/mod/games.scala index 51e826a09a1bf..624d0058c6b15 100644 --- a/app/views/mod/games.scala +++ b/app/views/mod/games.scala @@ -139,22 +139,21 @@ object games: ), td(dataSort := pov.moves)(pov.moves), td(dataSort := ~pov.player.ratingDiff)( - pov.win match { + pov.win match case Some(true) => goodTag(cls := "result")("1") case Some(false) => badTag(cls := "result")("0") case None => span(cls := "result")("½") - }, - pov.player.ratingDiff match { + , + pov.player.ratingDiff match case Some(d) if d > 0 => goodTag(s"+$d") case Some(d) if d < 0 => badTag(d) case _ => span("-") - } ), - assessment match { + assessment match case Some(Left(full)) => td(dataSort := full.analysis.avg)(full.analysis.toString) case _ => td - }, - assessment match { + , + assessment match case Some(ass) => ass.fold(_.basics, identity) pipe { basics => frag( @@ -171,7 +170,7 @@ object games: ) } case _ => frag(td, td) - }, + , td(dataSort := pov.game.movedAt.toSeconds.toString)( a(href := routes.Round.watcher(pov.gameId, pov.color.name), cls := "glpt")( momentFromNowServerText(pov.game.movedAt) diff --git a/app/views/mod/inquiry.scala b/app/views/mod/inquiry.scala index edde29b3e5796..861b75ff535f2 100644 --- a/app/views/mod/inquiry.scala +++ b/app/views/mod/inquiry.scala @@ -33,7 +33,7 @@ object inquiry: frag( link, " ", - if (highlight) communication.highlightBad(text) else frag(text), + if highlight then communication.highlightBad(text) else frag(text), " " ) } @@ -167,7 +167,7 @@ object inquiry: div(cls := "dropper shadowban buttons")( postForm( action := url, - title := (if (in.user.marks.troll) "Un-shadowban" else "Shadowban"), + title := (if in.user.marks.troll then "Un-shadowban" else "Shadowban"), cls := "main" )( markButton(in.user.marks.troll)(dataIcon := licon.BubbleSpeech), @@ -191,7 +191,7 @@ object inquiry: div( isGranted(_.SendToZulip) option { val url = - if (in.report.isAppeal) appealRoutes.sendToZulip(in.user.username) + if in.report.isAppeal then appealRoutes.sendToZulip(in.user.username) else routes.Mod.inquiryToZulip postForm(action := url)( submitButton(cls := "fbt")("Send to Zulip") @@ -279,7 +279,7 @@ object inquiry: ) private def snoozeUrl(report: Report, duration: String): String = - if (report.isAppeal) appealRoutes.snooze(report.user, duration).url + if report.isAppeal then appealRoutes.snooze(report.user, duration).url else reportRoutes.snooze(report.id, duration).url private def boostOpponents( diff --git a/app/views/mod/menu.scala b/app/views/mod/menu.scala index d869bf147970b..f95f0a2273419 100644 --- a/app/views/mod/menu.scala +++ b/app/views/mod/menu.scala @@ -41,7 +41,7 @@ object menu: isGranted(_.Shadowban) option a(cls := active.active("panic"), href := routes.Mod.chatPanic)( "Chat Panic: ", - strong(if (isChatPanicEnabled) "ON" else "OFF") + strong(if isChatPanicEnabled then "ON" else "OFF") ), isGranted(_.Admin) option a(cls := active.active("mods"), href := routes.Mod.table)("Mods"), diff --git a/app/views/mod/search.scala b/app/views/mod/search.scala index ae2031c83e938..a854a15cf98bd 100644 --- a/app/views/mod/search.scala +++ b/app/views/mod/search.scala @@ -58,16 +58,16 @@ object search: div(cls := "mod-search page-menu__content box")( boxTop( h1("Fingerprint: ", fh.value), - if (isGranted(_.Admin)) + if isGranted(_.Admin) then postForm(cls := "box__top__actions", action := routes.Mod.printBan(!blocked, fh.value))( submitButton( cls := List( "button text" -> true, "active" -> blocked ) - )(if (blocked) "Banned" else "Ban this print") + )(if blocked then "Banned" else "Ban this print") ) - else if (blocked) div(cls := "banned")("BANNED") + else if blocked then div(cls := "banned")("BANNED") else emptyFrag ), isGranted(_.Admin) option div(cls := "box__pad")( @@ -96,16 +96,16 @@ object search: div(cls := "mod-search page-menu__content box")( boxTop( h1("IP address: ", renderIp(address)), - if (isGranted(_.Admin)) + if isGranted(_.Admin) then postForm(cls := "box__top__actions", action := routes.Mod.singleIpBan(!blocked, address.value))( submitButton( cls := List( "button text" -> true, "active" -> blocked ) - )(if (blocked) "Banned" else "Ban this IP") + )(if blocked then "Banned" else "Ban this IP") ) - else if (blocked) div(cls := "banned")("BANNED") + else if blocked then div(cls := "banned")("BANNED") else emptyFrag ), isGranted(_.Admin) option div(cls := "box__pad")( @@ -168,11 +168,11 @@ object search: td(a(href := clasRoutes.show(c.id.value))(s"${c.id}")), td(c.name), td(momentFromNow(c.created.at)), - c.archived match { + c.archived match case None => td("No") case Some(lila.clas.Clas.Recorded(closerId, at)) => td(userIdLink(closerId.some), nbsp, momentFromNow(at)) - }, + , td(c.teachers.toList.map(id => teacherLink(id))) ) ) diff --git a/app/views/oAuth/token/index.scala b/app/views/oAuth/token/index.scala index 7c2ca577b6060..4936e3fca4054 100644 --- a/app/views/oAuth/token/index.scala +++ b/app/views/oAuth/token/index.scala @@ -50,8 +50,8 @@ object index: ), tokens.headOption.filter(_.isBrandNew).map { token => div(cls := "box__pad brand")( - if (token.isDangerous) iconTag(licon.CautionTriangle)(cls := "is-red") - else iconTag(licon.Checkmark)(cls := "is-green"), + if token.isDangerous then iconTag(licon.CautionTriangle)(cls := "is-red") + else iconTag(licon.Checkmark)(cls := "is-green"), div( if token.isDangerous then p(strong(trans.oauthScope.doNotShareIt())) diff --git a/app/views/opening/show.scala b/app/views/opening/show.scala index 950072738f783..2324976ee3d30 100644 --- a/app/views/opening/show.scala +++ b/app/views/opening/show.scala @@ -45,7 +45,7 @@ object show: case Right((name, key)) => val className = s"opening__name__section opening__name__section--${i + 1}" frag( - if (i == 0) emptyFrag else if (i == 1) ": " else ", ", + if i == 0 then emptyFrag else if i == 1 then ": " else ", ", key.fold(span(cls := className)(name)) { k => a(href := keyUrl(k))(cls := className)(name) } @@ -82,7 +82,7 @@ object show: href := s"${routes.UserAnalysis.pgn(page.query.sans mkString "_")}#explorer" )(trans.openingExplorer()) ), - if (page.explored.so(_.history).nonEmpty) + if page.explored.so(_.history).nonEmpty then div(cls := "opening__popularity opening__popularity--chart")( canvas(cls := "opening__popularity__chart") ) diff --git a/app/views/opening/tree.scala b/app/views/opening/tree.scala index 293909d55601d..9ba4066099c50 100644 --- a/app/views/opening/tree.scala +++ b/app/views/opening/tree.scala @@ -36,11 +36,11 @@ object tree: node.children map { case (op, node) => val fold = level < 4 && node.children.nonEmpty val content = frag( - (if (fold) summary else div) (op match { + (if fold then summary else div) (op match case (name, None) => name case (name, Some(op)) => a(href := openingUrl(op))(name) - }), + ), renderChildren(node, level + 1) ) - if (fold) details(content) else content + if fold then details(content) else content } diff --git a/app/views/opening/wiki.scala b/app/views/opening/wiki.scala index ac0375e094711..fddc5d993d7d9 100644 --- a/app/views/opening/wiki.scala +++ b/app/views/opening/wiki.scala @@ -23,7 +23,7 @@ object wiki: (page.query.openingAndExtraMoves._1.isDefined && isGranted(_.OpeningWiki)) option { details(cls := "opening__wiki__editor")( summary(cls := "opening__wiki__editor__summary")("Edit the description", priorityTag(page)), - page.query.exactOpening match { + page.query.exactOpening match case Some(op) => frag( postForm(action := routes.Opening.wikiWrite(op.key, page.query.pgnUnderscored))( @@ -52,7 +52,6 @@ object wiki: ) ) } - } ) } ) @@ -68,8 +67,7 @@ object wiki: ) private val priorityTexts = Vector("Highest", "High", "Average", "Low", "Lowest") - def priorityTag(page: OpeningPage) = { + def priorityTag(page: OpeningPage) = val score = page.explored.fold(priorityTexts.size - 1)(OpeningWiki.priorityOf) val text = priorityTexts.lift(score) | priorityTexts.last strong(cls := s"priority priority--$score")(text, " priority") - } diff --git a/app/views/plan/index.scala b/app/views/plan/index.scala index 8669784415353..b8f15fc570e87 100644 --- a/app/views/plan/index.scala +++ b/app/views/plan/index.scala @@ -72,7 +72,7 @@ object index: iconTag(patronIconChar), div( h1(cls := "box__top")(thankYou()), - if (p.isLifetime) youHaveLifetime() + if p.isLifetime then youHaveLifetime() else p.expiresAt.map { expires => frag( @@ -207,7 +207,7 @@ object index: ), div(cls := "service")( div(cls := "buttons")( - if (ctx.isAuth) + if ctx.isAuth then frag( button(cls := "stripe button")(withCreditCard()), div(cls := "paypal paypal--order"), diff --git a/app/views/plan/indexPayPal.scala b/app/views/plan/indexPayPal.scala index d9bce1d1f970c..cf929385c39bb 100644 --- a/app/views/plan/indexPayPal.scala +++ b/app/views/plan/indexPayPal.scala @@ -27,7 +27,7 @@ object indexPayPal: h1( userLink(me), " • ", - if (patron.isLifetime) strong(lifetimePatron()) + if patron.isLifetime then strong(lifetimePatron()) else patronForMonths(me.plan.months) ) ), diff --git a/app/views/plan/indexStripe.scala b/app/views/plan/indexStripe.scala index 4367810ab0e09..25b5b64ed07c6 100644 --- a/app/views/plan/indexStripe.scala +++ b/app/views/plan/indexStripe.scala @@ -35,7 +35,7 @@ object indexStripe: h1( userLink(me), " • ", - if (patron.isLifetime) strong(lifetimePatron()) + if patron.isLifetime then strong(lifetimePatron()) else patronForMonths(me.plan.months) ) ), @@ -64,14 +64,15 @@ object indexStripe: td(cls := "change") { val cancelButton = a(dataForm := "cancel")(cancelSupport()) frag( - if (pricing.currency != info.subscription.item.price.currency) cancelButton + if pricing.currency != info.subscription.item.price.currency then cancelButton else xOrY( a(dataForm := "switch")( changeMonthlyAmount(info.subscription.item.price.money.display) ), cancelButton - ), + ) + , postForm(cls := "switch", action := routes.Plan.switch)( p(decideHowMuch()), strong(pricing.currency.getSymbol(ctx.lang.locale), nbsp), @@ -80,7 +81,7 @@ object indexStripe: min := pricing.min.amount, max := pricing.max.amount, step := { - if (zeroDecimalCurrencies contains pricing.currency) "1" + if zeroDecimalCurrencies contains pricing.currency then "1" else "0.01" }, name := "amount", diff --git a/app/views/plan/thanks.scala b/app/views/plan/thanks.scala index 6ae0ba74ff176..8cdb9286621bf 100644 --- a/app/views/plan/thanks.scala +++ b/app/views/plan/thanks.scala @@ -25,30 +25,30 @@ object thanks: div(cls := "body")( p(tyvm()), p(transactionCompleted()), - (gift, patron) match { + (gift, patron) match case (Some(gift), _) => p( userIdLink(gift.userId.some), " ", - if (gift.isLifetime) "is now a lifetime Lichess Patron" + if gift.isLifetime then "is now a lifetime Lichess Patron" else "is now a Lichess Patron for one month", ", thanks to you!" ) case (_, Some(pat)) => - if ( - pat.payPal.exists(_.renew) || + if pat.payPal.exists(_.renew) || pat.payPalCheckout.exists(_.renew) || stripeCustomer.exists(_.renew) - ) ctx.me map { me => - p( - permanentPatron(), - br, - a(href := routes.User.show(me.username))(checkOutProfile()) - ) - } - else { + then + ctx.me map { me => + p( + permanentPatron(), + br, + a(href := routes.User.show(me.username))(checkOutProfile()) + ) + } + else frag( - if (pat.isLifetime) + if pat.isLifetime then p( nowLifetime(), br, @@ -68,9 +68,8 @@ object thanks: p(downgradeNextMonth()) ) ) - } case _ => emptyFrag - }, + , br, br, br, diff --git a/app/views/practice/index.scala b/app/views/practice/index.scala index 31d9e5155a361..8520c02eff65a 100644 --- a/app/views/practice/index.scala +++ b/app/views/practice/index.scala @@ -33,7 +33,7 @@ if (confirm('You will lose your practice progress!')) this.parentNode.submit(); div(cls := "bar", style := s"width: ${data.progressPercent}%") ), postForm(action := routes.Practice.reset)( - if (ctx.isAuth) (data.nbDoneChapters > 0) option a(cls := "do-reset")("Reset my progress") + if ctx.isAuth then (data.nbDoneChapters > 0) option a(cls := "do-reset")("Reset my progress") else a(href := routes.Auth.signup)("Sign up to save your progress") ) ), @@ -45,7 +45,7 @@ if (confirm('You will lose your practice progress!')) this.parentNode.submit(); section.studies.filter(s => !s.hide || isGranted(_.PracticeConfig)).map { stud => val prog = data.progressOn(stud.id) a( - cls := s"study ${if (prog.complete) "done" else "ongoing"}", + cls := s"study ${if prog.complete then "done" else "ongoing"}", href := routes.Practice.show(section.id, stud.slug, stud.id) )( ctx.isAuth option span(cls := "ribbon-wrapper")( diff --git a/app/views/puzzle/bits.scala b/app/views/puzzle/bits.scala index 454cdc5a9a0a1..72cd2e98d1be9 100644 --- a/app/views/puzzle/bits.scala +++ b/app/views/puzzle/bits.scala @@ -17,7 +17,7 @@ object bits: views.html.board.bits.mini(fen, p.color, lastMove.some)(span) def jsI18n(streak: Boolean)(using Lang) = - if (streak) i18nJsObject(streakI18nKeys) + if streak then i18nJsObject(streakI18nKeys) else i18nJsObject(trainingI18nKeys) + { PuzzleTheme.enPassant.key.value -> JsString(PuzzleTheme.enPassant.name.txt()) diff --git a/app/views/puzzle/dashboard.scala b/app/views/puzzle/dashboard.scala index 0766768dfbb6d..d392747a006d0 100644 --- a/app/views/puzzle/dashboard.scala +++ b/app/views/puzzle/dashboard.scala @@ -23,7 +23,7 @@ object dashboard: days = days, path = "dashboard", title = - if (ctx is user) trans.puzzle.puzzleDashboard.txt() + if ctx is user then trans.puzzle.puzzleDashboard.txt() else s"${user.username} ${trans.puzzle.puzzleDashboard.txt()}", subtitle = trans.puzzle.puzzleDashboardDescription.txt(), dashOpt = dashOpt, @@ -62,7 +62,7 @@ object dashboard: days = days, "improvementAreas", title = - if (ctx is user) trans.puzzle.improvementAreas.txt() + if ctx is user then trans.puzzle.improvementAreas.txt() else s"${user.username} ${trans.puzzle.improvementAreas.txt()}", subtitle = trans.puzzle.improvementAreasDescription.txt(), dashOpt = dashOpt @@ -76,7 +76,7 @@ object dashboard: days = days, "strengths", title = - if (ctx is user) trans.puzzle.strengths.txt() + if ctx is user then trans.puzzle.strengths.txt() else s"${user.username} ${trans.puzzle.strengths.txt()}", subtitle = trans.puzzle.strengthDescription.txt(), dashOpt = dashOpt @@ -166,6 +166,6 @@ object dashboard: results.canReplay option span(cls := s"$metricClass--fix__text")( trans.puzzle.nbToReplay.plural(results.unfixed, strong(results.unfixed)) ), - iconTag(if (results.canReplay) licon.PlayTriangle else licon.Checkmark) + iconTag(if results.canReplay then licon.PlayTriangle else licon.Checkmark) ) ) diff --git a/app/views/puzzle/history.scala b/app/views/puzzle/history.scala index 16b4ab03f12ef..ec60d7e2bfb28 100644 --- a/app/views/puzzle/history.scala +++ b/app/views/puzzle/history.scala @@ -14,7 +14,7 @@ object history: def apply(user: User, pager: Paginator[PuzzleSession])(using ctx: PageContext) = val title = - if (ctx is user) trans.puzzle.history.txt() + if ctx is user then trans.puzzle.history.txt() else s"${user.username} ${trans.puzzle.history.txt()}" views.html.base.layout( title = title, @@ -51,7 +51,7 @@ object history: ), span(cls := "puzzle-history__round__meta")( span(cls := "puzzle-history__round__result")( - if (r.round.win.yes) goodTag(trans.puzzle.solved()) + if r.round.win.yes then goodTag(trans.puzzle.solved()) else badTag(trans.puzzle.failed()) ), span(cls := "puzzle-history__round__id")(s"#${r.puzzle.id}") diff --git a/app/views/puzzle/ofPlayer.scala b/app/views/puzzle/ofPlayer.scala index 8dc99b2a07858..c0ea79c38f81f 100644 --- a/app/views/puzzle/ofPlayer.scala +++ b/app/views/puzzle/ofPlayer.scala @@ -37,10 +37,9 @@ object ofPlayer: submitButton(cls := "button")(trans.puzzle.searchPuzzles.txt()) ), div(cls := "puzzle-of-player__results")( - (user, puzzles) match { + (user, puzzles) match case (Some(u), Some(pager)) => - if (pager.nbResults == 0 && ctx.is(u)) - p(trans.puzzle.fromMyGamesNone()) + if pager.nbResults == 0 && ctx.is(u) then p(trans.puzzle.fromMyGamesNone()) else frag( p(strong(trans.puzzle.fromXGamesFound((pager.nbResults), userLink(u)))), @@ -67,7 +66,6 @@ object ofPlayer: ) ) case (_, _) => emptyFrag - } ) ) ) diff --git a/app/views/puzzle/show.scala b/app/views/puzzle/show.scala index b9fe5ee29b03b..daca9f3ab09ee 100644 --- a/app/views/puzzle/show.scala +++ b/app/views/puzzle/show.scala @@ -19,7 +19,7 @@ object show: )(using ctx: PageContext) = val isStreak = data.value.contains("streak") views.html.base.layout( - title = if (isStreak) "Puzzle Streak" else trans.puzzles.txt(), + title = if isStreak then "Puzzle Streak" else trans.puzzles.txt(), moreCss = frag( cssTag("puzzle"), ctx.pref.hasKeyboardMove option cssTag("keyboardMove"), @@ -49,11 +49,11 @@ object show: routes.Export.puzzleThumbnail(puzzle.id, ctx.pref.theme.some, ctx.pref.pieceSet.some).url ).some, title = - if (isStreak) "Puzzle Streak" + if isStreak then "Puzzle Streak" else s"Chess tactic #${puzzle.id} - ${puzzle.color.name.capitalize} to play", url = s"$netBaseUrl${routes.Puzzle.show(puzzle.id).url}", description = - if (isStreak) trans.puzzle.streakDescription.txt() + if isStreak then trans.puzzle.streakDescription.txt() else s"Lichess tactic trainer: ${puzzle.color .fold( diff --git a/app/views/puzzle/theme.scala b/app/views/puzzle/theme.scala index e23ad0db18294..3feb4a2545930 100644 --- a/app/views/puzzle/theme.scala +++ b/app/views/puzzle/theme.scala @@ -49,7 +49,7 @@ object theme: div(cls := s"puzzle-themes__list ${cat.value.replace(":", "-")}")( themes.map { pt => val url = - if (pt.theme == PuzzleTheme.mix) routes.Puzzle.home + if pt.theme == PuzzleTheme.mix then routes.Puzzle.home else routes.Puzzle.show(pt.theme.key.value) a(cls := "puzzle-themes__link", href := (pt.count > 0).option(langHref(url)))( span( diff --git a/app/views/relay/tourForm.scala b/app/views/relay/tourForm.scala index f723d6218b526..9b2bd5be64b1e 100644 --- a/app/views/relay/tourForm.scala +++ b/app/views/relay/tourForm.scala @@ -47,14 +47,14 @@ object tourForm: views.html.base.layout( title = title, moreCss = cssTag("relay.form") - )(menu match { + )(menu match case Some(active) => main(cls := "page-small page-menu")( tour.pageMenu(active), div(cls := "page-menu__content box box-pad")(body) ) case None => main(cls := "page-small box box-pad")(body) - }) + ) private def inner(form: Form[Data])(using PageContext) = frag( div(cls := "form-group")(bits.howToUse), @@ -79,7 +79,7 @@ object tourForm: help = raw("Compute and display a simple leaderboard based on game results").some, half = true ), - if (isGranted(_.Relay)) + if isGranted(_.Relay) then form3.group( form("tier"), raw("Official Lichess broadcast tier"), diff --git a/app/views/report/list.scala b/app/views/report/list.scala index 2797430f76815..aff169bc9f2fd 100644 --- a/app/views/report/list.scala +++ b/app/views/report/list.scala @@ -60,9 +60,9 @@ object list: r.atoms.size > 3 option i(cls := "more")("And ", r.atoms.size - 3, " more") ), td( - r.inquiry match { + r.inquiry match case None => - if (r.done.isDefined) + if r.done.isDefined then postForm(action := reportRoutes.inquiry(r.id), cls := "reopen")( submitButton(dataIcon := licon.PlayTriangle, cls := "text button button-metal")( "Reopen" @@ -77,7 +77,6 @@ object list: "Open by ", userIdLink(inquiry.mod.some) ) - } ) ) case _ => emptyFrag diff --git a/app/views/round/bits.scala b/app/views/round/bits.scala index 758ea1b5aa601..da49ce8263aba 100644 --- a/app/views/round/bits.scala +++ b/app/views/round/bits.scala @@ -30,7 +30,7 @@ object bits: openGraph = openGraph, moreJs = moreJs, moreCss = frag( - cssTag(if (variant == Crazyhouse) "round.zh" else "round"), + cssTag(if variant == Crazyhouse then "round.zh" else "round"), ctx.pref.hasKeyboardMove option cssTag("keyboardMove"), ctx.pref.hasVoice option cssTag("voice"), ctx.blind option cssTag("round.nvui"), @@ -105,7 +105,7 @@ object bits: span(cls := "meta")( playerText(pov.opponent, withRating = false), span(cls := "indicator")( - if (pov.isMyTurn) + if pov.isMyTurn then pov.remainingSeconds .fold[Frag](trans.yourTurn())(secondsFromNow(_, alwaysRelative = true)) else nbsp diff --git a/app/views/round/jsI18n.scala b/app/views/round/jsI18n.scala index bcd15d5411ab9..dce557b49ce75 100644 --- a/app/views/round/jsI18n.scala +++ b/app/views/round/jsI18n.scala @@ -10,7 +10,7 @@ object jsI18n: def apply(g: lila.game.Game)(using Lang) = i18nJsObject: baseTranslations ++ { - if (g.isCorrespondence) correspondenceTranslations + if g.isCorrespondence then correspondenceTranslations else realtimeTranslations } ++ { g.variant.exotic so variantTranslations diff --git a/app/views/round/player.scala b/app/views/round/player.scala index 89f74143950ae..58b5686f53168 100644 --- a/app/views/round/player.scala +++ b/app/views/round/player.scala @@ -44,7 +44,7 @@ object player: bits.layout( variant = pov.game.variant, - title = s"${trans.play.txt()} ${if (ctx.pref.isZen) "ZEN" else playerText(pov.opponent)}", + title = s"${trans.play.txt()} ${if ctx.pref.isZen then "ZEN" else playerText(pov.opponent)}", moreJs = frag( roundNvuiTag, jsModuleInit( diff --git a/app/views/search/index.scala b/app/views/search/index.scala index 6925c88c2a4ff..8e94035f7977e 100644 --- a/app/views/search/index.scala +++ b/app/views/search/index.scala @@ -75,7 +75,7 @@ object index: paginator.map { pager => val permalink = a(cls := "permalink", href := routes.Search.index(), noFollow)("Permalink") - if (pager.nbResults > 0) + if pager.nbResults > 0 then frag( div(cls := "search__status box__pad")( strong(xGamesFound(pager.nbResults.localize, pager.nbResults)), diff --git a/app/views/simul/homeInner.scala b/app/views/simul/homeInner.scala index 15c5d175a179b..670f7378b01a6 100644 --- a/app/views/simul/homeInner.scala +++ b/app/views/simul/homeInner.scala @@ -51,7 +51,7 @@ object homeInner: }, tr(cls := "create")( td(colspan := "4")( - if (ctx.isAuth) + if ctx.isAuth then a(href := routes.Simul.form, cls := "action button text")(trans.hostANewSimul()) else a(href := routes.Auth.signup, cls := "action button text")("Sign up to host or join a simul") diff --git a/app/views/simul/hosted.scala b/app/views/simul/hosted.scala index cdd2b0f8f1ae1..bb912ae11e9a0 100644 --- a/app/views/simul/hosted.scala +++ b/app/views/simul/hosted.scala @@ -17,7 +17,8 @@ object hosted: moreJs = infiniteScrollTag ) { main(cls := "page-small box simul-list")( - if (pager.nbResults == 0) div(cls := "box__top")(h1(userLink(user), " hasn't hosted any simuls yet!")) + if pager.nbResults == 0 then + div(cls := "box__top")(h1(userLink(user), " hasn't hosted any simuls yet!")) else table(cls := "slist slist-pad")( thead( diff --git a/app/views/storm.scala b/app/views/storm.scala index 78ad8ce0b2ad7..6939a5eb6c2f1 100644 --- a/app/views/storm.scala +++ b/app/views/storm.scala @@ -117,7 +117,7 @@ object storm: history, np => addQueryParam( - if (ctx is user) routes.Storm.dashboard().url + if ctx is user then routes.Storm.dashboard().url else routes.Storm.dashboardOf(user.username).url, "page", np.toString diff --git a/app/views/streamer/edit.scala b/app/views/streamer/edit.scala index 1670e3bb3b49a..710936713cf87 100644 --- a/app/views/streamer/edit.scala +++ b/app/views/streamer/edit.scala @@ -23,9 +23,9 @@ object edit: main(cls := "page-menu")( bits.menu("edit", s.some), div(cls := "page-menu__content box streamer-edit")( - if (ctx.is(s.user)) + if ctx.is(s.user) then div(cls := "streamer-header")( - if (s.streamer.hasPicture) + if s.streamer.hasPicture then a( targetBlank, cls := "picture-edit", @@ -40,7 +40,8 @@ object edit: a(targetBlank, cls := "button", href := routes.Streamer.picture)( uploadPicture() ) - ), + ) + , div(cls := "overview")( h1(s.streamer.name), bits.rules @@ -52,9 +53,9 @@ object edit: frag( (ctx.is(s.user) && s.streamer.listed.value) option div( cls := s"status is${granted so "-green"}", - dataIcon := (if (granted) licon.Checkmark else licon.InfoCircle) + dataIcon := (if granted then licon.Checkmark else licon.InfoCircle) )( - if (granted) + if granted then frag( approved(), s.streamer.approval.tier > 0 option frag( @@ -68,10 +69,10 @@ object edit: ) else frag( - if (s.streamer.approval.requested) pendingReview() + if s.streamer.approval.requested then pendingReview() else frag( - if (s.streamer.completeEnough) + if s.streamer.completeEnough then whenReady( postForm(action := routes.Streamer.approvalRequest)( button(tpe := "submit", cls := "button", (!ctx.is(s.user)) option disabled)( @@ -164,7 +165,7 @@ object edit: frag("Embed stream chat too"), half = true ), - if (granted) + if granted then form3.group( form("approval.tier"), raw("Homepage tier"), diff --git a/app/views/streamer/header.scala b/app/views/streamer/header.scala index 419d68b65e87e..d3a45337c7e84 100644 --- a/app/views/streamer/header.scala +++ b/app/views/streamer/header.scala @@ -13,7 +13,9 @@ object header: div(cls := "overview")( bits.streamerTitle(s), s.streamer.headline.map(_.value).map { d => - p(cls := s"headline ${if (d.length < 60) "small" else if (d.length < 120) "medium" else "large"}")( + p(cls := s"headline ${ + if d.length < 60 then "small" else if d.length < 120 then "medium" else "large" + }")( d ) }, diff --git a/app/views/streamer/index.scala b/app/views/streamer/index.scala index d98cfb0171d69..a2945921c1744 100644 --- a/app/views/streamer/index.scala +++ b/app/views/streamer/index.scala @@ -18,11 +18,11 @@ object index: requests: Boolean )(using ctx: PageContext) = - val title = if (requests) "Streamer approval requests" else lichessStreamers.txt() + val title = if requests then "Streamer approval requests" else lichessStreamers.txt() def widget(s: lila.streamer.Streamer.WithContext, stream: Option[lila.streamer.Stream]) = frag( - if (requests) a(href := s"${routes.Streamer.edit}?u=${s.user.username}", cls := "overlay") + if requests then a(href := s"${routes.Streamer.edit}?u=${s.user.username}", cls := "overlay") else bits.redirectLink(s.user.username, stream.isDefined.some)(cls := "overlay"), stream.isDefined option span(cls := "live-ribbon")(span(trans.streamer.live())), picture.thumbnail(s.streamer, s.user), @@ -30,7 +30,9 @@ object index: bits.streamerTitle(s), s.streamer.headline.map(_.value).map { d => p( - cls := s"headline ${if (d.length < 60) "small" else if (d.length < 120) "medium" else "large"}" + cls := s"headline ${ + if d.length < 60 then "small" else if d.length < 120 then "medium" else "large" + }" )(d) }, div(cls := "services")( @@ -63,7 +65,7 @@ object index: moreJs = frag(infiniteScrollTag, jsModule("streamer")) ) { main(cls := "page-menu")( - bits.menu(if (requests) "requests" else "index", none)(cls := " page-menu__menu"), + bits.menu(if requests then "requests" else "index", none)(cls := " page-menu__menu"), div(cls := "page-menu__content box streamer-list")( boxTop(h1(dataIcon := licon.Mic, cls := "text")(title)), !requests option div(cls := "list force-ltr live")( diff --git a/app/views/streamer/show.scala b/app/views/streamer/show.scala index 480681a3cdb90..5f59f4d9f9045 100644 --- a/app/views/streamer/show.scala +++ b/app/views/streamer/show.scala @@ -36,7 +36,7 @@ object show: main(cls := "page-menu streamer-show")( st.aside(cls := "page-menu__menu")( s.streamer.approval.chatEnabled option div(cls := "streamer-chat")( - s.stream match { + s.stream match case Some(YouTube.Stream(_, _, videoId, _, _)) => iframe( frame.credentialless, @@ -53,7 +53,6 @@ object show: src := s"https://twitch.tv/embed/${twitch.userId}/chat?${(ctx.pref.currentBg != "light") so "darkpopout&"}parent=${netConfig.domain}" ) } - } ), bits.menu("show", s.some) ), diff --git a/app/views/study/bits.scala b/app/views/study/bits.scala index 9b22392087d3d..9d794fbb30558 100644 --- a/app/views/study/bits.scala +++ b/app/views/study/bits.scala @@ -14,8 +14,8 @@ object bits: def orderSelect(order: Order, active: String, url: String => Call)(using PageContext) = val orders = - if (active == "all") Order.withoutSelector - else if (active startsWith "topic") Order.list + if active == "all" then Order.withoutSelector + else if active startsWith "topic" then Order.list else Order.withoutMine views.html.base.bits.mselect( "orders", @@ -59,7 +59,7 @@ object bits: iconTag(licon.Padlock)(cls := "private", ariaTitle(trans.study.`private`.txt())), " " ), - iconTag(if (s.liked) licon.Heart else licon.HeartOutline), + iconTag(if s.liked then licon.Heart else licon.HeartOutline), " ", s.study.likes.value, " • ", @@ -73,7 +73,7 @@ object bits: ol(cls := "chapters")( s.chapters.map { name => li(cls := "text", dataIcon := licon.DiscBigOutline)( - if (ctx.userId.exists(s.study.isMember)) name + if ctx.userId.exists(s.study.isMember) then name else removeMultibyteSymbols(name.value) ) } @@ -82,7 +82,7 @@ object bits: s.study.members.members.values .take(Study.previewNbMembers) .map { m => - li(cls := "text", dataIcon := (if (m.canContribute) licon.RadioTower else licon.Eye))( + li(cls := "text", dataIcon := (if m.canContribute then licon.RadioTower else licon.Eye))( titleNameOrId(m.id) ) } diff --git a/app/views/study/list.scala b/app/views/study/list.scala index f39aa7260da2c..4759b2de57eaa 100644 --- a/app/views/study/list.scala +++ b/app/views/study/list.scala @@ -129,7 +129,7 @@ object list: } private[study] def paginate(pager: Paginator[WithChaptersAndLiked], url: Call)(using PageContext) = - if (pager.currentPageResults.isEmpty) + if pager.currentPageResults.isEmpty then div(cls := "nostudies")( iconTag(licon.StudyBoard), p(trans.study.noneYet()) @@ -145,7 +145,7 @@ object list: private[study] def menu(active: String, order: Order, topics: List[StudyTopic] = Nil)(using ctx: PageContext ) = - val nonMineOrder = if (order == Order.Mine) Order.Hot else order + val nonMineOrder = if order == Order.Mine then Order.Hot else order st.aside(cls := "page-menu__menu subnav")( a(cls := active.active("all"), href := routes.Study.all(nonMineOrder.key))(trans.study.allStudies()), ctx.isAuth option bits.authLinks(active, nonMineOrder), diff --git a/app/views/swiss/bits.scala b/app/views/swiss/bits.scala index bb57e2c45ac29..44d47c11a6079 100644 --- a/app/views/swiss/bits.scala +++ b/app/views/swiss/bits.scala @@ -52,9 +52,9 @@ object bits: span(cls := "setup")( s.clock.show, " • ", - if (s.variant.exotic) s.variant.name else s.perfType.trans, + if s.variant.exotic then s.variant.name else s.perfType.trans, " • ", - if (s.settings.rated) trans.ratedTournament() else trans.casualTournament(), + if s.settings.rated then trans.ratedTournament() else trans.casualTournament(), " • ", s.estimatedDurationString ) @@ -74,7 +74,7 @@ object bits: case Some(d) => trans.swiss.oneRoundEveryXDays.pluralSame(d) case None if s.settings.manualRounds => trans.swiss.roundsAreStartedManually() case None => - if (s.settings.intervalSeconds < 60) + if s.settings.intervalSeconds < 60 then trans.swiss.xSecondsBetweenRounds.pluralSame(s.settings.intervalSeconds) else trans.swiss.xMinutesBetweenRounds.pluralSame(s.settings.intervalSeconds / 60) @@ -86,7 +86,7 @@ object bits: span(cls := "more")( trans.nbPlayers.plural(s.nbPlayers, s.nbPlayers.localize), " • ", - if (s.isStarted) trans.eventInProgress() else momentFromNow(s.startsAt) + if s.isStarted then trans.eventInProgress() else momentFromNow(s.startsAt) ) ) ) diff --git a/app/views/swiss/home.scala b/app/views/swiss/home.scala index 07fa4ebd050b1..bf75f472c067e 100644 --- a/app/views/swiss/home.scala +++ b/app/views/swiss/home.scala @@ -64,9 +64,9 @@ object home: span(cls := "setup")( s.clock.show, " • ", - if (s.variant.exotic) s.variant.name else s.perfType.trans, + if s.variant.exotic then s.variant.name else s.perfType.trans, " • ", - (if (s.settings.rated) trans.ratedTournament else trans.casualTournament) () + (if s.settings.rated then trans.ratedTournament else trans.casualTournament) () ) ), td( diff --git a/app/views/team/form.scala b/app/views/team/form.scala index 68a393606f892..5e2d02a796068 100644 --- a/app/views/team/form.scala +++ b/app/views/team/form.scala @@ -173,8 +173,7 @@ object form: help = trans.team.entryCodeDescriptionForLeader().some, half = true ) { field => - if (team.fold(true)(t => ctx.userId.exists(t.leaders.contains))) - form3.input(field) + if team.fold(true)(t => ctx.userId.exists(t.leaders.contains)) then form3.input(field) else form3.input(field)(tpe := "password", disabled) } ) diff --git a/app/views/team/list.scala b/app/views/team/list.scala index 9e03716082aad..645b2c986514c 100644 --- a/app/views/team/list.scala +++ b/app/views/team/list.scala @@ -38,7 +38,7 @@ object list: ) }, table(cls := "slist slist-pad")( - if (teams.nonEmpty) tbody(teams.map(bits.teamTr(_))) + if teams.nonEmpty then tbody(teams.map(bits.teamTr(_))) else noTeam() ) ) @@ -53,7 +53,7 @@ object list: h1(cls := "box__top")(teamsIlead()), standardFlash, table(cls := "slist slist-pad")( - if (teams.nonEmpty) tbody(teams.map(bits.teamTr(_))) + if teams.nonEmpty then tbody(teams.map(bits.teamTr(_))) else noTeam() ) ) @@ -90,7 +90,7 @@ object list: ), standardFlash, table(cls := "slist slist-pad")( - if (teams.nbResults > 0) + if teams.nbResults > 0 then tbody(cls := "infinite-scroll")( teams.currentPageResults map { bits.teamTr(_) }, pagerNextTable(teams, nextPageUrl) diff --git a/app/views/team/request.scala b/app/views/team/request.scala index f605f7884b7cd..c9c82eb7bf8b4 100644 --- a/app/views/team/request.scala +++ b/app/views/team/request.scala @@ -60,7 +60,7 @@ object request: tbody( requests.map { request => tr( - if (t.isEmpty) td(userLink(request.user), " ", teamLink(request.team)) + if t.isEmpty then td(userLink(request.user), " ", teamLink(request.team)) else td(userLink(request.user)), td(request.message), td(momentFromNow(request.date)), diff --git a/app/views/team/show.scala b/app/views/team/show.scala index a47c450d54d36..6a8799390d5d8 100644 --- a/app/views/team/show.scala +++ b/app/views/team/show.scala @@ -46,7 +46,7 @@ object show: .add("chat" -> chatOption.map { chat => views.html.chat.json( chat.chat, - name = if (t.isChatFor(_.LEADERS)) leadersChat.txt() else trans.chatRoom.txt(), + name = if t.isChatFor(_.LEADERS) then leadersChat.txt() else trans.chatRoom.txt(), timeout = chat.timeout, public = true, resourceId = lila.chat.Chat.ResourceId(s"team/${chat.chat.id}"), @@ -67,7 +67,7 @@ object show: boxTop( h1(cls := "text", dataIcon := licon.Group)(t.name), div( - if (t.disabled) span(cls := "staff")("CLOSED") + if t.disabled then span(cls := "staff")("CLOSED") else canSeeMembers option a(href := routes.Team.members(t.slug))( nbMembers.plural(t.nbMembers, strong(t.nbMembers.localize)) @@ -96,12 +96,12 @@ object show: ), div(cls := "team-show__actions")( (t.enabled && !info.mine) option frag( - if (info.myRequest.exists(_.declined)) + if info.myRequest.exists(_.declined) then frag( strong(requestDeclined()), a(cls := "button disabled button-metal")(joinTeam()) ) - else if (info.myRequest.isDefined) + else if info.myRequest.isDefined then frag( strong(beingReviewed()), postForm(action := routes.Team.quit(t.id))( diff --git a/app/views/team/tournaments.scala b/app/views/team/tournaments.scala index 9ff7c6400a315..d09dd5a9c6e0d 100644 --- a/app/views/team/tournaments.scala +++ b/app/views/team/tournaments.scala @@ -68,7 +68,7 @@ object tournaments: span(cls := "setup")( t.clock.show, " • ", - if (t.variant.exotic) t.variant.name else t.perfType.trans, + if t.variant.exotic then t.variant.name else t.perfType.trans, t.position.isDefined option frag(" • ", trans.thematic()), " • ", if t.mode.rated then trans.ratedTournament() else trans.casualTournament(), @@ -82,9 +82,9 @@ object tournaments: span(cls := "setup")( s.clock.show, " • ", - if (s.variant.exotic) s.variant.name else s.perfType.trans, + if s.variant.exotic then s.variant.name else s.perfType.trans, " • ", - (if (s.settings.rated) trans.ratedTournament else trans.casualTournament) () + (if s.settings.rated then trans.ratedTournament else trans.casualTournament) () ) ) ) @@ -114,5 +114,5 @@ object tournaments: ) private def renderStartsAt(any: TeamInfo.AnyTour)(using Lang): Frag = - if (any.isEnterable && any.startsAt.isBeforeNow) trans.playingRightNow() + if any.isEnterable && any.startsAt.isBeforeNow then trans.playingRightNow() else momentFromNowOnce(any.startsAt) diff --git a/app/views/tournament/faq.scala b/app/views/tournament/faq.scala index 7f0ffd2bf5e47..bbf6348ff2e39 100644 --- a/app/views/tournament/faq.scala +++ b/app/views/tournament/faq.scala @@ -36,11 +36,11 @@ object faq: }, p(trans.arena.willBeNotified()), h2(trans.arena.isItRated()), - rated match { + rated match case Some(true) => p(trans.arena.isRated()) case Some(false) => p(trans.arena.isNotRated()) case None => p(trans.arena.someRated()) - }, + , h2(howAreScoresCalculated()), p(howAreScoresCalculatedAnswer()), h2(berserk()), diff --git a/app/views/tournament/finishedList.scala b/app/views/tournament/finishedList.scala index 332fbbb2bd6dd..c932b34415eae 100644 --- a/app/views/tournament/finishedList.scala +++ b/app/views/tournament/finishedList.scala @@ -32,7 +32,7 @@ object finishedList: span( t.clock.show, " • ", - if (t.variant.exotic) t.variant.name else t.perfType.trans, + if t.variant.exotic then t.variant.name else t.perfType.trans, t.position.isDefined option frag(" • ", trans.thematic()), " • ", if t.mode.rated then trans.ratedTournament() else trans.casualTournament(), diff --git a/app/views/tournament/form.scala b/app/views/tournament/form.scala index d82fcdca29fbc..a038853cd4eb2 100644 --- a/app/views/tournament/form.scala +++ b/app/views/tournament/form.scala @@ -22,7 +22,7 @@ object form: main(cls := "page-small")( div(cls := "tour__form box box-pad")( h1(cls := "box__top")( - if (fields.isTeamBattle) trans.arena.newTeamBattle() + if fields.isTeamBattle then trans.arena.newTeamBattle() else trans.createANewTournament() ), postForm(cls := "form3", action := routes.Tournament.webCreate)( @@ -72,7 +72,7 @@ object form: form3.split(fields.rated, fields.variant), fields.clock, form3.split( - if (TournamentForm.minutes contains tour.minutes) form3.split(fields.minutes) + if TournamentForm.minutes contains tour.minutes then form3.split(fields.minutes) else form3.group(form("minutes"), trans.duration(), half = true)( form3.input(_)(tpe := "number") @@ -193,7 +193,7 @@ final private class TourFields(form: Form[?], tour: Option[Tournament])(using Pa div( form3.input(f), " ", - if (isTeamBattle) "Team Battle" else "Arena", + if isTeamBattle then "Team Battle" else "Arena", br, small(cls := "form-help")( trans.safeTournamentName(), diff --git a/app/views/tournament/history.scala b/app/views/tournament/history.scala index 419b83e3812fd..d4b8a3515b7fa 100644 --- a/app/views/tournament/history.scala +++ b/app/views/tournament/history.scala @@ -38,7 +38,7 @@ object history: ) } - private def nameOf(f: Freq) = if (f == Freq.Weekend) "Elite" else f.name + private def nameOf(f: Freq) = if f == Freq.Weekend then "Elite" else f.name private val allFreqs = List( Freq.Unique, diff --git a/app/views/tournament/homepageSpotlight.scala b/app/views/tournament/homepageSpotlight.scala index 0aae7c491db3b..441c93e62479b 100644 --- a/app/views/tournament/homepageSpotlight.scala +++ b/app/views/tournament/homepageSpotlight.scala @@ -26,14 +26,14 @@ object homepageSpotlight: }, span(cls := "content")( span(cls := "name")(tour.name()), - if (tour.isDistant) span(cls := "more")(momentFromNow(tour.startsAt)) + if tour.isDistant then span(cls := "more")(momentFromNow(tour.startsAt)) else frag( span(cls := "headline")(spot.headline), span(cls := "more")( trans.nbPlayers.plural(tour.nbPlayers, tour.nbPlayers.localize), " • ", - if (tour.isStarted) trans.finishesX(momentFromNow(tour.finishesAt)) + if tour.isStarted then trans.finishesX(momentFromNow(tour.finishesAt)) else momentFromNow(tour.startsAt) ) ) @@ -47,7 +47,7 @@ object homepageSpotlight: span(cls := "more")( trans.nbPlayers.plural(tour.nbPlayers, tour.nbPlayers.localize), " • ", - if (tour.isStarted) trans.eventInProgress() else momentFromNow(tour.startsAt) + if tour.isStarted then trans.eventInProgress() else momentFromNow(tour.startsAt) ) ) ) diff --git a/app/views/tournament/show.scala b/app/views/tournament/show.scala index b8e06a04ac1ca..337b0ecef1b80 100644 --- a/app/views/tournament/show.scala +++ b/app/views/tournament/show.scala @@ -43,7 +43,7 @@ object show: ) ), moreCss = cssTag { - if (tour.isTeamBattle) "tournament.show.team-battle" + if tour.isTeamBattle then "tournament.show.team-battle" else "tournament.show" }, chessground = false, diff --git a/app/views/tournament/side.scala b/app/views/tournament/side.scala index b26b292f7f5b3..3976ad13bbe9a 100644 --- a/app/views/tournament/side.scala +++ b/app/views/tournament/side.scala @@ -60,7 +60,7 @@ object side: tour.createdBy == lila.user.User.lichessId || tour.conditions.teamMember.exists(_.teamId == team.id) } map { case (team, link) => st.section( - if (isMyTeamSync(team.id)) frag(trans.team.team(), " ", link) + if isMyTeamSync(team.id) then frag(trans.team.team(), " ", link) else trans.team.joinLichessVariantTeam(link) ) }, diff --git a/app/views/tournament/teamBattle.scala b/app/views/tournament/teamBattle.scala index 1e4197d665de8..70ed69d971b00 100644 --- a/app/views/tournament/teamBattle.scala +++ b/app/views/tournament/teamBattle.scala @@ -25,7 +25,7 @@ object teamBattle: div(cls := "tour__form box box-pad")( h1(cls := "box__top")(tour.name()), standardFlash, - if (tour.isFinished) p("This tournament is over, and the teams can no longer be updated.") + if tour.isFinished then p("This tournament is over, and the teams can no longer be updated.") else p("List the teams that will compete in this battle."), postForm(cls := "form3", action := routes.Tournament.teamBattleUpdate(tour.id))( form3.group( diff --git a/app/views/tutor/compare.scala b/app/views/tutor/compare.scala index 490fdd72d0340..1c60bca9db115 100644 --- a/app/views/tutor/compare.scala +++ b/app/views/tutor/compare.scala @@ -26,10 +26,10 @@ private object compare: " is ", showQuality(comp.grade), " ", - comp.reference match { + comp.reference match case TutorCompare.DimAvg(_) => frag("in ", otherDims(comp.dimensionType)) case TutorCompare.Peers(_) => frag("your peers'") - }, + , "." ) @@ -39,14 +39,14 @@ private object compare: case _ => "others" private[tutor] def showQuality(quality: Grade) = - (if (quality.better) goodTag else if (quality.worse) badTag else span) (quality.wording.value) + (if quality.better then goodTag else if quality.worse then badTag else span) (quality.wording.value) private[tutor] def showMetric(comp: TutorCompare.AnyComparison): String = - (comp.metric match { + (comp.metric match case TutorMetric.GlobalClock => "global speed" case TutorMetric.ClockUsage => "clock usage" case metric => metric.metric.name.toLowerCase - }) + ) private[tutor] def showDimension[D](dimension: D): String = dimension match case d: LilaOpeningFamily => s"the ${d.name.value}" diff --git a/app/views/tutor/home.scala b/app/views/tutor/home.scala index d826efafabebb..bb91f884af650 100644 --- a/app/views/tutor/home.scala +++ b/app/views/tutor/home.scala @@ -13,8 +13,8 @@ object home: bits.layout(menu = menu(full, user, none))( cls := "tutor__home box", boxTop(h1(bits.otherUser(user), "Lichess Tutor")), - if (full.report.perfs.isEmpty) empty.mascotSaysInsufficient - else { + if full.report.perfs.isEmpty then empty.mascotSaysInsufficient + else bits.mascotSays( p( strong( @@ -29,7 +29,7 @@ object home: "It should give us some idea about what your strengths are, and where you have room for improvement." ) ) - }, + , div(cls := "tutor__perfs tutor-cards")( full.report.perfs.toList map { perfReportCard(full.report, _, user) } ) diff --git a/app/views/tv/side.scala b/app/views/tv/side.scala index 2c45715ae89a5..a4bed7981d357 100644 --- a/app/views/tv/side.scala +++ b/app/views/tv/side.scala @@ -49,7 +49,7 @@ object side: div(cls := "setup")( views.html.game.widgets showClock game, separator, - (if (game.rated) trans.rated else trans.casual).txt(), + (if game.rated then trans.rated else trans.casual).txt(), separator, views.html.game.bits.variantLink(game.variant, game.perfType, shortName = true) ) diff --git a/app/views/ublog/blog.scala b/app/views/ublog/blog.scala index f89dbe8539a6d..0bd77a270f18e 100644 --- a/app/views/ublog/blog.scala +++ b/app/views/ublog/blog.scala @@ -29,12 +29,12 @@ object blog: robots = netConfig.crawlable && blog.listed ) { main(cls := "page-menu")( - views.html.blog.bits.menu(none, (if (ctx is user) "mine" else "community").some), + views.html.blog.bits.menu(none, (if ctx is user then "mine" else "community").some), div(cls := "page-menu__content box box-pad ublog-index")( boxTop( h1(trans.ublog.xBlog(userLink(user))), div(cls := "box__top__actions")( - if (ctx is user) + if ctx is user then frag( a(href := routes.Ublog.drafts(user.username))(trans.ublog.drafts()), postView.newPostLink @@ -52,7 +52,7 @@ object blog: ) ), standardFlash, - if (posts.nbResults > 0) + if posts.nbResults > 0 then div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")( posts.currentPageResults map { postView.card(_) }, pagerNext(posts, np => s"${routes.Ublog.index(user.username, np).url}") diff --git a/app/views/ublog/form.scala b/app/views/ublog/form.scala index d5d79a03b2dba..1a45db06d06de 100644 --- a/app/views/ublog/form.scala +++ b/app/views/ublog/form.scala @@ -143,7 +143,7 @@ object form: div(id := "markdown-editor", attr("data-image-upload-url") := routes.Main.uploadImage("ublogBody")) ) }, - post.toOption match { + post.toOption match case None => form3.group(form("topics"), frag(trans.ublog.selectPostTopics()))( form3.textarea(_)(dataRel := UblogTopic.all.mkString(",")) @@ -178,7 +178,7 @@ object form: ) ) ) - }, + , captcha.fold(views.html.base.captcha.hiddenEmpty(form)) { c => views.html.base.captcha(form, c) }, @@ -189,7 +189,7 @@ object form: )( trans.cancel() ), - form3.submit((if (post.isRight) trans.apply else trans.ublog.saveDraft) ()) + form3.submit((if post.isRight then trans.apply else trans.ublog.saveDraft) ()) ) ) diff --git a/app/views/ublog/index.scala b/app/views/ublog/index.scala index 406de2a888e47..f5fe8ee666925 100644 --- a/app/views/ublog/index.scala +++ b/app/views/ublog/index.scala @@ -31,7 +31,7 @@ object index: postView.newPostLink ) ), - if (posts.nbResults > 0) + if posts.nbResults > 0 then div(cls := "ublog-index__posts ublog-index__posts--drafts ublog-post-cards infinite-scroll")( posts.currentPageResults map { postView.card(_, postView.editUrlOfPost) }, pagerNext(posts, np => routes.Ublog.drafts(user.username, np).url) @@ -112,7 +112,7 @@ object index: ) ) ), - if (posts.nbResults > 0) + if posts.nbResults > 0 then div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")( posts.currentPageResults map { postView.card(_, showAuthor = true) }, pagerNext( @@ -123,8 +123,7 @@ object index: .url ) ) - else - div(cls := "ublog-index__posts--empty")("Nothing to show.") + else div(cls := "ublog-index__posts--empty")("Nothing to show.") ) ) } @@ -171,13 +170,12 @@ object index: views.html.blog.bits.menu(none, menuItem.some), div(cls := "page-menu__content box box-pad ublog-index")( boxTop(h1(title)), - if (posts.nbResults > 0) + if posts.nbResults > 0 then div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")( posts.currentPageResults map { postView.card(_, showAuthor = true) }, pagerNext(posts, np => route(np).url) ) - else - div(cls := "ublog-index__posts--empty")(onEmpty) + else div(cls := "ublog-index__posts--empty")(onEmpty) ) ) } diff --git a/app/views/ublog/post.scala b/app/views/ublog/post.scala index e74f0d6077097..15e3751b9fd2f 100644 --- a/app/views/ublog/post.scala +++ b/app/views/ublog/post.scala @@ -44,7 +44,7 @@ object post: csp = defaultCsp.withTwitter.withInlineIconFont.some ) { main(cls := "page-menu page-small")( - views.html.blog.bits.menu(none, (if (ctx is user) "mine" else "community").some), + views.html.blog.bits.menu(none, (if ctx is user then "mine" else "community").some), div(cls := "page-menu__content box box-pad ublog-post")( post.image.map { image => frag( @@ -64,7 +64,7 @@ object post: titleTag(user.title), user.username, !ctx.is(user) && isGranted(_.ModerateBlog) option - (if (blog.tier <= UblogBlog.Tier.VISIBLE) badTag else goodTag) ( + (if blog.tier <= UblogBlog.Tier.VISIBLE then badTag else goodTag) ( cls := "ublog-post__tier" )(UblogBlog.Tier.name(blog.tier)) ), @@ -79,15 +79,15 @@ object post: span(cls := "ublog-post__views")( trans.ublog.nbViews.plural(post.views.value, strong(post.views.value.localize)) ), - if (ctx is user) + if ctx is user then div(cls := "ublog-post__meta__owner")( - (if (post.live) goodTag else badTag) ( - if (post.live) trans.ublog.thisPostIsPublished() else trans.ublog.thisIsADraft() + (if post.live then goodTag else badTag) ( + if post.live then trans.ublog.thisPostIsPublished() else trans.ublog.thisIsADraft() ), " ", editButton(post) ) - else if (isGranted(_.ModerateBlog)) editButton(post) + else if isGranted(_.ModerateBlog) then editButton(post) else a( titleOrText(trans.reportXToModerators.txt(user.username)), @@ -135,7 +135,7 @@ object post: )(trans.edit()) private def likeButton(post: UblogPost, liked: Boolean, showText: Boolean)(using PageContext) = - val text = if (liked) trans.study.unlike.txt() else trans.study.like.txt() + val text = if liked then trans.study.unlike.txt() else trans.study.like.txt() button( tpe := "button", cls := List( diff --git a/app/views/user/bits.scala b/app/views/user/bits.scala index 722db2f8a0db2..45f62a3eae5b4 100644 --- a/app/views/user/bits.scala +++ b/app/views/user/bits.scala @@ -34,7 +34,7 @@ object bits: def signalBars(v: Int) = raw: val bars = (1 to 4).map { b => - s"""""" + s"""""" } mkString "" val title = v match case 1 => "Poor connection" diff --git a/app/views/user/mod.scala b/app/views/user/mod.scala index 980430d070d70..218958fe64329 100644 --- a/app/views/user/mod.scala +++ b/app/views/user/mod.scala @@ -153,7 +153,7 @@ object mod: } ), isGranted(_.CloseAccount) option div(cls := "btn-rack")( - if (u.enabled.yes) { + if u.enabled.yes then postForm( action := routes.Mod.closeAccount(u.username), title := "Disables this account.", @@ -161,9 +161,8 @@ object mod: )( submitButton(cls := "btn-rack__btn")("Close") ) - } else if (erased.value) { - "Erased" - } else + else if erased.value then "Erased" + else frag( postForm( action := routes.Mod.reopenAccount(u.username), @@ -244,9 +243,9 @@ object mod: def prefs(u: User)(pref: lila.pref.Pref)(using Context) = frag( canViewRoles(u) option mzSection("roles")( - (if (isGranted(_.ChangePermission)) a(href := routes.Mod.permissions(u.username)) else span) ( + (if isGranted(_.ChangePermission) then a(href := routes.Mod.permissions(u.username)) else span) ( strong(cls := "text inline", dataIcon := " ")("Permissions: "), - if (u.roles.isEmpty) "Add some" else Permission(u.roles).map(_.name).mkString(", ") + if u.roles.isEmpty then "Add some" else Permission(u.roles).map(_.name).mkString(", ") ) ), mzSection("preferences")( @@ -292,11 +291,11 @@ object mod: ul( charges.map { c => li( - c.giftTo match { + c.giftTo match case Some(giftedId) if u is giftedId => frag("Gift from", userIdLink(c.userId), " ") case Some(giftedId) => frag("Gift to", userIdLink(giftedId.some), " ") case _ => emptyFrag - }, + , c.money.display, " with ", c.serviceName, @@ -542,7 +541,7 @@ object mod: ), td( span(cls := s"sig sig_${Display.holdSig(result)}", dataIcon := licon.DiscBig), - if (result.basics.hold) "Yes" else "No" + if result.basics.hold then "Yes" else "No" ), td( pag.pov(result).map { p => @@ -576,7 +575,7 @@ object mod: private val reportban = iconTag(licon.CautionTriangle) private val notesText = iconTag(licon.Pencil) private def markTd(nb: Int, content: => Frag, date: Option[Instant] = None)(using ctx: Context) = - if (nb > 0) td(cls := "i", dataSort := nb, title := date.map(d => showInstantUTC(d)))(content) + if nb > 0 then td(cls := "i", dataSort := nb, title := date.map(d => showInstantUTC(d)))(content) else td def otherUsers(mod: Me, u: User, data: UserLogins.TableData[UserWithModlog], appeals: List[Appeal])(using @@ -747,7 +746,7 @@ object mod: val parsed = userAgentParser.parse(ua.value) tr( td(title := ua.value)( - if (parsed.device.family == "Other") "Computer" else parsed.device.family + if parsed.device.family == "Other" then "Computer" else parsed.device.family ), td(parts(parsed.os.family.some, parsed.os.major)), td(parts(parsed.userAgent.family.some, parsed.userAgent.major)), diff --git a/app/views/user/perfStat.scala b/app/views/user/perfStat.scala index 1a4933c1639dd..763eeff4bddf5 100644 --- a/app/views/user/perfStat.scala +++ b/app/views/user/perfStat.scala @@ -75,7 +75,7 @@ object perfStat: h2( trans.perfRatingX( strong( - if (perf.glicko.clueless) "?" + if perf.glicko.clueless then "?" else decimal(perf.glicko.rating).toString ) ), @@ -89,12 +89,12 @@ object perfStat: ". ", percentile.filter(_ != 0.0 && perf.glicko.provisional.no).map { percentile => span(cls := "details")( - if (ctx is u) { + if ctx is u then trans.youAreBetterThanPercentOfPerfTypePlayers( a(href := routes.User.ratingDistribution(perfType.key))(strong(percentile, "%")), a(href := routes.User.topNb(200, perfType.key))(perfType.trans) ) - } else { + else trans.userIsBetterThanPercentOfPerfTypePlayers( a(href := routes.User.show(u.username))(u.username), a(href := routes.User.ratingDistribution(perfType.key, u.username.some))( @@ -102,7 +102,6 @@ object perfStat: ), a(href := routes.User.topNb(200, perfType.key))(perfType.trans) ) - } ) } ), @@ -110,8 +109,8 @@ object perfStat: progressOverLastXGames(12), " ", span(cls := "progress")( - if (perf.progress > 0) tag("green")(dataIcon := licon.ArrowUpRight)(perf.progress) - else if (perf.progress < 0) tag("red")(dataIcon := licon.ArrowDownRight)(-perf.progress) + if perf.progress > 0 then tag("green")(dataIcon := licon.ArrowUpRight)(perf.progress) + else if perf.progress < 0 then tag("red")(dataIcon := licon.ArrowDownRight)(-perf.progress) else "-" ), ". ", @@ -187,7 +186,9 @@ object perfStat: ), tr(cls := "full")( th(disconnections()), - td(if (count.disconnects > count.all * 100 / 15) tag("red") else emptyFrag)(count.disconnects), + td(if count.disconnects > count.all * 100 / 15 then tag("red") else emptyFrag)( + count.disconnects + ), td(pct(count.disconnects, count.all)) ) ) @@ -216,11 +217,10 @@ object perfStat: case Some(from) => fromXToY( a(cls := "glpt", href := routes.Round.watcher(from.gameId, "white"))(absClientInstant(from.at)), - s.to match { + s.to match case Some(to) => a(cls := "glpt", href := routes.Round.watcher(to.gameId, "white"))(absClientInstant(to.at)) case None => now() - } ) case None => nbsp @@ -230,7 +230,7 @@ object perfStat: div(cls := "streak")( h3( title( - if (s.v > 0) tag(color)(trans.nbGames.plural(s.v, strong(s.v))) + if s.v > 0 then tag(color)(trans.nbGames.plural(s.v, strong(s.v))) else "-" ) ), @@ -288,7 +288,7 @@ object perfStat: div(cls := "streak")( h3( title( - if (s.v > 0) trans.nbGames.plural(s.v, strong(s.v)) + if s.v > 0 then trans.nbGames.plural(s.v, strong(s.v)) else "-" ) ), diff --git a/app/views/user/show/gamesContent.scala b/app/views/user/show/gamesContent.scala index 4909ba5646802..e60c8b147e997 100644 --- a/app/views/user/show/gamesContent.scala +++ b/app/views/user/show/gamesContent.scala @@ -31,8 +31,8 @@ object gamesContent: views.html.game.crosstable(_, none) }, div(cls := "search__result")( - if (filterName == "search") { - if (pager.nbResults > 0) + if filterName == "search" then + if pager.nbResults > 0 then frag( div(cls := "search__status")( strong(trans.search.gamesFound.plural(pager.nbResults, pager.nbResults.localize)) @@ -43,20 +43,21 @@ object gamesContent: ) ) else div(cls := "search__status")(strong(trans.noGameFound.txt())) - } else + else div( cls := List( "games infinite-scroll" -> true, "now-playing center" -> (filterName == "playing" && pager.nbResults > 2) ) )( - if (filterName == "playing" && pager.nbResults > 2) + if filterName == "playing" && pager.nbResults > 2 then pager.currentPageResults.flatMap { Pov(_, u) }.map { pov => views.html.game.mini(pov)(cls := "paginated") } else views.html.game - .widgets(pager.currentPageResults, notes, user = u.some, ownerLink = ctx is u), + .widgets(pager.currentPageResults, notes, user = u.some, ownerLink = ctx is u) + , pagerNext(pager, np => routes.User.games(u.username, filterName, np).url) ) ) diff --git a/app/views/user/show/header.scala b/app/views/user/show/header.scala index 2a05db7796dcd..c4e6e44ff7862 100644 --- a/app/views/user/show/header.scala +++ b/app/views/user/show/header.scala @@ -17,13 +17,12 @@ object header: def apply(u: User, info: UserInfo, angle: UserInfo.Angle, social: UserInfo.Social)(using ctx: PageContext) = frag( div(cls := "box__top user-show__header")( - if (u.isPatron) - h1(cls := s"user-link ${if (isOnline(u.id)) "online" else "offline"}")( + if u.isPatron then + h1(cls := s"user-link ${if isOnline(u.id) then "online" else "offline"}")( a(href := routes.Plan.index)(patronIcon), userSpan(u, withPowerTip = false, withOnline = false) ) - else - h1(userSpan(u, withPowerTip = false)), + else h1(userSpan(u, withPowerTip = false)), div( cls := List( "trophies" -> true, @@ -137,16 +136,15 @@ object header: !ctx.is(u) option noteZone(u, social.notes), isGranted(_.UserModView) option div(cls := "mod-zone mod-zone-full none"), standardFlash, - angle match { + angle match case UserInfo.Angle.Games(Some(searchForm)) => views.html.search.user(u, searchForm) case _ => val profile = u.profileOrDefault val hideTroll = u.marks.troll && !ctx.is(u) div(id := "us_profile")( - if (info.ratingChart.isDefined && (!u.lame || ctx.is(u) || isGranted(_.UserModView))) + if info.ratingChart.isDefined && (!u.lame || ctx.is(u) || isGranted(_.UserModView)) then div(cls := "rating-history")(spinner) - else - (ctx.is(u) && u.count.game < 10) option newPlayer(u), + else (ctx.is(u) && u.count.game < 10) option newPlayer(u), div(cls := "profile-side")( div(cls := "user-infos")( !ctx.is(u) option frag( @@ -219,12 +217,12 @@ object header: a(cls := "insight", href := routes.Insight.index(u.username), dataIcon := licon.Target)( span( strong("Chess Insights"), - em("Analytics from ", if (ctx.is(u)) "your" else s"${u.username}'s", " games") + em("Analytics from ", if ctx.is(u) then "your" else s"${u.username}'s", " games") ) ) ) ) - }, + , info.ublog.so(_.latests).nonEmpty option div(cls := "user-show__blog ublog-post-cards")( info.ublog.so(_.latests) map { views.html.ublog.post.card(_, showAuthor = false) } ), @@ -262,7 +260,7 @@ object header: form3.textarea(lila.user.UserForm.note("text"))( placeholder := trans.writeAPrivateNoteAboutThisUser.txt() ), - if (isGranted(_.ModNote)) + if isGranted(_.ModNote) then div(cls := "mod-note")( submitButton(cls := "button", name := "noteType", value := "mod")("Save Mod Note"), isGranted(_.Admin) option submitButton(cls := "button", name := "noteType", value := "dox")( @@ -287,7 +285,7 @@ object header: userIdLink(note.from.some), br, note.dox option "dox ", - if (isGranted(_.ModNote)) momentFromNowServer(note.date) + if isGranted(_.ModNote) then momentFromNowServer(note.date) else momentFromNow(note.date), (ctx.me.exists(note.isFrom) && !note.mod) option frag( br, diff --git a/app/views/user/show/newPlayer.scala b/app/views/user/show/newPlayer.scala index 93cf6862d971f..facd8294e3c8d 100644 --- a/app/views/user/show/newPlayer.scala +++ b/app/views/user/show/newPlayer.scala @@ -21,7 +21,7 @@ object newPlayer: ) ), p( - if (u.kid) "Kid mode is enabled." + if u.kid then "Kid mode is enabled." else frag( "Will a child use this account? You might want to enable ", diff --git a/app/views/user/show/otherTrophies.scala b/app/views/user/show/otherTrophies.scala index 41fee37666354..af0e7ef0090b3 100644 --- a/app/views/user/show/otherTrophies.scala +++ b/app/views/user/show/otherTrophies.scala @@ -70,7 +70,7 @@ object otherTrophies: "trophy award icon3d streamer" -> true, "streaming" -> streaming ), - ariaTitle(if (streaming) "Live now!" else "Lichess Streamer") + ariaTitle(if streaming then "Live now!" else "Lichess Streamer") )(licon.Mic) } ) diff --git a/app/views/user/show/side.scala b/app/views/user/show/side.scala index 25bc52af1ea21..bcb7af649130f 100644 --- a/app/views/user/show/side.scala +++ b/app/views/user/show/side.scala @@ -29,30 +29,33 @@ object side: "active" -> active.has(perfType) ), href := ctx.pref.showRatings.so: - if (isPuzzle) routes.Puzzle.dashboard(30, "home", u.username.some).url + if isPuzzle then routes.Puzzle.dashboard(30, "home", u.username.some).url else routes.User.perfStat(u.username, perfType.key).url , span( h3(perfType.trans), - if (isPuzzle && u.perfs.dubiousPuzzle && !ctx.is(u) && ctx.pref.showRatings) st.rating(strong("?")) + if isPuzzle && u.perfs.dubiousPuzzle && !ctx.is(u) && ctx.pref.showRatings then + st.rating(strong("?")) else st.rating( ctx.pref.showRatings option frag( - if (perf.glicko.clueless) strong("?") + if perf.glicko.clueless then strong("?") else strong( perf.glicko.intRating, perf.provisional.yes option "?" - ), + ) + , " ", ratingProgress(perf.progress), " " ), span( - if (perfType.key.value == "puzzle") trans.nbPuzzles.plural(perf.nb, perf.nb.localize) + if perfType.key.value == "puzzle" then trans.nbPuzzles.plural(perf.nb, perf.nb.localize) else trans.nbGames.plural(perf.nb, perf.nb.localize) ) - ), + ) + , rankMap get perfType ifTrue ctx.pref.showRatings map { rank => span(cls := "rank", title := trans.rankIsUpdatedEveryNbMinutes.pluralSameTxt(15))( trans.rankX(rank.localize) diff --git a/app/views/userTournament/created.scala b/app/views/userTournament/created.scala index 84e23105962c3..b5717b5677f37 100644 --- a/app/views/userTournament/created.scala +++ b/app/views/userTournament/created.scala @@ -19,8 +19,7 @@ object created: path = path, moreJs = infiniteScrollTag ) { - if (pager.nbResults == 0) - div(cls := "box-pad")(u.username, " hasn't created any tournament yet!") + if pager.nbResults == 0 then div(cls := "box-pad")(u.username, " hasn't created any tournament yet!") else div(cls := "tournament-list")( table(cls := "slist")( diff --git a/app/views/userTournament/list.scala b/app/views/userTournament/list.scala index 2b85eb54d5e0f..0784b84276f07 100644 --- a/app/views/userTournament/list.scala +++ b/app/views/userTournament/list.scala @@ -18,8 +18,7 @@ object list: pager: Paginator[lila.tournament.LeaderboardApi.TourEntry], count: String )(using Lang) = - if (pager.nbResults == 0) - div(cls := "box-pad")(u.username, " hasn't played in any tournament yet!") + if pager.nbResults == 0 then div(cls := "box-pad")(u.username, " hasn't played in any tournament yet!") else div(cls := "tournament-list")( table(cls := "slist")( @@ -42,7 +41,7 @@ object list: span(cls := "setup")( e.tour.clock.show, " • ", - if (e.tour.variant.exotic) e.tour.variant.name else e.tour.perfType.trans, + if e.tour.variant.exotic then e.tour.variant.name else e.tour.perfType.trans, " • ", momentFromNow(e.tour.startsAt) ) diff --git a/app/views/userTournament/upcoming.scala b/app/views/userTournament/upcoming.scala index 2e7ef5b01ecc6..bbb0b11597da7 100644 --- a/app/views/userTournament/upcoming.scala +++ b/app/views/userTournament/upcoming.scala @@ -14,8 +14,7 @@ object upcoming: title = s"${u.username} upcoming tournaments", path = "upcoming" ) { - if (pager.nbResults == 0) - div(cls := "box-pad")(u.username, " hasn't joined any tournament yet!") + if pager.nbResults == 0 then div(cls := "box-pad")(u.username, " hasn't joined any tournament yet!") else div(cls := "tournament-list")( table(cls := "slist")( diff --git a/app/views/video/index.scala b/app/views/video/index.scala index 960cfc4045e1f..5016679b528f6 100644 --- a/app/views/video/index.scala +++ b/app/views/video/index.scala @@ -13,7 +13,7 @@ object index: ) = val tagString = - s"${if (control.filter.tags.nonEmpty) control.filter.tags.mkString(" + ") + " • " else ""}" + s"${if control.filter.tags.nonEmpty then control.filter.tags.mkString(" + ") + " • " else ""}" layout( title = s"${tagString}Free Chess Videos", @@ -21,7 +21,7 @@ object index: .OpenGraph( title = s"${tagString}free, carefully curated chess videos", description = s"${videos.nbResults} curated chess videos${ - if (tagString.nonEmpty) " matching the tags " + tagString + if tagString.nonEmpty then " matching the tags " + tagString else " • " }free for all", url = s"$netBaseUrl${routes.Video.index}?${control.queryString}" @@ -31,7 +31,7 @@ object index: )( boxTop( h1( - if (control.filter.tags.nonEmpty) frag(pluralize("video", videos.nbResults), " found") + if control.filter.tags.nonEmpty then frag(pluralize("video", videos.nbResults), " found") else "Chess videos" ), bits.searchForm(control.query) @@ -48,7 +48,7 @@ object index: div(cls := "list box__pad infinite-scroll")( videos.currentPageResults.map { bits.card(_, control) }, videos.currentPageResults.sizeIs < 4 option div(cls := s"not_much nb_${videos.nbResults}")( - if (videos.currentPageResults.isEmpty) "No videos for these tags:" + if videos.currentPageResults.isEmpty then "No videos for these tags:" else "That's all we got for these tags:", control.filter.tags.map { tag => a(cls := "tag", dataIcon := licon.Tag, href := s"${routes.Video.index}?tags=$tag")(tag.capitalize) diff --git a/app/views/video/layout.scala b/app/views/video/layout.scala index 4ed56015febc4..354ee51a84e39 100644 --- a/app/views/video/layout.scala +++ b/app/views/video/layout.scala @@ -38,10 +38,9 @@ object layout: } ), div(cls := "under-tags")( - if (control.filter.tags.nonEmpty) + if control.filter.tags.nonEmpty then a(cls := "button button-empty", href := routes.Video.index)("Clear search") - else - a(dataIcon := licon.Tag, href := routes.Video.tags)("View more tags") + else a(dataIcon := licon.Tag, href := routes.Video.tags)("View more tags") ) ), div(cls := "page-menu__content box")(body) diff --git a/app/views/video/search.scala b/app/views/video/search.scala index 54d8d964294fb..cb189ee093e9b 100644 --- a/app/views/video/search.scala +++ b/app/views/video/search.scala @@ -17,7 +17,7 @@ object search: div(cls := "list infinitescroll box__pad")( videos.currentPageResults.map { bits.card(_, control) }, videos.currentPageResults.sizeIs < 4 option div(cls := s"not_much nb_${videos.nbResults}")( - if (videos.currentPageResults.isEmpty) "No videos for this search:" + if videos.currentPageResults.isEmpty then "No videos for this search:" else "That's all we got for this search:", s""""${~control.query}"""", br, diff --git a/modules/activity/src/main/ActivityReadApi.scala b/modules/activity/src/main/ActivityReadApi.scala index e52cf51fd1867..ed09e58555835 100644 --- a/modules/activity/src/main/ActivityReadApi.scala +++ b/modules/activity/src/main/ActivityReadApi.scala @@ -32,7 +32,7 @@ final class ActivityReadApi( private given Ordering[Double] = scala.math.Ordering.Double.TotalOrdering def recentAndPreload(u: User)(using lang: Lang): Fu[Vector[ActivityView]] = - for { + for activities <- coll( _.find(regexId(u.id)) @@ -49,7 +49,7 @@ final class ActivityReadApi( one(practiceStructure, a).mon(_.user segment "activity.view") }.parallel _ <- preloadAll(views) - } yield addSignup(u.createdAt, views) + yield addSignup(u.createdAt, views) private def preloadAll(views: Seq[ActivityView])(using lang: Lang) = for _ <- lightUserApi.preloadMany(views.flatMap(_.follows.so(_.allUserIds))) @@ -73,10 +73,10 @@ final class ActivityReadApi( .liveLightsByIds(p.value) .mon(_.user segment "activity.ublogs") .dmap(_.some.filter(_.nonEmpty)) - practice = (for { + practice = (for p <- a.practice struct <- practiceStructure - } yield p.value.flatMap { (studyId, nb) => + yield p.value.flatMap { (studyId, nb) => struct study studyId map (_ -> nb) }.toMap) forumPostView = forumPosts.map { p => @@ -169,7 +169,7 @@ final class ActivityReadApi( case ((false, as), a) if a.interval contains at => (true, as :+ a.copy(signup = true)) case ((found, as), a) => (found, as :+ a) } - if (!found && views.sizeIs < Activity.recentNb && nowInstant.minusDays(8).isBefore(at)) + if !found && views.sizeIs < Activity.recentNb && nowInstant.minusDays(8).isBefore(at) then views :+ ActivityView( interval = TimeInterval(at.withTimeAtStartOfDay, at.withTimeAtStartOfDay plusDays 1), signup = true diff --git a/modules/activity/src/main/BSONHandlers.scala b/modules/activity/src/main/BSONHandlers.scala index 179392368ec1e..ef14c61c5f17c 100644 --- a/modules/activity/src/main/BSONHandlers.scala +++ b/modules/activity/src/main/BSONHandlers.scala @@ -18,20 +18,19 @@ private object BSONHandlers: given BSONHandler[Id] = tryHandler( { case BSONString(v) => - v split idSep match { + v split idSep match case Array(userId, dayStr) => Success(Id(UserId(userId), LichessDay(Integer.parseInt(dayStr)))) case _ => handlerBadValue(s"Invalid activity id $v") - } }, id => BSONString(s"${id.userId}$idSep${id.day.value}") ) private given BSONHandler[RatingProg] = tryHandler( { case v: BSONArray => - for { + for before <- v.getAsTry[IntRating](0) after <- v.getAsTry[IntRating](1) - } yield RatingProg(before, after) + yield RatingProg(before, after) }, o => BSONArray(o.before, o.after) ) diff --git a/modules/activity/src/main/activities.scala b/modules/activity/src/main/activities.scala index b8e08508d52c0..69eae082549ea 100644 --- a/modules/activity/src/main/activities.scala +++ b/modules/activity/src/main/activities.scala @@ -71,8 +71,8 @@ object activities: def add(gameId: GameId, moved: Boolean, ended: Boolean) = Corres( moves = moves + (moved so 1), - movesIn = if (moved) (gameId :: movesIn).distinct.take(maxSubEntries) else movesIn, - end = if (ended) (gameId :: end).take(maxSubEntries) else end + movesIn = if moved then (gameId :: movesIn).distinct.take(maxSubEntries) else movesIn, + end = if ended then (gameId :: end).take(maxSubEntries) else end ) object Corres: given Zero[Corres] = Zero(Corres(0, Nil, Nil)) @@ -81,7 +81,7 @@ object activities: case class FollowList(ids: List[UserId], nb: Option[Int]): def actualNb = nb | ids.size def +(id: UserId) = - if (ids contains id) this + if ids contains id then this else val newIds = (id :: ids).distinct copy( diff --git a/modules/analyse/src/main/AccuracyCP.scala b/modules/analyse/src/main/AccuracyCP.scala index e09275c05f7b5..99a8aab8f008b 100644 --- a/modules/analyse/src/main/AccuracyCP.scala +++ b/modules/analyse/src/main/AccuracyCP.scala @@ -7,19 +7,19 @@ import lila.tree.Eval.* object AccuracyCP: def diffsList(pov: SideAndStart, analysis: Analysis): List[Option[Int]] = { - if (pov.color == pov.startColor) Info.start(pov.startedAtPly) :: analysis.infos + if pov.color == pov.startColor then Info.start(pov.startedAtPly) :: analysis.infos else analysis.infos }.map(_.eval) .grouped(2) .collect { case List(e1, e2) => - for { s1 <- e1.forceAsCp; s2 <- e2.forceAsCp } yield { + for s1 <- e1.forceAsCp; s2 <- e2.forceAsCp yield { (s2.ceiled.value - s1.ceiled.value) * pov.color.fold(-1, 1) } atLeast 0 } .toList def prevColorInfos(pov: SideAndStart, analysis: Analysis): List[Info] = { - if (pov.color == pov.startColor) Info.start(pov.startedAtPly) :: analysis.infos + if pov.color == pov.startColor then Info.start(pov.startedAtPly) :: analysis.infos else analysis.infos }.zipWithIndex.collect { case (e, i) if (i % 2) == 0 => e diff --git a/modules/analyse/src/main/AccuracyPercent.scala b/modules/analyse/src/main/AccuracyPercent.scala index e2c784f595c6a..1a96f6acb1b1a 100644 --- a/modules/analyse/src/main/AccuracyPercent.scala +++ b/modules/analyse/src/main/AccuracyPercent.scala @@ -42,7 +42,7 @@ for x in xs: print(f"f({x}) = {model_func(x, a, k, b)}"); */ def fromWinPercents(before: WinPercent, after: WinPercent): AccuracyPercent = AccuracyPercent { - if (after.value >= before.value) 100d + if after.value >= before.value then 100d else { val winDiff = before.value - after.value @@ -53,7 +53,8 @@ for x in xs: def fromEvalsAndPov(pov: Game.SideAndStart, evals: List[Eval]): List[AccuracyPercent] = val subjectiveEvals = pov.color.fold(evals, evals.map(_.invert)) - val alignedEvals = if (pov.color == pov.startColor) Eval.initial :: subjectiveEvals else subjectiveEvals + val alignedEvals = + if pov.color == pov.startColor then Eval.initial :: subjectiveEvals else subjectiveEvals alignedEvals .grouped(2) .collect { case List(e1, e2) => diff --git a/modules/analyse/src/main/Advice.scala b/modules/analyse/src/main/Advice.scala index d7d7fa4e63034..229e524bfae2d 100644 --- a/modules/analyse/src/main/Advice.scala +++ b/modules/analyse/src/main/Advice.scala @@ -15,10 +15,10 @@ sealed trait Advice: withEval.so(evalComment so { c => s"($c) " }) + - this.match { + this.match case MateAdvice(seq, _, _, _) => seq.desc case CpAdvice(judgment, _, _) => judgment.toString - } + "." + { + + "." + { withBestMove.so: info.variation.headOption.so: move => s" $move was best." @@ -57,7 +57,7 @@ private[analyse] object CpAdvice: ) def apply(prev: Info, info: Info): Option[CpAdvice] = - for { + for cp <- prev.cp infoCp <- info.cp prevWinningChances = WinPercent.winningChances(cp) @@ -66,7 +66,7 @@ private[analyse] object CpAdvice: info.color.fold(-d, d) } judgement <- winningChanceJudgements find { case (d, _) => d <= delta } map (_._2) - } yield CpAdvice(judgement, info, prev) + yield CpAdvice(judgement, info, prev) sealed abstract private[analyse] class MateSequence(val desc: String) private[analyse] case object MateCreated diff --git a/modules/analyse/src/main/RequesterApi.scala b/modules/analyse/src/main/RequesterApi.scala index 8b7ef0bec190a..1d2c54e023273 100644 --- a/modules/analyse/src/main/RequesterApi.scala +++ b/modules/analyse/src/main/RequesterApi.scala @@ -14,7 +14,7 @@ final class RequesterApi(coll: Coll)(using Executor): $id(requester), $inc( "total" -> 1, - formatter.print(nowInstant) -> (if (ownGame) 1 else 2) + formatter.print(nowInstant) -> (if ownGame then 1 else 2) ), upsert = true ) diff --git a/modules/analyse/src/test/AccuracyPercentTest.scala b/modules/analyse/src/test/AccuracyPercentTest.scala index 5270bc2622c13..cf427f4a59622 100644 --- a/modules/analyse/src/test/AccuracyPercentTest.scala +++ b/modules/analyse/src/test/AccuracyPercentTest.scala @@ -4,9 +4,9 @@ import chess.{ ByColor, Color } import lila.tree.Eval.Cp import lila.common.Maths.isCloseTo -class AccuracyPercentTest extends munit.FunSuite { +class AccuracyPercentTest extends munit.FunSuite: - import AccuracyPercent._ + import AccuracyPercent.* type AccMap = ByColor[AccuracyPercent] def compute(cps: List[Int]): Option[AccMap] = @@ -102,4 +102,3 @@ class AccuracyPercentTest extends munit.FunSuite { assert(isCloseTo(a.black.value, 10d, 5d)) assert(isCloseTo(a.white.value, 10d, 5d)) } -} diff --git a/modules/api/src/main/AccountClosure.scala b/modules/api/src/main/AccountClosure.scala index 4901eeebe73b1..7a2c26819cbcd 100644 --- a/modules/api/src/main/AccountClosure.scala +++ b/modules/api/src/main/AccountClosure.scala @@ -54,7 +54,7 @@ final class AccountClosure( _ <- streamerApi.demote(u.id) reports <- reportApi.processAndGetBySuspect(lila.report.Suspect(u)) _ <- - if (selfClose) modLogApi.selfCloseAccount(u.id, reports) + if selfClose then modLogApi.selfCloseAccount(u.id, reports) else modLogApi.closeAccount(u.id) _ <- appealApi.onAccountClose(u) _ <- u.marks.troll so relationApi.fetchFollowing(u.id).flatMap { diff --git a/modules/api/src/main/AnnounceStore.scala b/modules/api/src/main/AnnounceStore.scala index 92cd029ef51aa..fcb2dc3fd28c5 100644 --- a/modules/api/src/main/AnnounceStore.scala +++ b/modules/api/src/main/AnnounceStore.scala @@ -11,7 +11,7 @@ object AnnounceStore: def get: Option[Announce] = current foreach { c => - if (c.date.isBeforeNow) current = none + if c.date.isBeforeNow then current = none } current @@ -22,7 +22,7 @@ object AnnounceStore: // 5 minutes Lichess will restart // 20 seconds Cthulhu will awake def set(str: String): Option[Announce] = - set(str.split(" ").toList match { + set(str.split(" ").toList match case length :: unit :: rest => Try { val msg = rest mkString " " @@ -32,7 +32,7 @@ object AnnounceStore: Announce(msg, date, json) }.toOption case _ => none - }) + ) get def cancel = Announce("", nowInstant, Json.obj()) diff --git a/modules/api/src/main/Env.scala b/modules/api/src/main/Env.scala index 020cd22c4c050..456ba09ac3cfd 100644 --- a/modules/api/src/main/Env.scala +++ b/modules/api/src/main/Env.scala @@ -105,7 +105,7 @@ final class Env( endpoint = config.influxEventEndpoint, env = config.influxEventEnv ) - if (mode == Mode.Prod) scheduler.scheduleOnce(5 seconds)(influxEvent.start()) + if mode == Mode.Prod then scheduler.scheduleOnce(5 seconds)(influxEvent.start()) private lazy val linkCheck = wire[LinkCheck] lazy val chatFreshness = wire[ChatFreshness] diff --git a/modules/api/src/main/EventStream.scala b/modules/api/src/main/EventStream.scala index 7d655baa90751..31c263474fda7 100644 --- a/modules/api/src/main/EventStream.scala +++ b/modules/api/src/main/EventStream.scala @@ -98,7 +98,7 @@ final class EventStream( case lila.challenge.Event.Create(c) if isMyChallenge(c) => val json = challengeJson("challenge")(c) ++ challengeCompat(c) lila.common.LilaFuture // give time for anon challenger to load the challenge page - .delay(if (c.challengerIsAnon) 2.seconds else 0.seconds) { + .delay(if c.challengerIsAnon then 2.seconds else 0.seconds) { queue.offer(json.some).void } .unit diff --git a/modules/api/src/main/GameApi.scala b/modules/api/src/main/GameApi.scala index a163ae3bdde17..daf3f25a74fdf 100644 --- a/modules/api/src/main/GameApi.scala +++ b/modules/api/src/main/GameApi.scala @@ -40,7 +40,7 @@ final private[api] class GameApi( adapter = Adapter[Game]( collection = gameRepo.coll, selector = { - if (~playing) lila.game.Query.nowPlaying(user.id) + if ~playing then lila.game.Query.nowPlaying(user.id) else $doc( G.playerUids -> user.id, @@ -60,7 +60,7 @@ final private[api] class GameApi( sort = $doc(G.createdAt -> -1), _.sec ).withNbResults( - if (~playing) gameCache.nbPlaying(user.id) + if ~playing then gameCache.nbPlaying(user.id) else fuccess: rated.fold(user.count.game): @@ -91,7 +91,7 @@ final private[api] class GameApi( adapter = Adapter[Game]( collection = gameRepo.coll, selector = { - if (~playing) lila.game.Query.nowPlayingVs(users._1.id, users._2.id) + if ~playing then 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, @@ -110,7 +110,7 @@ final private[api] class GameApi( sort = $doc(G.createdAt -> -1), _.sec ).withNbResults( - if (~playing) gameCache.nbPlaying(users._1.id) + if ~playing then gameCache.nbPlaying(users._1.id) else crosstableApi(users._1.id, users._2.id).dmap(_.nbGames) ), currentPage = page, @@ -135,7 +135,7 @@ final private[api] class GameApi( adapter = Adapter[Game]( collection = gameRepo.coll, selector = { - if (~playing) lila.game.Query.nowPlayingVs(userIds) + if ~playing then lila.game.Query.nowPlayingVs(userIds) else lila.game.Query.opponents(userIds) ++ $doc( G.status $gte chess.Status.Mate.id, @@ -167,7 +167,7 @@ final private[api] class GameApi( private def gamesJson(withFlags: WithFlags)(games: Seq[Game]): Fu[Seq[JsObject]] = val allAnalysis = - if (withFlags.analysis) analysisRepo byIds games.map(_.id into Analysis.Id) + if withFlags.analysis then analysisRepo byIds games.map(_.id into Analysis.Id) else fuccess(List.fill(games.size)(none[Analysis])) allAnalysis flatMap { analysisOptions => (games map gameRepo.initialFen).parallel map { initialFens => diff --git a/modules/api/src/main/GameApiV2.scala b/modules/api/src/main/GameApiV2.scala index 8ad60c0e2fe8f..8de217151a611 100644 --- a/modules/api/src/main/GameApiV2.scala +++ b/modules/api/src/main/GameApiV2.scala @@ -104,7 +104,7 @@ final class GameApiV2( Source.futureSource: config.playerFile.so(realPlayerApi.apply) map { realPlayers => val playerSelect = - if (config.finished) + if config.finished then config.vs.fold(Query.user(config.user.id)) { Query.opponents(config.user, _) } else config.vs.map(_.id).fold(Query.nowPlaying(config.user.id)) { @@ -119,7 +119,7 @@ final class GameApiV2( ) .documentSource() .map(g => config.postFilter(g) option g) - .throttle(config.perSecond.value * 10, 1 second, e => if (e.isDefined) 10 else 2) + .throttle(config.perSecond.value * 10, 1 second, e => if e.isDefined then 10 else 2) .mapConcat(_.toList) .take(config.max | Int.MaxValue) .via(upgradeOngoingGame) @@ -178,7 +178,7 @@ final class GameApiV2( case Format.PGN => pgnDump.formatter(config.flags)(game, fen, analysis, teams, none) case Format.JSON => def addBerserk(color: chess.Color)(json: JsObject) = - if (pairing berserkOf color) + if pairing berserkOf color then json deepMerge Json.obj( "players" -> Json.obj(color.name -> Json.obj("berserk" -> true)) ) @@ -320,7 +320,7 @@ object GameApiV2: enum Format: case PGN, JSON object Format: - def byRequest(req: play.api.mvc.RequestHeader) = if (HTTPRequest acceptsNdJson req) JSON else PGN + def byRequest(req: play.api.mvc.RequestHeader) = if HTTPRequest acceptsNdJson req then JSON else PGN sealed trait Config: val format: Format diff --git a/modules/api/src/main/InfluxEvent.scala b/modules/api/src/main/InfluxEvent.scala index 926bd17aa59f8..1cef2f1dcf040 100644 --- a/modules/api/src/main/InfluxEvent.scala +++ b/modules/api/src/main/InfluxEvent.scala @@ -19,5 +19,5 @@ final class InfluxEvent( .post(s"""event,program=lila,env=$env,title=$key text="$text"""") .effectFold( err => lila.log("influxEvent").error(endpoint, err), - res => if (res.status != 204) lila.log("influxEvent").error(s"$endpoint ${res.status}") + res => if res.status != 204 then lila.log("influxEvent").error(s"$endpoint ${res.status}") ) diff --git a/modules/api/src/main/LinkCheck.scala b/modules/api/src/main/LinkCheck.scala index c3ee6fd0f7192..c7134229f7357 100644 --- a/modules/api/src/main/LinkCheck.scala +++ b/modules/api/src/main/LinkCheck.scala @@ -33,7 +33,7 @@ final private class LinkCheck( import LinkCheck.* def apply(line: UserLine, source: PublicSource): Fu[Boolean] = - if (multipleLinks find line.text) fuFalse + if multipleLinks find line.text then fuFalse else line.text match case tournamentLinkR(id) => withSource(source, tourLink)(id, line) @@ -56,7 +56,7 @@ final private class LinkCheck( case _ => fuccess(none) } flatMapz { source => // the owners of a chat can post whichever link they like - if (source.owners(line.userId)) fuTrue + if source.owners(line.userId) then fuTrue else f(id, source) } diff --git a/modules/api/src/main/PagerDuty.scala b/modules/api/src/main/PagerDuty.scala index c0f4f5087acd9..b929d0ad0406c 100644 --- a/modules/api/src/main/PagerDuty.scala +++ b/modules/api/src/main/PagerDuty.scala @@ -34,10 +34,9 @@ final private class PagerDuty(ws: StandaloneWSClient, config: ApiConfig.PagerDut .addEffects( err => logger.error("lilaRestart failed", err), res => - if (res.status != 201) { + if res.status != 201 then println(res.body) logger.warn(s"lilaRestart status=${res.status}") - } ) .void diff --git a/modules/api/src/main/PersonalDataExport.scala b/modules/api/src/main/PersonalDataExport.scala index b781d5042ec96..abdce7e7541c0 100644 --- a/modules/api/src/main/PersonalDataExport.scala +++ b/modules/api/src/main/PersonalDataExport.scala @@ -191,7 +191,7 @@ final class PersonalDataExport( val outro = Source(List(textTitle("End of data export."))) - List[Source[String, _]]( + List[Source[String, ?]]( intro, connections, followedUsers, diff --git a/modules/api/src/main/PgnDump.scala b/modules/api/src/main/PgnDump.scala index fac4e5f260317..6e61b68dcc0a6 100644 --- a/modules/api/src/main/PgnDump.scala +++ b/modules/api/src/main/PgnDump.scala @@ -28,7 +28,7 @@ final class PgnDump( realPlayers: Option[RealPlayers] = None ): Fu[Pgn] = dumper(game, initialFen, flags, teams) flatMap { pgn => - if (flags.tags) + if flags.tags then (game.simulId so simulApi.idToName) .orElse(game.tournamentId so getTournamentName.async) .orElse(game.swissId so getSwissName.async) map { @@ -37,7 +37,7 @@ final class PgnDump( else fuccess(pgn) } map { pgn => val evaled = analysis.ifTrue(flags.evals).fold(pgn)(annotator.addEvals(pgn, _)) - if (flags.literate) annotator(evaled, game, analysis) + if flags.literate then annotator(evaled, game, analysis) else evaled } map { pgn => realPlayers.fold(pgn)(_.update(game, pgn)) diff --git a/modules/api/src/main/RoundApi.scala b/modules/api/src/main/RoundApi.scala index ce5f9a786ce52..60841babf807e 100644 --- a/modules/api/src/main/RoundApi.scala +++ b/modules/api/src/main/RoundApi.scala @@ -195,7 +195,7 @@ final private[api] class RoundApi( )) private def withNote(note: String)(json: JsObject) = - if (note.isEmpty) json else json + ("note" -> JsString(note)) + if note.isEmpty then json else json + ("note" -> JsString(note)) private def withBookmark(v: Boolean)(json: JsObject) = json.add("bookmarked" -> v) @@ -220,13 +220,14 @@ final private[api] class RoundApi( ) private def withForecast(pov: Pov, owner: Boolean, fco: Option[Forecast])(json: JsObject) = - if (pov.game.forecastable && owner) + if pov.game.forecastable && owner then json + ( "forecast" -> { - if (pov.forecastable) fco.fold[JsValue](Json.obj("none" -> true)) { fc => - import Forecast.given - Json toJson fc - } + if pov.forecastable then + fco.fold[JsValue](Json.obj("none" -> true)) { fc => + import Forecast.given + Json toJson fc + } else Json.obj("onMyTurn" -> true) } ) diff --git a/modules/api/src/main/UserGameApi.scala b/modules/api/src/main/UserGameApi.scala index 257cc6324da69..11c116e8e0e96 100644 --- a/modules/api/src/main/UserGameApi.scala +++ b/modules/api/src/main/UserGameApi.scala @@ -20,11 +20,11 @@ final class UserGameApi( import LightUser.lightUserWrites def jsPaginator(pag: Paginator[Game])(using ctx: Context): Fu[JsObject] = - for { + for bookmarkedIds <- bookmarkApi.filterGameIdsBookmarkedBy(pag.currentPageResults, ctx.me) _ <- lightUser.preloadMany(pag.currentPageResults.flatMap(_.userIds)) _ <- getTournamentName.preload(pag.currentPageResults.flatMap(_.tournamentId))(using ctx.lang) - } yield + yield given Writes[Game] = Writes { g => write(g, bookmarkedIds(g.id), ctx.me)(using ctx.lang) } diff --git a/modules/api/src/test/LpvGameRegexTest.scala b/modules/api/src/test/LpvGameRegexTest.scala index b5c7282fbc95c..758e24b1d3753 100644 --- a/modules/api/src/test/LpvGameRegexTest.scala +++ b/modules/api/src/test/LpvGameRegexTest.scala @@ -2,7 +2,7 @@ package lila.api import lila.common.config.NetDomain -class LpvGameRegexTest extends munit.FunSuite { +class LpvGameRegexTest extends munit.FunSuite: val re = LpvGameRegex(NetDomain("boo.org:8080")) @@ -129,4 +129,3 @@ class LpvGameRegexTest extends munit.FunSuite { test("blog links extract game id 2") { assert(group(re.gamePgnsRe, "boo.org:8080/1234abcd1234#123", 1).contains("1234abcd")) } -} diff --git a/modules/api/src/test/MultiKeyMapTest.scala b/modules/api/src/test/MultiKeyMapTest.scala index fb2b8dfcd8dd5..3a76f952c2a50 100644 --- a/modules/api/src/test/MultiKeyMapTest.scala +++ b/modules/api/src/test/MultiKeyMapTest.scala @@ -1,6 +1,6 @@ package lila.lobby -class MultiKeyMapTest extends munit.FunSuite { +class MultiKeyMapTest extends munit.FunSuite: case class V(a: Int, b: Int) @@ -24,4 +24,3 @@ class MultiKeyMapTest extends munit.FunSuite { test("expose keys") { assertEquals(m.key1s.toSet, Set(1)) } -} diff --git a/modules/api/src/test/ReferrerRedirectTest.scala b/modules/api/src/test/ReferrerRedirectTest.scala index a725c4012445f..ae82dd6a489ec 100644 --- a/modules/api/src/test/ReferrerRedirectTest.scala +++ b/modules/api/src/test/ReferrerRedirectTest.scala @@ -2,7 +2,7 @@ package lila.api import lila.common.config.BaseUrl -class ReferrerRedirectTest extends munit.FunSuite { +class ReferrerRedirectTest extends munit.FunSuite: def r = new ReferrerRedirect(BaseUrl("https://lichess.org")) @@ -32,4 +32,3 @@ class ReferrerRedirectTest extends munit.FunSuite { assertEquals(r.valid("/ /evil.com"), None) assertEquals(r.valid("http://lichess.org/"), None) // downgrade to http } -} diff --git a/modules/appeal/src/main/Appeal.scala b/modules/appeal/src/main/Appeal.scala index 54c3c816eab9e..47ff8ba1840e1 100644 --- a/modules/appeal/src/main/Appeal.scala +++ b/modules/appeal/src/main/Appeal.scala @@ -32,11 +32,11 @@ case class Appeal( msgs = msgs :+ msg, updatedAt = nowInstant, status = - if (isByMod(msg) && isUnread) Appeal.Status.Read - else if (!isByMod(msg) && isRead) Appeal.Status.Unread + if isByMod(msg) && isUnread then Appeal.Status.Read + else if !isByMod(msg) && isRead then Appeal.Status.Unread else status, firstUnrepliedAt = - if (isByMod(msg) || msgs.lastOption.exists(isByMod) || isRead) nowInstant + if isByMod(msg) || msgs.lastOption.exists(isByMod) || isRead then nowInstant else firstUnrepliedAt ) @@ -51,7 +51,7 @@ case class Appeal( def unread = copy(status = Appeal.Status.Unread) def read = copy(status = Appeal.Status.Read) - def toggleMute = if (isMuted) read else copy(status = Appeal.Status.Muted) + def toggleMute = if isMuted then read else copy(status = Appeal.Status.Muted) def isByMod(msg: AppealMsg) = msg.by != id diff --git a/modules/appeal/src/main/AppealApi.scala b/modules/appeal/src/main/AppealApi.scala index a13242049822d..61ec9d32b9d50 100644 --- a/modules/appeal/src/main/AppealApi.scala +++ b/modules/appeal/src/main/AppealApi.scala @@ -79,7 +79,7 @@ final class AppealApi( .aggregateList(maxDocs = nb, _.sec): framework => import framework.* Match(selector) -> List( - Sort((if (ascending) Ascending.apply else Descending.apply) ("firstUnrepliedAt")), + Sort((if ascending then Ascending.apply else Descending.apply) ("firstUnrepliedAt")), Limit(nb), PipelineOperator( $lookup.simple( diff --git a/modules/blog/src/main/LastPostCache.scala b/modules/blog/src/main/LastPostCache.scala index ab4ecc9b6a985..08453b3f5e60f 100644 --- a/modules/blog/src/main/LastPostCache.scala +++ b/modules/blog/src/main/LastPostCache.scala @@ -30,7 +30,7 @@ final class LastPostCache( private def maybeNotifyLastPost(post: Option[MiniPost]): Unit = post foreach { last => - if (lastNotifiedId.so(last.id !=)) notifier(last.id) + if lastNotifiedId.so(last.id !=) then notifier(last.id) lastNotifiedId = last.id.some } diff --git a/modules/blog/src/main/Youtube.scala b/modules/blog/src/main/Youtube.scala index 5a1c6629f1210..f0746f0bd54e1 100644 --- a/modules/blog/src/main/Youtube.scala +++ b/modules/blog/src/main/Youtube.scala @@ -14,28 +14,26 @@ object Youtube: def fixStartTimes(html: Html) = Html { EmbedRegex.replaceAllIn( html.value, - m => { + m => val orig = m group 0 parseSeconds(m group 1).fold(orig)(seconds => s"$orig&start=$seconds") - } ) } private def parseSeconds(text: String) = text match case HourMinSecRegex(hourS, minS, secS) => - for { + for hour <- hourS.toIntOption min <- minS.toIntOption sec <- secS.toIntOption - } yield 3600 * hour + 60 * min + sec + yield 3600 * hour + 60 * min + sec case MinSecRegex(minS, secS) => - for { + for min <- minS.toIntOption sec <- secS.toIntOption - } yield 60 * min + sec + yield 60 * min + sec case SecRegex(secS) => - for { - sec <- secS.toIntOption - } yield sec + for sec <- secS.toIntOption + yield sec case _ => None diff --git a/modules/blog/src/test/Fixtures.scala b/modules/blog/src/test/Fixtures.scala index b3392ff6ceef7..88e0d542761f8 100644 --- a/modules/blog/src/test/Fixtures.scala +++ b/modules/blog/src/test/Fixtures.scala @@ -1,6 +1,6 @@ package lila.blog -object Fixtures { +object Fixtures: def noYoutube = Html { """ @@ -353,4 +353,3 @@ object Fixtures {

Beginners may be best served by playing conventional e4/d4 systems as white and the French as black. Avoid pawn moves which weaken key squares; fortify weak squares around your king. Maintain the initiative and attack. Sac when it draws the king out and you have a follow-up. Emphasize king safety over material gain. Calculate what your opponent (and you) can do with exchanged pieces before entering into tactical complications. Go crazy!

""" } -} diff --git a/modules/blog/src/test/YoutubeTest.scala b/modules/blog/src/test/YoutubeTest.scala index df3b69089484f..5fd2b1275bf20 100644 --- a/modules/blog/src/test/YoutubeTest.scala +++ b/modules/blog/src/test/YoutubeTest.scala @@ -1,6 +1,6 @@ package lila.blog -class YoutubeTest extends munit.FunSuite { +class YoutubeTest extends munit.FunSuite: test("no youtube embed") { assertEquals(Youtube.fixStartTimes(Fixtures.noYoutube), Fixtures.noYoutube) @@ -18,4 +18,3 @@ class YoutubeTest extends munit.FunSuite { ) ) } -} diff --git a/modules/bookmark/src/main/Env.scala b/modules/bookmark/src/main/Env.scala index d2cd71feb8bd9..cba6805dad3fd 100644 --- a/modules/bookmark/src/main/Env.scala +++ b/modules/bookmark/src/main/Env.scala @@ -31,11 +31,12 @@ final class Env( lazy val api = wire[BookmarkApi] system.actorOf( - Props(new Actor { - def receive = { - case Toggle(gameId, userId) => api.toggle(gameId, userId).unit - case Remove(gameId) => api.removeByGameId(gameId).unit - } - }), + Props( + new Actor: + def receive = { + case Toggle(gameId, userId) => api.toggle(gameId, userId).unit + case Remove(gameId) => api.removeByGameId(gameId).unit + } + ), name = config.actorName ) diff --git a/modules/bot/src/main/BotJsonView.scala b/modules/bot/src/main/BotJsonView.scala index 53823364d9233..d8360af1e1b91 100644 --- a/modules/bot/src/main/BotJsonView.scala +++ b/modules/bot/src/main/BotJsonView.scala @@ -65,7 +65,7 @@ final class BotJsonView( def chatLine(username: UserName, text: String, player: Boolean) = Json.obj( "type" -> "chatLine", - "room" -> (if (player) "player" else "spectator"), + "room" -> (if player then "player" else "spectator"), "username" -> username, "text" -> text ) diff --git a/modules/bot/src/main/BotPlayer.scala b/modules/bot/src/main/BotPlayer.scala index 3741ea9cd192e..e8f423764273f 100644 --- a/modules/bot/src/main/BotPlayer.scala +++ b/modules/bot/src/main/BotPlayer.scala @@ -25,8 +25,8 @@ final class BotPlayer( if !pov.isMyTurn then clientError("Not your turn, or game already over") else val promise = Promise[Unit]() - if (pov.player.isOfferingDraw && offeringDraw.has(false)) declineDraw(pov) - else if (!pov.player.isOfferingDraw && ~offeringDraw) offerDraw(pov) + if pov.player.isOfferingDraw && offeringDraw.has(false) then declineDraw(pov) + else if !pov.player.isOfferingDraw && ~offeringDraw then offerDraw(pov) tellRound(pov.gameId, BotPlay(pov.playerId, uci, promise.some)) promise.future.recover: case _: lila.round.GameIsFinishedError if ~offeringDraw => () @@ -35,7 +35,7 @@ final class BotPlayer( !spam.detect(d.text) so fuccess: lila.mon.bot.chats(me.username.value).increment() - val chatId = ChatId(if (d.room == "player") gameId.value else s"$gameId/w") + val chatId = ChatId(if d.room == "player" then gameId.value else s"$gameId/w") val source = d.room == "spectator" option { lila.hub.actorApi.shutup.PublicSource.Watcher(gameId) } @@ -49,9 +49,9 @@ final class BotPlayer( rematches.prevGameIdOffering(challengeId) so gameRepo.game map { _.flatMap(Pov(_, me)) so { pov => // delay so it feels more natural - lila.common.LilaFuture.delay(if (accept) 100.millis else 1.second) { + lila.common.LilaFuture.delay(if accept then 100.millis else 1.second) { fuccess { - tellRound(pov.gameId, if (accept) RematchYes(pov.playerId) else RematchNo(pov.playerId)) + tellRound(pov.gameId, if accept then RematchYes(pov.playerId) else RematchNo(pov.playerId)) } } true @@ -62,34 +62,35 @@ final class BotPlayer( Bus.publish(Tell(id.value, msg), "roundSocket") def abort(pov: Pov): Funit = - if (!pov.game.abortableByUser) clientError("This game can no longer be aborted") + if !pov.game.abortableByUser then clientError("This game can no longer be aborted") else fuccess { tellRound(pov.gameId, Abort(pov.playerId)) } def resign(pov: Pov): Funit = - if (pov.game.abortableByUser) fuccess { - tellRound(pov.gameId, Abort(pov.playerId)) - } - else if (pov.game.resignable) fuccess { - tellRound(pov.gameId, Resign(pov.playerId)) - } + if pov.game.abortableByUser then + fuccess { + tellRound(pov.gameId, Abort(pov.playerId)) + } + else if pov.game.resignable then + fuccess { + tellRound(pov.gameId, Resign(pov.playerId)) + } else clientError("This game cannot be resigned") private def declineDraw(pov: Pov): Unit = - if (pov.game.drawable && pov.opponent.isOfferingDraw) - tellRound(pov.gameId, DrawNo(pov.playerId)) + if pov.game.drawable && pov.opponent.isOfferingDraw then tellRound(pov.gameId, DrawNo(pov.playerId)) private def offerDraw(pov: Pov): Unit = - if (pov.game.drawable && (pov.game.playerCanOfferDraw(pov.color) || pov.opponent.isOfferingDraw)) + if pov.game.drawable && (pov.game.playerCanOfferDraw(pov.color) || pov.opponent.isOfferingDraw) then tellRound(pov.gameId, DrawYes(pov.playerId)) def setDraw(pov: Pov, v: Boolean): Unit = - if (v) offerDraw(pov) else declineDraw(pov) + if v then offerDraw(pov) else declineDraw(pov) def setTakeback(pov: Pov, v: Boolean): Unit = - if (pov.game.playable && pov.game.canTakebackOrAddTime) + if pov.game.playable && pov.game.canTakebackOrAddTime then tellRound(pov.gameId, if v then TakebackYes(pov.playerId) else TakebackNo(pov.playerId)) def claimVictory(pov: Pov): Funit = diff --git a/modules/bot/src/main/GameStateStream.scala b/modules/bot/src/main/GameStateStream.scala index 6c92c91431b35..7c9838755220b 100644 --- a/modules/bot/src/main/GameStateStream.scala +++ b/modules/bot/src/main/GameStateStream.scala @@ -87,7 +87,7 @@ final class GameStateStream( // prepend the full game JSON at the start of the stream queue offer json.some // close stream if game is over - if (init.game.finished) onGameOver(none) + if init.game.finished then onGameOver(none) else self ! SetOnline } lila.mon.bot.gameStream("start").increment() @@ -98,7 +98,7 @@ final class GameStateStream( Bus.unsubscribe(self, classifiers) // hang around if game is over // so the opponent has a chance to rematch - context.system.scheduler.scheduleOnce(if (gameOver) 10 second else 1 second): + context.system.scheduler.scheduleOnce(if gameOver then 10 second else 1 second): Bus.publish(Tell(init.game.id.value, BotConnected(as, v = false)), "roundSocket") queue.complete() lila.mon.bot.gameStream("stop").increment().unit diff --git a/modules/bot/src/main/OnlineApiUsers.scala b/modules/bot/src/main/OnlineApiUsers.scala index 7362cc2cddd50..b3f3d93e6830a 100644 --- a/modules/bot/src/main/OnlineApiUsers.scala +++ b/modules/bot/src/main/OnlineApiUsers.scala @@ -19,7 +19,7 @@ final class OnlineApiUsers( def setOnline(userId: UserId): Unit = val wasOffline = !isOnline(userId) && !cache.get(userId) cache.put(userId) - if (wasOffline) publish(userId, isOnline = true) + if wasOffline then publish(userId, isOnline = true) def get: Set[UserId] = cache.keySet diff --git a/modules/challenge/src/main/BSONHandlers.scala b/modules/challenge/src/main/BSONHandlers.scala index 45c5df80a4486..c9c3f1c32490f 100644 --- a/modules/challenge/src/main/BSONHandlers.scala +++ b/modules/challenge/src/main/BSONHandlers.scala @@ -63,8 +63,8 @@ private object BSONHandlers: given BSON[Challenger] with def reads(r: Reader) = - if (r contains "id") registeredHandler reads r - else if (r contains "s") anonHandler reads r + if r contains "id" then registeredHandler reads r + else if r contains "s" then anonHandler reads r else Challenger.Open def writes(w: Writer, c: Challenger) = c match diff --git a/modules/challenge/src/main/ChallengeApi.scala b/modules/challenge/src/main/ChallengeApi.scala index 02f2c002a6ea6..175b53d410d32 100644 --- a/modules/challenge/src/main/ChallengeApi.scala +++ b/modules/challenge/src/main/ChallengeApi.scala @@ -84,7 +84,7 @@ final class ChallengeApi( def createdByChallengerId = repo.createdByChallengerId() def createdByDestId(userId: UserId, max: Int = 50) = countInFor get userId flatMap { nb => - if (nb > 5) repo.createdByPopularDestId(max)(userId) + if nb > 5 then repo.createdByPopularDestId(max)(userId) else repo.createdByDestId()(userId) } @@ -213,4 +213,4 @@ final class ChallengeApi( // work around circular dependency private var socket: Option[ChallengeSocket] = None - private[challenge] def registerSocket(s: ChallengeSocket) = { socket = s.some } + private[challenge] def registerSocket(s: ChallengeSocket) = socket = s.some diff --git a/modules/challenge/src/main/ChallengeJoiner.scala b/modules/challenge/src/main/ChallengeJoiner.scala index 7ac69e4794b55..e40ec4edd8612 100644 --- a/modules/challenge/src/main/ChallengeJoiner.scala +++ b/modules/challenge/src/main/ChallengeJoiner.scala @@ -40,7 +40,7 @@ private object ChallengeJoiner: chess = chessGame, whitePlayer = Player.make(chess.White, c.finalColor.fold(origUser, destUser).map(_ only c.perfType)), blackPlayer = Player.make(chess.Black, c.finalColor.fold(destUser, origUser).map(_ only c.perfType)), - mode = if (chessGame.board.variant.fromPosition) Mode.Casual else c.mode, + mode = if chessGame.board.variant.fromPosition then Mode.Casual else c.mode, source = Source.Friend, daysPerTurn = c.daysPerTurn, pgnImport = None, @@ -70,9 +70,8 @@ private object ChallengeJoiner: startedAtPly = sp.ply, clock = tc.realTime.map(_.toClock) ) - if (variant.fromPosition && Fen.write(game).isInitial) - makeChess(chess.variant.Standard) -> none - else game -> baseState + if variant.fromPosition && Fen.write(game).isInitial then makeChess(chess.variant.Standard) -> none + else game -> baseState def addGameHistory(position: Option[Situation.AndFullMoveNumber])(game: Game): Game = position.fold(game): sp => diff --git a/modules/challenge/src/main/ChallengeRepo.scala b/modules/challenge/src/main/ChallengeRepo.scala index cf10a12810298..c5eda616a6bd3 100644 --- a/modules/challenge/src/main/ChallengeRepo.scala +++ b/modules/challenge/src/main/ChallengeRepo.scala @@ -38,13 +38,13 @@ final private class ChallengeRepo(colls: ChallengeColls)(using def createdByDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = createdList($doc("destUser.id" -> userId), max) - def createdByPopularDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = for { + def createdByPopularDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = for realTime <- createdList($doc("destUser.id" -> userId, "timeControl.l" $exists true), max) corres <- (realTime.sizeIs < max) so createdList( $doc($doc("destUser.id" -> userId), "timeControl.l" $exists false), max - realTime.size ) - } yield realTime ::: corres + yield realTime ::: corres def setChallenger(c: Challenge, color: Option[chess.Color]) = coll.update diff --git a/modules/challenge/src/test/JoinerTest.scala b/modules/challenge/src/test/JoinerTest.scala index c6fa872b6dc8e..647940c59fec7 100644 --- a/modules/challenge/src/test/JoinerTest.scala +++ b/modules/challenge/src/test/JoinerTest.scala @@ -6,7 +6,7 @@ import chess.variant.{ FromPosition, Standard } import lila.game.Game import chess.Clock -final class JoinerTest extends munit.FunSuite { +final class JoinerTest extends munit.FunSuite: val timeControl = Challenge.TimeControl.Clock(Clock.Config(Clock.LimitSeconds(300), Clock.IncrementSeconds(0))) @@ -38,4 +38,3 @@ final class JoinerTest extends munit.FunSuite { ) assertEquals(ChallengeJoiner.createGame(challenge, None, None).chess.startedAtPly, Ply(6)) } -} diff --git a/modules/chat/src/main/ChatApi.scala b/modules/chat/src/main/ChatApi.scala index 6d6996ecbcd41..71004e406f7aa 100644 --- a/modules/chat/src/main/ChatApi.scala +++ b/modules/chat/src/main/ChatApi.scala @@ -134,7 +134,7 @@ final class ChatApi( publish(chatId, ChatLine(chatId, line), busChan) def service(chatId: ChatId, text: String, busChan: BusChan.Select, isVolatile: Boolean): Unit = - (if (isVolatile) volatile else system) (chatId, text, busChan).unit + (if isVolatile then volatile else system) (chatId, text, busChan).unit def timeout( chatId: ChatId, @@ -160,12 +160,11 @@ final class ChatApi( reason = reason, scope = ChatTimeout.Scope.Global, text = data.text, - busChan = data.chan match { + busChan = data.chan match case "tournament" => _.Tournament case "swiss" => _.Swiss case "team" => _.Team case _ => _.Study - } ) } @@ -203,7 +202,7 @@ final class ChatApi( line foreach { l => publish(chat.id, ChatLine(chat.id, l), busChan) } - if (isMod(mod) || isRelayMod(mod)) + if isMod(mod) || isRelayMod(mod) then lila.common.Bus.publish( lila.hub.actorApi.mod.ChatTimeout( mod = mod.userId, @@ -213,7 +212,7 @@ final class ChatApi( ), "chatTimeout" ) - if (isNew) + if isNew then lila.common.Bus .publish(lila.hub.actorApi.security.DeletePublicChats(user.id), "deletePublicChats") else logger.info(s"${mod.username} times out ${user.username} in #${c.id} for ${reason.key}") @@ -265,7 +264,7 @@ final class ChatApi( findOption(chatId) dmap (_ | Chat.makeMixed(chatId)) def findIf(chatId: ChatId, cond: Boolean): Fu[MixedChat] = - if (cond) find(chatId) + if cond then find(chatId) else fuccess(Chat.makeMixed(chatId)) def findNonEmpty(chatId: ChatId): Fu[Option[MixedChat]] = @@ -323,7 +322,7 @@ final class ChatApi( out2.take(Line.textMaxSize).some.filter(_.nonEmpty) private def removeSelfMention(in: String, username: UserName) = - if (in.contains('@')) + if in.contains('@') then ("""(?i)@(? Fu[Option[User]]): Fu[Boolean] = - if (enabled) fetch(id) dmap { _ so allowed } + if enabled then fetch(id) dmap { _ so allowed } else fuTrue def enabled = @@ -33,4 +33,4 @@ final class ChatPanic: logger.warn("Chat Panic disabled") until = none - def set(v: Boolean) = if (v) start() else stop() + def set(v: Boolean) = if v then start() else stop() diff --git a/modules/chat/src/main/ChatTimeout.scala b/modules/chat/src/main/ChatTimeout.scala index a6c3a26391844..dc7ecb8ef2486 100644 --- a/modules/chat/src/main/ChatTimeout.scala +++ b/modules/chat/src/main/ChatTimeout.scala @@ -21,7 +21,7 @@ final class ChatTimeout( isActive(chat.id, user.id) flatMap { if _ then fuccess(false) else - if (scope == Scope.Global) global put user.id + if scope == Scope.Global then global put user.id coll.insert .one( $doc( diff --git a/modules/chat/src/main/Line.scala b/modules/chat/src/main/Line.scala index 82312df6916d8..39a26312f24c2 100644 --- a/modules/chat/src/main/Line.scala +++ b/modules/chat/src/main/Line.scala @@ -78,9 +78,9 @@ object Line: case _ => none def userLineToStr(x: UserLine): String = val sep = - if (x.troll) trollChar - else if (x.deleted) deletedChar - else if (x.patron) patronChar + if x.troll then trollChar + else if x.deleted then deletedChar + else if x.patron then patronChar else " " val tit = x.title.so(_.value + titleSep) s"$tit${x.username}$sep${x.text}" diff --git a/modules/clas/src/main/ClasApi.scala b/modules/clas/src/main/ClasApi.scala index 3f1222ee03679..70efc9493f2cd 100644 --- a/modules/clas/src/main/ClasApi.scala +++ b/modules/clas/src/main/ClasApi.scala @@ -115,7 +115,7 @@ final class ClasApi( coll.update .one( $id(c.id), - if (v) $set("archived" -> Clas.Recorded(t.id, nowInstant)) + if v then $set("archived" -> Clas.Recorded(t.id, nowInstant)) else $unset("archived") ) .void @@ -367,7 +367,7 @@ ${clas.desc}""", invite: ClasInvite ): Fu[ClasInvite.Feedback] = val url = s"$baseUrl/class/invitation/${invite._id}" - if (student.kid) fuccess(ClasInvite.Feedback.CantMsgKid(url)) + if student.kid then fuccess(ClasInvite.Feedback.CantMsgKid(url)) else import lila.i18n.I18nKeys.clas.* given play.api.i18n.Lang = student.realLang | lila.i18n.defaultLang diff --git a/modules/clas/src/main/ClasForm.scala b/modules/clas/src/main/ClasForm.scala index b242ee93af4e9..017a1d1bd6c46 100644 --- a/modules/clas/src/main/ClasForm.scala +++ b/modules/clas/src/main/ClasForm.scala @@ -21,12 +21,11 @@ final class ClasForm( "desc" -> cleanText(minLength = 0, maxLength = 2000), "teachers" -> nonEmptyText.verifying( "Invalid teacher list", - str => { + str => val ids = readTeacherIds(str) ids.nonEmpty && ids.sizeIs <= 10 && ids.forall { id => blockingFetchUser(id into UserStr).isDefined } - } ) )(ClasData.apply)(unapply) ) diff --git a/modules/clas/src/main/ClasProgress.scala b/modules/clas/src/main/ClasProgress.scala index ba74b5c820165..2a73dea01355f 100644 --- a/modules/clas/src/main/ClasProgress.scala +++ b/modules/clas/src/main/ClasProgress.scala @@ -35,7 +35,7 @@ case class StudentProgress( rating: (IntRating, IntRating) ): def ratingProgress = (rating._2 - rating._1) into IntRatingDiff - def winRate = if (nb > 0) wins * 100 / nb else 0 + def winRate = if nb > 0 then wins * 100 / nb else 0 def duration = Duration.ofMillis(millis) final class ClasProgressApi( @@ -156,4 +156,4 @@ final class ClasProgressApi( .toMap private[clas] def onFinishGame(game: lila.game.Game): Unit = - if (game.userIds.exists(studentCache.isStudent)) gameRepo.denormalizePerfType(game) + if game.userIds.exists(studentCache.isStudent) then gameRepo.denormalizePerfType(game) diff --git a/modules/clas/src/main/ClasStudentCache.scala b/modules/clas/src/main/ClasStudentCache.scala index eb5b1a117db68..88e0795365cf4 100644 --- a/modules/clas/src/main/ClasStudentCache.scala +++ b/modules/clas/src/main/ClasStudentCache.scala @@ -27,7 +27,7 @@ final class ClasStudentCache(colls: ClasColls)(using scheduler: Scheduler)(using .documentSource() .throttle(300, 1.second) .toMat(Sink.fold[Int, Bdoc](0) { case (counter, doc) => - if (counter % 500 == 0) logger.info(s"ClasStudentCache.rebuild $counter") + if counter % 500 == 0 then logger.info(s"ClasStudentCache.rebuild $counter") doc.string("userId") foreach nextBloom.add counter + 1 })(Keep.right) diff --git a/modules/coach/src/main/CoachProfileForm.scala b/modules/coach/src/main/CoachProfileForm.scala index 1865f467ce87f..f99ac9337aa08 100644 --- a/modules/coach/src/main/CoachProfileForm.scala +++ b/modules/coach/src/main/CoachProfileForm.scala @@ -52,9 +52,9 @@ object CoachProfileForm: listed = Coach.Listed(listed), available = Coach.Available(available), profile = profile, - languages = Json.parse(languages).validate[List[TagifyLang]] match { + languages = Json.parse(languages).validate[List[TagifyLang]] match case JsSuccess(langs, _) => langs.take(10).map(_.code).flatMap(Lang.get).map(_.code).distinct case _ => Nil - }, + , updatedAt = nowInstant ) diff --git a/modules/common/src/main/Bus.scala b/modules/common/src/main/Bus.scala index 8fcf4d0ad2d16..9b83b45863e1c 100644 --- a/modules/common/src/main/Bus.scala +++ b/modules/common/src/main/Bus.scala @@ -79,7 +79,7 @@ final private class EventBus[Event, Channel, Subscriber]( channel, (_: Channel, subs: Set[Subscriber]) => val newSubs = subs - subscriber - if (newSubs.isEmpty) null + if newSubs.isEmpty then null else newSubs ) .unit diff --git a/modules/common/src/main/Chronometer.scala b/modules/common/src/main/Chronometer.scala index b2a3a6cf272dd..55e65c8d6c308 100644 --- a/modules/common/src/main/Chronometer.scala +++ b/modules/common/src/main/Chronometer.scala @@ -12,7 +12,7 @@ object Chronometer: def seconds = (millis / 1000).toInt def logIfSlow(threshold: Int, logger: lila.log.Logger)(msg: A => String) = - if (millis >= threshold) log(logger)(msg) + if millis >= threshold then log(logger)(msg) else this def log(logger: lila.log.Logger)(msg: A => String) = logger.info(s"<${millis}ms> ${msg(result)}") @@ -34,10 +34,10 @@ object Chronometer: println(s"chrono $msg - $showDuration") result def ppIfGt(msg: String, duration: FiniteDuration): A = - if (nanos > duration.toNanos) pp(msg) + if nanos > duration.toNanos then pp(msg) else result - def showDuration: String = if (millis >= 1) s"$millis ms" else s"$micros micros" + def showDuration: String = if millis >= 1 then s"$millis ms" else s"$micros micros" case class LapTry[A](result: Try[A], nanos: Long): def millis = (nanos / 1000000).toInt diff --git a/modules/common/src/main/CuteNameGenerator.scala b/modules/common/src/main/CuteNameGenerator.scala index 8790c35a49f04..a43fd2e941bf9 100644 --- a/modules/common/src/main/CuteNameGenerator.scala +++ b/modules/common/src/main/CuteNameGenerator.scala @@ -8,8 +8,8 @@ object CuteNameGenerator: def make(maxSize: Int = 20, triesLeft: Int = 100): Option[UserName] = val name = makeForSure - if (name.value.sizeIs <= maxSize) name.some - else if (triesLeft <= 0) none + if name.value.sizeIs <= maxSize then name.some + else if triesLeft <= 0 then none else make(maxSize, triesLeft - 1) def makeForSure: UserName = UserName(anyOf(combinations).map(anyOf).mkString) diff --git a/modules/common/src/main/EmailAddress.scala b/modules/common/src/main/EmailAddress.scala index 4fc062a4581dc..3f6f73b0c3f05 100644 --- a/modules/common/src/main/EmailAddress.scala +++ b/modules/common/src/main/EmailAddress.scala @@ -18,7 +18,7 @@ object EmailAddress extends OpaqueString[EmailAddress]: val normalizedName = name .replace(".", "") // remove all dots .takeWhile('+' != _) // skip everything after the first '+' - if (normalizedName.isEmpty) lower else s"$normalizedName@$domain" + if normalizedName.isEmpty then lower else s"$normalizedName@$domain" case _ => lower def domain: Option[Domain] = diff --git a/modules/common/src/main/Form.scala b/modules/common/src/main/Form.scala index f3160051dd57f..78e364bf67f2f 100644 --- a/modules/common/src/main/Form.scala +++ b/modules/common/src/main/Form.scala @@ -6,7 +6,7 @@ import play.api.data.format.Formats.* import play.api.data.format.Formatter import play.api.data.Forms.* import play.api.data.validation.{ Constraint, Constraints } -import play.api.data.{ Field, FormError, Mapping, Form => PlayForm } +import play.api.data.{ Field, FormError, Mapping, Form as PlayForm } import play.api.data.validation as V import scala.util.Try import java.time.LocalDate @@ -109,8 +109,7 @@ object Form: // \u0131\u0307 is ı (\u0131) with an i dot (\u0307) private val regex = "(?iu)l(?:[i\u0456]|\u0131\u0307?)[c\u0441][h\u04bb][e\u0435][s\u0455]".r def apply(verifiedUser: Boolean) = Constraint[String] { (t: String) => - if (regex.find(t) && !verifiedUser) - V.Invalid(V.ValidationError("Must not contain \"lichess\"")) + if regex.find(t) && !verifiedUser then V.Invalid(V.ValidationError("Must not contain \"lichess\"")) else V.Valid } @@ -136,7 +135,7 @@ object Form: .transform[Color](c => Color.fromWhite(c == "white"), _.name) private def pluralize(pattern: String, nb: Int) = - pattern.replace("{s}", if (nb == 1) "" else "s") + pattern.replace("{s}", if nb == 1 then "" else "s") given intBase: Formatter[Int] = intFormat given strBase: Formatter[String] = stringFormat @@ -164,22 +163,24 @@ object Form: object constraint: def minLength[A](from: A => String)(length: Int): Constraint[A] = Constraint[A]("constraint.minLength", length) { o => - if (from(o).lengthIs >= length) V.Valid else V.Invalid(V.ValidationError("error.minLength", length)) + if from(o).lengthIs >= length then V.Valid + else V.Invalid(V.ValidationError("error.minLength", length)) } def maxLength[A](from: A => String)(length: Int): Constraint[A] = Constraint[A]("constraint.maxLength", length) { o => - if (from(o).lengthIs <= length) V.Valid else V.Invalid(V.ValidationError("error.maxLength", length)) + if from(o).lengthIs <= length then V.Valid + else V.Invalid(V.ValidationError("error.maxLength", length)) } object fen: val mapping = trim(of[String]).into[Fen.Epd] def playable(strict: Boolean) = mapping .verifying("Invalid position", fen => Fen.read(fen).exists(_ playable strict)) - .transform[Fen.Epd](if (strict) truncateMoveNumber else identity, identity) + .transform[Fen.Epd](if strict then truncateMoveNumber else identity, identity) val playableStrict = playable(strict = true) def truncateMoveNumber(fen: Fen.Epd) = Fen.readWithMoveNumber(fen).fold(fen) { g => - if (g.fullMoveNumber >= 150) + if g.fullMoveNumber >= 150 then Fen write g.copy(fullMoveNumber = g.fullMoveNumber.map(_ % 100)) // keep the start ply low else fen } @@ -206,10 +207,9 @@ object Form: def bind(key: String, data: Map[String, String]) = base.bind(key, data) map sr.apply def unbind(key: String, value: T) = base.unbind(key, rs(value)) - given Formatter[chess.variant.Variant] = { + given Formatter[chess.variant.Variant] = import chess.variant.Variant formatter.stringFormatter[Variant](_.key.value, str => Variant.orDefault(Variant.LilaKey(str))) - } extension [A](f: Formatter[A]) def transform[B](to: A => B, from: B => A): Formatter[B] = new: diff --git a/modules/common/src/main/Heapsort.scala b/modules/common/src/main/Heapsort.scala index 5426f92199ff9..1f1c9490ee581 100644 --- a/modules/common/src/main/Heapsort.scala +++ b/modules/common/src/main/Heapsort.scala @@ -13,7 +13,7 @@ object Heapsort: private[this] def moveN[T](p: PriorityQueue[T], g: Growable[T], n: Int): Unit = // Only the dequeue and dequeueAll methods will return elements in priority order (while removing elements from the heap). var k = p.length atMost n - while (k > 0) + while k > 0 do g += p.dequeue() k -= 1 diff --git a/modules/common/src/main/LilaCookie.scala b/modules/common/src/main/LilaCookie.scala index 5c2d2d8d99e3d..d74db3bb5e83f 100644 --- a/modules/common/src/main/LilaCookie.scala +++ b/modules/common/src/main/LilaCookie.scala @@ -34,7 +34,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): ) ) ), - if (remember) none else 0.some + if remember then none else 0.some ) def cookie(name: String, value: String, maxAge: Option[Int] = None, httpOnly: Option[Boolean] = None)(using @@ -43,7 +43,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): Cookie( name, value, - if (maxAge has 0) none + if maxAge has 0 then none else maxAge orElse baker.maxAge orElse 86400.some, "/", cookieDomain.some, @@ -57,7 +57,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): DiscardingCookie(name, "/", cookieDomain.some, baker.httpOnly) def ensure(req: RequestHeader)(res: Result): Result = - if (req.session.data.contains(LilaCookie.sessionId)) res + if req.session.data.contains(LilaCookie.sessionId) then res else res withCookies makeSessionId(using req) def ensureAndGet(req: RequestHeader)(res: String => Fu[Result])(using Executor): Fu[Result] = diff --git a/modules/common/src/main/MarkdownRender.scala b/modules/common/src/main/MarkdownRender.scala index f999ced990fb8..df4980b7803ec 100644 --- a/modules/common/src/main/MarkdownRender.scala +++ b/modules/common/src/main/MarkdownRender.scala @@ -49,11 +49,11 @@ final class MarkdownRender( ): private val extensions = java.util.ArrayList[Extension]() - if (table) + if table then extensions.add(TablesExtension.create()) extensions.add(MarkdownRender.tableWrapperExtension) - if (strikeThrough) extensions.add(StrikethroughExtension.create()) - if (autoLink) + if strikeThrough then extensions.add(StrikethroughExtension.create()) + if autoLink then extensions.add(AutolinkExtension.create()) extensions.add(MarkdownRender.WhitelistedImage.create(assetDomain)) extensions.add( @@ -70,10 +70,10 @@ final class MarkdownRender( .set(Parser.FENCED_CODE_BLOCK_PARSER, Boolean box code) // configurable - if (table) options.set(TablesExtension.CLASS_NAME, "slist") - if (!header) options.set(Parser.HEADING_PARSER, Boolean box false) - if (!blockQuote) options.set(Parser.BLOCK_QUOTE_PARSER, Boolean box false) - if (!list) options.set(Parser.LIST_BLOCK_PARSER, Boolean box false) + if table then options.set(TablesExtension.CLASS_NAME, "slist") + if !header then options.set(Parser.HEADING_PARSER, Boolean box false) + if !blockQuote then options.set(Parser.BLOCK_QUOTE_PARSER, Boolean box false) + if !list then options.set(Parser.LIST_BLOCK_PARSER, Boolean box false) private val immutableOptions = options.toImmutable @@ -146,15 +146,16 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .nodeRendererFactory(new NodeRendererFactory { - override def apply(options: DataHolder) = new NodeRenderer: - override def getNodeRenderingHandlers() = - Set(NodeRenderingHandler(classOf[Image], render _)).asJava - }) + .nodeRendererFactory( + new NodeRendererFactory: + override def apply(options: DataHolder) = new NodeRenderer: + override def getNodeRenderingHandlers() = + Set(NodeRenderingHandler(classOf[Image], render _)).asJava + ) private def render(node: Image, context: NodeRendererContext, html: HtmlWriter): Unit = // Based on implementation in CoreNodeRenderer. - if (context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context)) + if context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context) then context.renderChildren(node) else { @@ -185,9 +186,10 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .nodeRendererFactory(new NodeRendererFactory { - override def apply(options: DataHolder) = new PgnEmbedNodeRenderer(expander) - }) + .nodeRendererFactory( + new NodeRendererFactory: + override def apply(options: DataHolder) = new PgnEmbedNodeRenderer(expander) + ) .unit private class PgnEmbedNodeRenderer(expander: PgnSourceExpand) extends NodeRenderer: override def getNodeRenderingHandlers() = @@ -215,7 +217,7 @@ object MarkdownRender: private def renderLinkNode(node: LinkNode, context: NodeRendererContext, html: HtmlWriter) = // Based on implementation in CoreNodeRenderer. - if (context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context)) + if context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context) then context.renderChildren(node) else val link = context.resolveLink(LinkType.LINK, node.getUrl().unescape(), null, null) @@ -237,7 +239,7 @@ object MarkdownRender: html: HtmlWriter, baseLink: ResolvedLink ) = - val link = if (node.getTitle.isNotNull) baseLink.withTitle(node.getTitle().unescape()) else baseLink + val link = if node.getTitle.isNotNull then baseLink.withTitle(node.getTitle().unescape()) else baseLink html.attr("href", link.getUrl) html.attr(link.getNonNullAttributes()) html.srcPos(node.getChars()).withAttr(link).tag("a") @@ -270,14 +272,15 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .attributeProviderFactory(new IndependentAttributeProviderFactory { - override def apply(context: LinkResolverContext): AttributeProvider = lilaLinkAttributeProvider - }) + .attributeProviderFactory( + new IndependentAttributeProviderFactory: + override def apply(context: LinkResolverContext): AttributeProvider = lilaLinkAttributeProvider + ) .unit private val lilaLinkAttributeProvider = new AttributeProvider: override def setAttributes(node: Node, part: AttributablePart, attributes: MutableAttributes) = - if ((node.isInstanceOf[Link] || node.isInstanceOf[AutoLink]) && part == AttributablePart.LINK) + if (node.isInstanceOf[Link] || node.isInstanceOf[AutoLink]) && part == AttributablePart.LINK then attributes.replaceValue("rel", rel).unit attributes.replaceValue("href", RawHtml.removeUrlTrackingParameters(attributes.getValue("href"))).unit diff --git a/modules/common/src/main/Maths.scala b/modules/common/src/main/Maths.scala index ba045fc92084e..0e84c46add628 100644 --- a/modules/common/src/main/Maths.scala +++ b/modules/common/src/main/Maths.scala @@ -55,7 +55,7 @@ object Maths: @scala.annotation.tailrec def boxedNormalDistribution(mean: Int, deviation: Int, factor: Double): Int = val normal = mean + deviation * ThreadLocalRandom.nextGaussian() * factor.atMost(1) - if (normal > mean - deviation && normal < mean + deviation) normal.toInt + if normal > mean - deviation && normal < mean + deviation then normal.toInt else boxedNormalDistribution(mean, deviation, factor) // https://www.scribbr.com/statistics/standard-deviation/ diff --git a/modules/common/src/main/SimpleOpening.scala b/modules/common/src/main/SimpleOpening.scala index 7b13b07668fc9..61edbbb62d6ff 100644 --- a/modules/common/src/main/SimpleOpening.scala +++ b/modules/common/src/main/SimpleOpening.scala @@ -14,7 +14,7 @@ case class SimpleOpening(ref: Opening, name: SimpleOpening.Name, family: LilaOpe import SimpleOpening.* val key = nameToKey(name into OpeningName) into Key def isFamily = ref.variation.isEmpty - def familyKeyOrKey = if (isFamily) Key(family.key.value) else key + def familyKeyOrKey = if isFamily then Key(family.key.value) else key def variation = ref.variation | otherVariations inline def nbMoves = ref.nbMoves inline def lastUci = ref.lastUci @@ -42,7 +42,7 @@ object SimpleOpening: LilaOpeningFamily(ref.family.key into LilaOpeningFamily.Key).fold(acc): fam => val op = SimpleOpening(ref, nameOf(ref), fam) val prev = acc get op.key - if (prev.fold(true)(_.nbMoves > op.nbMoves)) acc.updated(op.key, op) + if prev.fold(true)(_.nbMoves > op.nbMoves) then acc.updated(op.key, op) else acc lazy val openingList = openings.values.toList.sortBy(_.name.value) diff --git a/modules/common/src/main/String.scala b/modules/common/src/main/String.scala index a48695870a50d..206cd33ed7cda 100644 --- a/modules/common/src/main/String.scala +++ b/modules/common/src/main/String.scala @@ -108,7 +108,7 @@ object String: def shorten(text: String, length: Int): String = shorten(text, length, "…") def shorten(text: String, length: Int, sep: String): String = val oneline = onelineR.replaceAllIn(text, " ") - if (oneline.lengthIs > length + sep.length) oneline.take(length) ++ sep + if oneline.lengthIs > length + sep.length then oneline.take(length) ++ sep else oneline def isShouting(text: String) = @@ -122,7 +122,7 @@ object String: case _ => i } > 0 } - def noShouting(str: String): String = if (isShouting(str)) str.toLowerCase else str + def noShouting(str: String): String = if isShouting(str) then str.toLowerCase else str object base64: import java.util.Base64 @@ -145,7 +145,7 @@ object String: ): Frag = raw: val withLinks = RawHtml.addLinks(rawText, expandImg) - if (nl2br) RawHtml.nl2br(withLinks.value) else withLinks + if nl2br then RawHtml.nl2br(withLinks.value) else withLinks def nl2brUnsafe(text: String): Frag = raw: @@ -163,7 +163,7 @@ object String: def markdownLinksOrRichText(text: String)(using config.NetDomain): Frag = val escaped = Html(escapeHtmlRaw(text)) val marked = RawHtml.justMarkdownLinks(escaped) - if (marked == escaped) richText(text) + if marked == escaped then richText(text) else nl2brUnsafe(marked.value) def safeJsonValue(jsValue: JsValue): String = diff --git a/modules/common/src/main/WMMatching.scala b/modules/common/src/main/WMMatching.scala index 44846e334988b..dc485143e6399 100644 --- a/modules/common/src/main/WMMatching.scala +++ b/modules/common/src/main/WMMatching.scala @@ -35,7 +35,7 @@ object WMMatching: // founds minimum-weighted matching among maximum-cardinality matchings private[this] def lowLevel(nvertex: Int, pairScore: (Int, Int) => Option[Int]): List[(Int, Int)] = val (endpoint, weights) = fullGraph(nvertex, pairScore) - if (endpoint.isEmpty) Nil + if endpoint.isEmpty then Nil else val maxweight = weights.max maxWeightMatching(endpoint, weights.mapInPlace { maxweight - _ }, maxcardinality = true) @@ -75,11 +75,11 @@ object WMMatching: private[this] def mateToList(endpoint: Array[Int], mate: Array[Int]): List[(Int, Int)] = // Transform mate such that mate(v) is the vertex to which v is paired. var l: List[(Int, Int)] = Nil - for (v <- Range(mate.length - 2, -1, -1)) + for v <- Range(mate.length - 2, -1, -1) do val k = mate(v) - if (k >= 0) + if k >= 0 then val e = endpoint(k) - if (v < e) l ::= ((v, e)) + if v < e then l ::= ((v, e)) l private[this] def fullGraph( @@ -91,15 +91,14 @@ object WMMatching: e.sizeHint(m) val w = Array.newBuilder[Int] w.sizeHint(m >> 1) - for { + for i <- 0 until (nvertex - 1) j <- (i + 1) until nvertex p <- pairScore(i, j) - } yield { + yield e += i e += j w += p - } (e.result(), w.result()) private class BlossomIdAllocator(n: Int): @@ -108,7 +107,7 @@ object WMMatching: private[this] var freeIds = SortedSet.empty[Int] private[this] var top = n def allocateId(): Int = - val i = if (freeIds.isEmpty) + val i = if freeIds.isEmpty then top += 1 top else @@ -124,7 +123,7 @@ object WMMatching: private class DuelDelta(val tp: Int, var delta: Int): var extra = -1 def update(d: Int, e: Int): Unit = - if (delta > d) + if delta > d then delta = d extra = e private object Impl: @@ -190,7 +189,7 @@ object WMMatching: // If b is a (sub-)blossom, // blossombase(b) is its base VERTEX (i.e. recursive sub-blossom). - private[this] val blossombase = Array.tabulate[Int](2 * nvertex) { i => if (i < nvertex) i else -1 } + private[this] val blossombase = Array.tabulate[Int](2 * nvertex) { i => if i < nvertex then i else -1 } /* If b is a non-trivial (sub-)blossom, @@ -227,7 +226,7 @@ object WMMatching: private[this] val dualvar = // Find the maximum edge weight. val maxweight = weights.max - Array.tabulate[Int](2 * nvertex) { i => if (i < nvertex) maxweight else 0 } + Array.tabulate[Int](2 * nvertex) { i => if i < nvertex then maxweight else 0 } // slack function optimization private[this] val dw = weights.map { _ * 2 } @@ -248,7 +247,7 @@ object WMMatching: // Generate the leaf vertices of a blossom. private[this] def blossomLeaves(b: Int): Iterator[Int] = - if (b < nvertex) Iterator(b) else blossomLeavesG(b) + if b < nvertex then Iterator(b) else blossomLeavesG(b) // Assign label t to the top-level blossom containing vertex w // and record the fact that w was reached through the edge with @@ -263,7 +262,7 @@ object WMMatching: labelend(b) = p bestedge(w) = -1 bestedge(b) = -1 - if (t == 1) + if t == 1 then // b became an S-vertex/blossom; add it(s vertices) to the queue. blossomLeaves(b).foreach(queue ::= _) else @@ -275,23 +274,23 @@ object WMMatching: // Trace back from v and w, placing breadcrumbs as we go. @tailrec private[this] def scan(v: Int, w: Int, path: List[Int]): (Int, List[Int]) = - if (v == -1 && w == -1) (-1, path) // not found + if v == -1 && w == -1 then (-1, path) // not found else // Look for a breadcrumb in v's blossom or put a new breadcrumb. val b = inblossom(v) - if (label(b) == 3) (blossombase(b), path) + if label(b) == 3 then (blossombase(b), path) else label(b) = 3 // Trace one step back. val nv = - if (labelend(b) == -1) -1 + if labelend(b) == -1 then -1 else val t = endpoint(labelend(b)) val c = inblossom(t) // c is a T-blossom; trace one more step back. endpoint(labelend(c)) // Swap v and w so that we alternate between both paths. - if (w != -1) scan(w, nv, b :: path) + if w != -1 then scan(w, nv, b :: path) else scan(nv, w, b :: path) // Trace back from vertices v and w to discover either a new blossom // or an augmenting path. Return the base vertex of the new blossom or -1. @@ -318,7 +317,7 @@ object WMMatching: endps: List[Int] ): (List[Int], List[Int]) = val bv = inblossom(v) - if (bv == bb) (path, endps) + if bv == bb then (path, endps) else // Add bv to the new blossom. blossomparent(bv) = b @@ -331,7 +330,7 @@ object WMMatching: val bb = inblossom(base) // Create blossom. val b = blossomIdAllocator.allocateId() - if (allocatedvertex <= b) allocatedvertex = b + 1 + if allocatedvertex <= b then allocatedvertex = b + 1 blossombase(b) = base blossomparent(b) = -1 blossomparent(bb) = b @@ -348,8 +347,8 @@ object WMMatching: // Set dual variable to zero. dualvar(b) = 0 // Relabel vertices. - for (v <- blossomLeaves(b)) - if (label(inblossom(v)) == 2) + for v <- blossomLeaves(b) do + if label(inblossom(v)) == 2 then // This T-vertex now turns into an S-vertex because it becomes // part of an S-blossom; add it to the queue. queue ::= v @@ -357,42 +356,39 @@ object WMMatching: // Compute blossombestedges(b). val bestedgeto = Array.fill(allocatedvertex)(-1) - for (bv <- blossomchilds(b)) + for bv <- blossomchilds(b) do val nblists = - if (blossombestedges(bv) == null) + if blossombestedges(bv) == null then blossomLeaves(bv).flatMap(neighbend(_).view.map { p => p >> 1 }) else blossombestedges(bv).iterator - for (k <- nblists) + for k <- nblists do val kk = 2 * k - val j = if (inblossom(endpoint(kk + 1)) == b) endpoint(kk) else endpoint(kk + 1) + val j = if inblossom(endpoint(kk + 1)) == b then endpoint(kk) else endpoint(kk + 1) val bj = inblossom(j) - if (bj != b && label(bj) == 1) + if bj != b && label(bj) == 1 then val i = bestedgeto(bj) - if (i == -1 || slack(k) < slack(i)) - bestedgeto(bj) = k + if i == -1 || slack(k) < slack(i) then bestedgeto(bj) = k // Forget about least-slack edges of the subblossom. blossombestedges(bv) = null bestedge(bv) = -1 val a = bestedgeto.filter { _ != -1 } blossombestedges(b) = a // Select bestedge(b). - bestedge(b) = if (a.nonEmpty) a.minBy(slack) else -1 + bestedge(b) = if a.nonEmpty then a.minBy(slack) else -1 // Expand the given top-level blossom. private[this] def expandBlossom(b: Int, endstage: Boolean): Unit = // Convert sub-blossoms into top-level blossoms. - for (s <- blossomchilds(b)) + for s <- blossomchilds(b) do blossomparent(s) = -1 - if (s < nvertex) - inblossom(s) = s - else if (endstage && dualvar(s) == 0) + if s < nvertex then inblossom(s) = s + else if endstage && dualvar(s) == 0 then // Recursively expand this sub-blossom. expandBlossom(s, endstage) - else - blossomLeaves(s).foreach(inblossom(_) = s) + else blossomLeaves(s).foreach(inblossom(_) = s) // If we expand a T-blossom during a stage, its sub-blossoms must be // relabeled. - if (!endstage && label(b) == 2) + if !endstage && label(b) == 2 then // Start at the sub-blossom through which the expanding // blossom obtained its label, and relabel sub-blossoms until // we reach the base. @@ -404,12 +400,12 @@ object WMMatching: val l1 = blossomchilds(b).length - 1 val (jstep, endptrick) = // Start index is odd; go forward and wrap. - if ((j & 1) != 0) ((j: Int) => { if (j == l1) 0 else j + 1 }, 0) + if (j & 1) != 0 then ((j: Int) => if j == l1 then 0 else j + 1, 0) // Start index is even; go backward. - else ((j: Int) => { if (j == 0) l1 else j - 1 }, 1) + else ((j: Int) => if j == 0 then l1 else j - 1, 1) // Move along the blossom until we get to the base. var p = labelend(b) - while (j != 0) + while j != 0 do // Relabel the T-sub-blossom. label(endpoint(p ^ 1)) = 0 label(endpoint(blossomendps(b)(j - endptrick) ^ endptrick ^ 1)) = 0 @@ -431,22 +427,22 @@ object WMMatching: bestedge(bv) = -1 // Continue along the blossom until we get back to entrychild. j = jstep(j) - while (blossomchilds(b)(j) != entrychild) + while blossomchilds(b)(j) != entrychild do // Examine the vertices of the sub-blossom to see whether // it is reachable from a neighbouring S-vertex outside the // expanding blossom. val bv = blossomchilds(b)(j) - if (label(bv) == 1) { + if label(bv) == 1 then { // This sub-blossom just got label S through one of its // neighbours; leave it. } else blossomLeaves(bv) .find(label(_) != 0) - .foreach(v => { + .foreach(v => label(v) = 0 label(endpoint(mate(blossombase(bv)))) = 0 assignLabel(v, 2, labelend(v)) - }) + ) j = jstep(j) // Recycle the blossom number. label(b) = -1 @@ -464,36 +460,32 @@ object WMMatching: // Bubble up through the blossom tree from vertex v to an immediate // isub-blossom of b. var t = v - while (blossomparent(t) != b) - t = blossomparent(t) + while blossomparent(t) != b do t = blossomparent(t) // Recursively deal with the first sub-blossom. - if (t >= nvertex) - augmentBlossom(t, v) + if t >= nvertex then augmentBlossom(t, v) // Decide in which direction we will go round the blossom. val l1 = blossomchilds(b).length - 1 val i = blossomchilds(b).indexOf(t) var j = i val (jstep, endptrick) = - if ((j & 1) != 0) ((j: Int) => { if (j == l1) 0 else j + 1 }, 0) - else ((j: Int) => { if (j == 0) l1 else j - 1 }, 1) + if (j & 1) != 0 then ((j: Int) => if j == l1 then 0 else j + 1, 0) + else ((j: Int) => if j == 0 then l1 else j - 1, 1) // Move along the blossom until we get to the base. - while (j != 0) + while j != 0 do // Step to the next sub-blossom and augment it recursively. j = jstep(j) t = blossomchilds(b)(j) val p = blossomendps(b)(j - endptrick) ^ endptrick - if (t >= nvertex) - augmentBlossom(t, endpoint(p)) + if t >= nvertex then augmentBlossom(t, endpoint(p)) // Step to the next sub-blossom and augment it recursively. j = jstep(j) t = blossomchilds(b)(j) - if (t >= nvertex) - augmentBlossom(t, endpoint(p ^ 1)) + if t >= nvertex then augmentBlossom(t, endpoint(p ^ 1)) // Match the edge connecting those sub-blossoms. mate(endpoint(p)) = p ^ 1 mate(endpoint(p ^ 1)) = p // Rotate the list of sub-blossoms to put the new base at the front. - if (i > 0) + if i > 0 then val n = blossomchilds(b).length val t1 = new Array[Int](n) Impl.rotate(blossomchilds(b), t1, n, i) @@ -513,11 +505,10 @@ object WMMatching: @tailrec def f(s: Int, p: Int): Unit = val bs = inblossom(s) // Augment through the S-blossom from s to base. - if (bs >= nvertex) - augmentBlossom(bs, s) + if bs >= nvertex then augmentBlossom(bs, s) mate(s) = p // Trace one step back. - if (labelend(bs) == -1) { + if labelend(bs) == -1 then { // Reached single vertex; stop. } else val t = endpoint(labelend(bs)) @@ -526,8 +517,7 @@ object WMMatching: val ns = endpoint(labelend(bt)) val j = endpoint(labelend(bt) ^ 1) // Augment through the T-blossom from j to base. - if (bt >= nvertex) - augmentBlossom(bt, j) + if bt >= nvertex then augmentBlossom(bt, j) // Update mate(j) mate(j) = labelend(bt) // Keep the opposite endpoint; @@ -538,7 +528,7 @@ object WMMatching: f(endpoint(kk + 1), kk) @tailrec private[this] def substage(): Boolean = - if (queue.isEmpty) false + if queue.isEmpty then false else // Take an S vertex from the queue. val v = queue.head @@ -547,27 +537,26 @@ object WMMatching: val k = p >> 1 val w = endpoint(p) // w is a neighbour to v - if (inblossom(v) == inblossom(w)) + if inblossom(v) == inblossom(w) then // this edge is internal to a blossom; ignore it false else var kslack = 0 - if (!allowedge(k)) + if !allowedge(k) then kslack = slack(k) - if (kslack <= 0) - allowedge(k) = true - if (allowedge(k)) - if (label(inblossom(w)) == 0) + if kslack <= 0 then allowedge(k) = true + if allowedge(k) then + if label(inblossom(w)) == 0 then // (C1) w is a free vertex; // label w with T and label its mate with S (R12). assignLabel(w, 2, p ^ 1) false - else if (label(inblossom(w)) == 1) + else if label(inblossom(w)) == 1 then // (C2) w is an S-vertex (not in the same blossom); // follow back-links to discover either an // augmenting path or a new blossom. val base = scanBlossom(v, w) - if (base >= 0) + if base >= 0 then // Found a new blossom; add it to the blossom // bookkeeping and turn it into an S-blossom. addBlossom(base, k) @@ -577,7 +566,7 @@ object WMMatching: // matching and end this stage. augmentMatching(k) true - else if (label(w) == 0) + else if label(w) == 0 then // w is inside a T-blossom, but w itself has not // yet been reached from outside the blossom; // mark it as reached (we need this to relabel @@ -586,25 +575,21 @@ object WMMatching: labelend(w) = p ^ 1 false else false - else if (label(inblossom(w)) == 1) + else if label(inblossom(w)) == 1 then // keep track of the least-slack non-allowable edge to // a different S-blossom. val b = inblossom(v) - if (bestedge(b) == -1 || kslack < slack(bestedge(b))) - bestedge(b) = k + if bestedge(b) == -1 || kslack < slack(bestedge(b)) then bestedge(b) = k false - else if (label(w) == 0) + else if label(w) == 0 then // w is a free vertex (or an unreached vertex inside // a T-blossom) but we can not reach it yet; // keep track of the least-slack edge that reaches w. - if (bestedge(w) == -1 || kslack < slack(bestedge(w))) - bestedge(w) = k + if bestedge(w) == -1 || kslack < slack(bestedge(w)) then bestedge(w) = k false else false - if (neighbend(v).exists(go)) - true - else - substage() + if neighbend(v).exists(go) then true + else substage() private[this] val vertices = 0 until nvertex private[this] def updateDual(): Boolean = // There is no augmenting path under these constraints; @@ -615,47 +600,41 @@ object WMMatching: val dt0 = new DuelDelta(0, Int.MaxValue) // Compute delta0: the minimum value of any vertex dual. - if (!maxcardinality) - dt0.update(dualvar.view.slice(0, nvertex).min, -1) + if !maxcardinality then dt0.update(dualvar.view.slice(0, nvertex).min, -1) // Compute delta1: the minimum slack on any edge between // an S-vertex and a free vertex. val dt1 = new DuelDelta(1, dt0.delta) - for { + for v <- vertices if label(inblossom(v)) == 0 - } yield { + yield val be = bestedge(v) - if (be != -1) - dt1.update(slack(be), be) - } + if be != -1 then dt1.update(slack(be), be) val dt2 = new DuelDelta(2, dt1.delta) // Compute delta2: half the minimum slack on any edge between // a pair of S-blossoms. - for { + for b <- 0 until allocatedvertex if blossomparent(b) == -1 && label(b) == 1 - } yield { + yield val be = bestedge(b) - if (be != -1) - dt2.update(slack(be) >> 1, be) - } + if be != -1 then dt2.update(slack(be) >> 1, be) val dt3 = new DuelDelta(3, dt2.delta) // Compute delta3: minimum z variable of any T-blossom. - for (b <- nvertex until allocatedvertex) - if (blossombase(b) >= 0 && blossomparent(b) == -1 && label(b) == 2) - dt3.update(dualvar(b), b) + for b <- nvertex until allocatedvertex do + if blossombase(b) >= 0 && blossomparent(b) == -1 && label(b) == 2 then dt3.update(dualvar(b), b) - if (dt3.delta == Int.MaxValue) + if dt3.delta == Int.MaxValue then // No further improvement possible; max-cardinality optimum reached. false else val dt = List(dt0, dt1, dt2, dt3).find(_.delta == dt3.delta).head // Update dual variables according to delta. - for (v <- vertices) + for v <- vertices do label(inblossom(v)) match case 0 => () case 1 => @@ -665,8 +644,8 @@ object WMMatching: // T-vertex: 2*u = 2*u + 2*delta dualvar(v) += dt.delta - for (b <- nvertex until allocatedvertex) - if (blossombase(b) >= 0 && blossomparent(b) == -1) + for b <- nvertex until allocatedvertex do + if blossombase(b) >= 0 && blossomparent(b) == -1 then label(b) match case 0 => () case 1 => dualvar(b) += dt.delta @@ -680,7 +659,7 @@ object WMMatching: allowedge(dt.extra) = true val kk = 2 * dt.extra val ei = endpoint(kk) - queue ::= (if (label(inblossom(ei)) == 0) endpoint(kk + 1) else ei) + queue ::= (if label(inblossom(ei)) == 0 then endpoint(kk + 1) else ei) true case 2 => // Use the least-slack edge to continue the search. @@ -692,8 +671,8 @@ object WMMatching: true @tailrec private[this] def stage(): Boolean = - if (substage()) true - else if (!updateDual()) false + if substage() then true + else if !updateDual() then false else stage() // Main loop: continue until no further improvement is possible. @@ -717,10 +696,7 @@ object WMMatching: queue = Nil // Label single blossoms/vertices with S and put them in the queue. - for (v <- vertices) - if (mate(v) == -1 && label(inblossom(v)) == 0) - assignLabel(v, 1, -1) - if (stage() && iterations > 1) - mainLoop(iterations - 1) + for v <- vertices do if mate(v) == -1 && label(inblossom(v)) == 0 then assignLabel(v, 1, -1) + if stage() && iterations > 1 then mainLoop(iterations - 1) mainLoop(nvertex) def result: Array[Int] = mate diff --git a/modules/common/src/main/base/LilaJsonExtensions.scala b/modules/common/src/main/base/LilaJsonExtensions.scala index 22c7ac1c56d8a..2167cbb7ca03b 100644 --- a/modules/common/src/main/base/LilaJsonExtensions.scala +++ b/modules/common/src/main/base/LilaJsonExtensions.scala @@ -45,13 +45,13 @@ trait JsonExtensions: } def add(pair: (String, Boolean)): JsObject = - if (pair._2) js + (pair._1 -> JsBoolean(true)) + if pair._2 then js + (pair._1 -> JsBoolean(true)) else js def add[A](pair: (String, A))(using sr: SameRuntime[A, Boolean]): JsObject = add(pair._1, sr(pair._2)) def add(key: String, value: Boolean): JsObject = - if (value) js + (key -> JsBoolean(true)) + if value then js + (key -> JsBoolean(true)) else js def add[A](key: String, value: A)(using sr: SameRuntime[A, Boolean]): JsObject = add(key, sr(value)) diff --git a/modules/common/src/main/base/LilaLibraryExtensions.scala b/modules/common/src/main/base/LilaLibraryExtensions.scala index c2833b2fa894a..b40004d5c7f54 100644 --- a/modules/common/src/main/base/LilaLibraryExtensions.scala +++ b/modules/common/src/main/base/LilaLibraryExtensions.scala @@ -25,8 +25,8 @@ trait LilaLibraryExtensions extends LilaTypes: def atMost(topValue: Long): Long = min(self, topValue) def squeeze(bottom: Long, top: Long): Long = max(min(self, top), bottom) def toSaturatedInt: Int = - if (self.toInt == self) self.toInt - else if (self > 0) Integer.MAX_VALUE + if self.toInt == self then self.toInt + else if self > 0 then Integer.MAX_VALUE else Integer.MIN_VALUE extension (self: Int) @@ -67,13 +67,13 @@ trait LilaLibraryExtensions extends LilaTypes: extension (s: String) def replaceIf(t: Char, r: Char): String = - if (s.indexOf(t.toInt) >= 0) s.replace(t, r) else s + if s.indexOf(t.toInt) >= 0 then s.replace(t, r) else s def replaceIf(t: Char, r: CharSequence): String = - if (s.indexOf(t.toInt) >= 0) s.replace(String.valueOf(t), r) else s + if s.indexOf(t.toInt) >= 0 then s.replace(String.valueOf(t), r) else s def replaceIf(t: CharSequence, r: CharSequence): String = - if (s.contains(t)) s.replace(t, r) else s + if s.contains(t) then s.replace(t, r) else s def replaceAllIn(regex: Regex, replacement: String) = regex.replaceAllIn(s, replacement) @@ -107,7 +107,7 @@ trait LilaLibraryExtensions extends LilaTypes: extension (d: FiniteDuration) def toCentis = chess.Centis(d) - def abs = if (d.length < 0) -d else d + def abs = if d.length < 0 then -d else d extension [E, A](v: Validated[E, A]) def toFuture: Fu[A] = v.fold(err => fufail(err.toString), fuccess) @@ -302,15 +302,15 @@ trait LilaLibraryExtensions extends LilaTypes: extension (fua: Fu[Boolean]) def >>&(fub: => Fu[Boolean]): Fu[Boolean] = - fua.flatMap { if (_) fub else fuFalse }(EC.parasitic) + fua.flatMap { if _ then fub else fuFalse }(EC.parasitic) def >>|(fub: => Fu[Boolean]): Fu[Boolean] = - fua.flatMap { if (_) fuTrue else fub }(EC.parasitic) + fua.flatMap { if _ then fuTrue else fub }(EC.parasitic) def flatMapz[B](fub: => Fu[B])(using zero: Zero[B]): Fu[B] = - fua.flatMap { if (_) fub else fuccess(zero.zero) }(EC.parasitic) + fua.flatMap { if _ then fub else fuccess(zero.zero) }(EC.parasitic) def mapz[B](fb: => B)(using zero: Zero[B]): Fu[B] = - fua.map { if (_) fb else zero.zero }(EC.parasitic) + fua.map { if _ then fb else zero.zero }(EC.parasitic) inline def unary_! = fua.map { !_ }(EC.parasitic) diff --git a/modules/common/src/main/base/RawHtml.scala b/modules/common/src/main/base/RawHtml.scala index 9494eb6d948c1..7cd2bbd11bcbb 100644 --- a/modules/common/src/main/base/RawHtml.scala +++ b/modules/common/src/main/base/RawHtml.scala @@ -14,12 +14,11 @@ object RawHtml: def nl2br(s: String): Html = val sb = jStringBuilder(s.length) var counter = 0 - for (char <- s) - if (char == '\n') + for char <- s do + if char == '\n' then counter += 1 - if (counter < 3) - sb.append("
") - else if (char != '\r') + if counter < 3 then sb.append("
") + else if char != '\r' then counter = 0 sb.append(char) Html(sb.toString) @@ -44,16 +43,16 @@ object RawHtml: def expandAtUser(text: String)(using netDomain: config.NetDomain): List[String] = val m = atUsernamePat.matcher(text) - if (m.find) + if m.find then var idx = 0 val buf = List.newBuilder[String] while - if (idx < m.start) buf += text.substring(idx, m.start) + if idx < m.start then buf += text.substring(idx, m.start) buf += s"${netDomain}/@/${m.group(1)}" idx = m.end m.find do () - if (idx < text.length) buf += text.substring(idx) + if idx < text.length then buf += text.substring(idx) buf.result() else List(text) @@ -69,7 +68,7 @@ object RawHtml: expandAtUser(text).map { expanded => val m = urlPattern.matcher(expanded) - if (!m.find) escapeHtmlRaw(expanded) // preserve fast case! + if !m.find then escapeHtmlRaw(expanded) // preserve fast case! else val sb = new jStringBuilder(expanded.length + 200) val sArr = expanded.toCharArray @@ -84,43 +83,41 @@ object RawHtml: val end = val e = m.end - if (isLetterOrDigit(sArr(e - 1))) e + if isLetterOrDigit(sArr(e - 1)) then e else adjustUrlEnd(sArr, Math.max(pathS, domainS), e) val domain = expanded.substring( domainS, - pathS match { + pathS match case -1 => end case _ => pathS - } ) val isTldInternal = netDomain.value == domain val csb = new jStringBuilder() - if (!isTldInternal) csb.append(domain) - if (pathS >= 0) - if (sArr(pathS) != '/') csb.append('/') + if !isTldInternal then csb.append(domain) + if pathS >= 0 then + if sArr(pathS) != '/' then csb.append('/') csb.append(sArr, pathS, end - pathS) val allButScheme = escapeHtmlRaw(removeUrlTrackingParameters(csb.toString)) lazy val isHttp = domainS - start == 7 - lazy val url = (if (isHttp) "http://" else "https://") + allButScheme - lazy val text = if (isHttp) url else allButScheme + lazy val url = (if isHttp then "http://" else "https://") + allButScheme + lazy val text = if isHttp then url else allButScheme sb append { - if (isTldInternal) + if isTldInternal then linkRender flatMap { _(allButScheme, text).map(_.render) } getOrElse s"""${allButScheme match { + }">${allButScheme match case USER_LINK(user) => "@" + user case _ => s"${netDomain}$allButScheme" - }}""" + }""" else { - if ((end < sArr.length && sArr(end) == '"') || !expandImg) None + if (end < sArr.length && sArr(end) == '"') || !expandImg then None else imgUrl(url) } getOrElse { s"""$text""" @@ -139,34 +136,30 @@ object RawHtml: private[this] def adjustUrlEnd(sArr: Array[Char], start: Int, end: Int): Int = var last = end - 1 - while ( - (sArr(last): @switch) match { + while (sArr(last): @switch) match case '.' | ',' | '?' | '!' | ':' | ';' | '–' | '—' | '@' | '\'' | '(' => true case _ => false - } - ) { last -= 1 } + do last -= 1 - if (sArr(last) == ')') + if sArr(last) == ')' then @tailrec def pCnter(idx: Int, acc: Int): Int = - if (idx >= last) acc + if idx >= last then acc else pCnter( idx + 1, - acc + (sArr(idx) match { + acc + (sArr(idx) match case '(' => 1 case ')' => -1 case _ => 0 - }) + ) ) var parenCnt = pCnter(start, -1) - while ( - (sArr(last): @switch) match { + while (sArr(last): @switch) match case '.' | ',' | '?' | '!' | ':' | ';' | '–' | '—' | '@' | '\'' => true case '(' => parenCnt -= 1; true case ')' => parenCnt += 1; parenCnt <= 0 case _ => false - } - ) { last -= 1 } + do last -= 1 last + 1 private[this] val imgurRegex = """https?://(?:i\.)?imgur\.com/(\w++)(?:\.jpe?g|\.png|\.gif)?""".r @@ -186,11 +179,10 @@ object RawHtml: def justMarkdownLinks(escapedHtml: Html): Html = Html { markdownLinkRegex.replaceAllIn( escapedHtml.value, - m => { + m => val content = Matcher.quoteReplacement(m group 1) val href = removeUrlTrackingParameters(m group 2) s"""$content""" - } ) } diff --git a/modules/common/src/main/config.scala b/modules/common/src/main/config.scala index 0551917e8b342..1b5bccb35aece 100644 --- a/modules/common/src/main/config.scala +++ b/modules/common/src/main/config.scala @@ -74,7 +74,7 @@ object config: } given [A](using loader: ConfigLoader[A]): ConfigLoader[Option[A]] = - ConfigLoader[Option[A]](c => k => if (c.hasPath(k)) Some(loader.load(c, k)) else None) + ConfigLoader[Option[A]](c => k => if c.hasPath(k) then Some(loader.load(c, k)) else None) def strLoader[A](f: String => A): ConfigLoader[A] = ConfigLoader.stringLoader map f def intLoader[A](f: Int => A): ConfigLoader[A] = ConfigLoader.intLoader map f diff --git a/modules/common/src/main/model.scala b/modules/common/src/main/model.scala index bd1bc5408f991..8b8b1000907ef 100644 --- a/modules/common/src/main/model.scala +++ b/modules/common/src/main/model.scala @@ -16,7 +16,7 @@ object ApiVersion extends OpaqueInt[ApiVersion]: opaque type AssetVersion = String object AssetVersion extends OpaqueString[AssetVersion]: var current = random - def change() = { current = random } + def change() = current = random private def random = AssetVersion(SecureRandom nextString 6) opaque type Bearer = String @@ -37,7 +37,7 @@ case class IpV6Address(value: String) extends IpAddress: object IpAddress: private def parse(str: String): Try[IpAddress] = Try { - if (str.contains(".")) IpV4Address(parseIPv4Address(str).toString) + if str.contains(".") then IpV4Address(parseIPv4Address(str).toString) else IpV6Address(parseIPv6Address(str).toString) } def from(str: String): Option[IpAddress] = parse(str).toOption diff --git a/modules/common/src/main/mon.scala b/modules/common/src/main/mon.scala index 20c5a5662b661..55e361056e503 100644 --- a/modules/common/src/main/mon.scala +++ b/modules/common/src/main/mon.scala @@ -43,7 +43,7 @@ object mon: gauge("caffeine.request").withTags(tags("name" -> name, "hit" -> true)).update(stats.hitCount.toDouble) gauge("caffeine.request").withTags(tags("name" -> name, "hit" -> false)).update(stats.missCount.toDouble) histogram("caffeine.hit.rate").withTag("name", name).record((stats.hitRate * 100000).toLong) - if (stats.totalLoadTime > 0) + if stats.totalLoadTime > 0 then gauge("caffeine.load.count") .withTags(tags("name" -> name, "success" -> "success")) .update(stats.loadSuccessCount.toDouble) @@ -68,7 +68,7 @@ object mon: object evalCache: private val r = counter("evalCache.request") def request(ply: Int, isHit: Boolean) = - r.withTags(tags("ply" -> (if (ply < 15) ply.toString else "15+"), "hit" -> isHit)) + r.withTags(tags("ply" -> (if ply < 15 then ply.toString else "15+"), "hit" -> isHit)) object upgrade: val count = counter("evalCache.upgrade.count").withoutTags() val members = gauge("evalCache.upgrade.members").withoutTags() @@ -242,7 +242,7 @@ object mon: def segment(seg: String) = timer("mod.comm.segmentLat").withTag("segment", seg) def zoneSegment(name: String) = future("mod.zone.segment", name) object relay: - private def by(official: Boolean) = if (official) "official" else "user" + private def by(official: Boolean) = if official then "official" else "user" private def relay(official: Boolean, slug: String) = tags("by" -> by(official), "slug" -> slug) def ongoing(official: Boolean) = gauge("relay.ongoing").withTag("by", by(official)) @@ -255,10 +255,9 @@ object mon: def chats(username: String) = counter("bot.chats").withTag("name", username) def gameStream(event: String) = counter("bot.gameStream").withTag("event", event) object cheat: - def selfReport(wildName: String, auth: Boolean) = { + def selfReport(wildName: String, auth: Boolean) = val name = if wildName startsWith "soc: " then "soc" else wildName.takeWhile(' ' !=) counter("cheat.selfReport").withTags(tags("name" -> name, "auth" -> auth)) - } val holdAlert = counter("cheat.holdAlert").withoutTags() def autoAnalysis(reason: String) = counter("cheat.autoAnalysis").withTag("reason", reason) val autoMark = counter("cheat.autoMark.count").withoutTags() @@ -476,7 +475,7 @@ object mon: def score(auth: Boolean) = histogram("storm.run.score").withTag("auth", auth) def sign(cause: String) = counter("storm.run.sign").withTag("cause", cause) object racer: - private def tpe(lobby: Boolean) = if (lobby) "lobby" else "friend" + private def tpe(lobby: Boolean) = if lobby then "lobby" else "friend" def race(lobby: Boolean) = counter("racer.lobby.race").withTag("tpe", tpe(lobby)) def players(lobby: Boolean) = histogram("racer.lobby.players").withTag("tpe", tpe(lobby)) @@ -663,8 +662,8 @@ object mon: timer(name).withTags: tags("success" -> successTag(success), "segment" -> segment) - private def successTag(success: Boolean) = if (success) "success" else "failure" - private def hitTag(hit: Boolean) = if (hit) "hit" else "miss" + private def successTag(success: Boolean) = if success then "success" else "failure" + private def hitTag(hit: Boolean) = if hit then "hit" else "miss" private def apiTag(api: Option[ApiVersion]) = api.fold("-")(_.toString) diff --git a/modules/common/src/main/paginator/Paginator.scala b/modules/common/src/main/paginator/Paginator.scala index 9a110256ceb38..ac15fd10091cb 100644 --- a/modules/common/src/main/paginator/Paginator.scala +++ b/modules/common/src/main/paginator/Paginator.scala @@ -19,7 +19,7 @@ final class Paginator[A] private[paginator] ( (currentPage < nbPages && currentPageResults.nonEmpty) option (currentPage + 1) def nbPages: Int = - if (maxPerPage.value > 0) (nbResults + maxPerPage.value - 1) / maxPerPage.value + if maxPerPage.value > 0 then (nbResults + maxPerPage.value - 1) / maxPerPage.value else 0 def hasToPaginate: Boolean = nbResults > maxPerPage.value @@ -85,13 +85,13 @@ object Paginator: currentPage: Int = 1, maxPerPage: MaxPerPage = MaxPerPage(10) )(using Executor): Validated[String, Fu[Paginator[A]]] = - if (currentPage < 1) Validated.invalid("Current page must be greater than zero") - else if (maxPerPage.value <= 0) Validated.invalid("Max per page must be greater than zero") + if currentPage < 1 then Validated.invalid("Current page must be greater than zero") + else if maxPerPage.value <= 0 then Validated.invalid("Max per page must be greater than zero") else - Validated.valid(for { + Validated.valid(for nbResults <- adapter.nbResults safePage = currentPage.squeeze(1, Math.ceil(nbResults.toDouble / maxPerPage.value).toInt) // would rather let upstream code know the value they passed in was bad. // unfortunately can't do that without completing nbResults, so ig it's on them to check after results <- adapter.slice((safePage - 1) * maxPerPage.value, maxPerPage.value) - } yield new Paginator(safePage, maxPerPage, results, nbResults)) + yield new Paginator(safePage, maxPerPage, results, nbResults)) diff --git a/modules/common/src/test/AutoConfigTest.scala b/modules/common/src/test/AutoConfigTest.scala index 9e66acc27457d..11f9a82a1c4b0 100644 --- a/modules/common/src/test/AutoConfigTest.scala +++ b/modules/common/src/test/AutoConfigTest.scala @@ -4,7 +4,7 @@ import scala.concurrent.duration.* import com.typesafe.config.* import play.api.{ ConfigLoader, Configuration } -class AutoConfigTest extends munit.FunSuite { +class AutoConfigTest extends munit.FunSuite: private def parse(c: String) = Configuration(ConfigFactory.parseString(c.stripMargin)) @@ -105,4 +105,3 @@ class AutoConfigTest extends munit.FunSuite { assertEquals(config.get[Bar]("bar"), Bar("hello", "goodbye")(4.2)) } -} diff --git a/modules/common/src/test/FormTest.scala b/modules/common/src/test/FormTest.scala index 533c795946906..1837ecfd0bee3 100644 --- a/modules/common/src/test/FormTest.scala +++ b/modules/common/src/test/FormTest.scala @@ -1,14 +1,14 @@ package lila.common -import play.api.data._ -import play.api.data.format._ -import play.api.data.format.Formats._ -import play.api.data.Forms._ -import play.api.data.validation._ +import play.api.data.* +import play.api.data.format.* +import play.api.data.format.Formats.* +import play.api.data.Forms.* +import play.api.data.validation.* -import lila.common.Form._ +import lila.common.Form.* -class FormTest extends munit.FunSuite { +class FormTest extends munit.FunSuite: val date = java.time.LocalDateTime.of(2023, 4, 12, 11, 1, 15, 337_000_000) test("format iso datetime") { @@ -157,5 +157,3 @@ class FormTest extends munit.FunSuite { assertEquals(single("t" -> cleanTextWithSymbols).bind(Map("t" -> half.toString)), Right(half.toString)) assertEquals(single("t" -> cleanText).bind(Map("t" -> half.toString)), Right(half.toString)) } - -} diff --git a/modules/common/src/test/HeapsortTest.scala b/modules/common/src/test/HeapsortTest.scala index 08c0ee2024446..d966eb7494d6d 100644 --- a/modules/common/src/test/HeapsortTest.scala +++ b/modules/common/src/test/HeapsortTest.scala @@ -1,6 +1,6 @@ package lila.common -class HeapsortTest extends munit.FunSuite { +class HeapsortTest extends munit.FunSuite: import lila.common.Heapsort.{ topN, botN } test("empty collection") { assertEquals(List.empty[Int].topN(10), List.empty[Int]) @@ -18,4 +18,3 @@ class HeapsortTest extends munit.FunSuite { assertEquals(Heapsort.topN(Vector(5, 3, 1, 4, 2), 2)(using Ordering.Int), Vector(5, 4)) assertEquals(Heapsort.topN(Vector(5, 3, 1, 4, 2), 10)(using Ordering.Int), Vector(5, 4, 3, 2, 1)) } -} diff --git a/modules/common/src/test/IpAddressTest.scala b/modules/common/src/test/IpAddressTest.scala index ef3702d5b325d..055e443ddfb47 100644 --- a/modules/common/src/test/IpAddressTest.scala +++ b/modules/common/src/test/IpAddressTest.scala @@ -1,6 +1,6 @@ package lila.common -class IpAddressTest extends munit.FunSuite { +class IpAddressTest extends munit.FunSuite: test("iso ipv4") { assertEquals(IpAddress.unchecked("0.0.0.0").toString, "0.0.0.0") @@ -30,5 +30,3 @@ class IpAddressTest extends munit.FunSuite { test("equality mixed") { assertNotEquals(IpAddress.unchecked("0.0.0.0"), IpAddress.unchecked("::")) } - -} diff --git a/modules/common/src/test/LameNameTest.scala b/modules/common/src/test/LameNameTest.scala index b4de67b6c7d02..fd859d31ff675 100644 --- a/modules/common/src/test/LameNameTest.scala +++ b/modules/common/src/test/LameNameTest.scala @@ -1,6 +1,6 @@ package lila.common -class LameNameTest extends munit.FunSuite { +class LameNameTest extends munit.FunSuite: def isLame(str: String) = LameName.username(UserName(str)) @@ -51,4 +51,3 @@ class LameNameTest extends munit.FunSuite { assertEquals(isLame("BrianMatthewsnm"), false) assertEquals(isLame("TheGMBRianMatthews"), false) } -} diff --git a/modules/common/src/test/MarkdownTest.scala b/modules/common/src/test/MarkdownTest.scala index f8f59f6149795..473473286623c 100644 --- a/modules/common/src/test/MarkdownTest.scala +++ b/modules/common/src/test/MarkdownTest.scala @@ -3,7 +3,7 @@ package lila.common import chess.format.pgn.PgnStr import lila.common.config.AssetDomain -class MarkdownTest extends munit.FunSuite { +class MarkdownTest extends munit.FunSuite: val render: Markdown => Html = new MarkdownRender(assetDomain = AssetDomain("lichess1.org").some)("test") _ @@ -87,4 +87,3 @@ class MarkdownTest extends munit.FunSuite { """ ) } -} diff --git a/modules/common/src/test/MathsTest.scala b/modules/common/src/test/MathsTest.scala index 414f930732c0f..413c38dd34ad0 100644 --- a/modules/common/src/test/MathsTest.scala +++ b/modules/common/src/test/MathsTest.scala @@ -1,6 +1,6 @@ package lila.common -class MathsTest extends munit.FunSuite { +class MathsTest extends munit.FunSuite: import lila.common.Maths.* @@ -15,4 +15,3 @@ class MathsTest extends munit.FunSuite { // ~standardDeviation(List(46, 69, 32, 60, 52, 41)) must beCloseTo(13.31, 0.01) // sample assert(isCloseTo(~standardDeviation(List(46, 69, 32, 60, 52, 41)), 12.15, 0.01)) // population } -} diff --git a/modules/common/src/test/RawHtmlTest.scala b/modules/common/src/test/RawHtmlTest.scala index 15db4c14d51dd..a925040d28638 100644 --- a/modules/common/src/test/RawHtmlTest.scala +++ b/modules/common/src/test/RawHtmlTest.scala @@ -1,21 +1,20 @@ package lila.base import lila.common.{ Html, config } -import RawHtml._ +import RawHtml.* -class RawHtmlTest extends munit.FunSuite { +class RawHtmlTest extends munit.FunSuite: given config.NetDomain = config.NetDomain("lichess.org") given munit.Compare[Html, String] with def isEqual(obtained: Html, expected: String): Boolean = obtained.value == expected val htmlTags = "<[^>]++>".r - def copyLinkConsistency(text: String) = { + def copyLinkConsistency(text: String) = // Plain text of linkified text >> linkify to the same result. val firstHtml = addLinks(text) val copyText = htmlTags.replaceAllIn(firstHtml.value, "") assertEquals(firstHtml, addLinks(copyText)) - } test("http external") { val url = "http://zombo.com" @@ -270,4 +269,3 @@ class RawHtmlTest extends munit.FunSuite { "abc

def

abc

def" ) } -} diff --git a/modules/common/src/test/StringTest.scala b/modules/common/src/test/StringTest.scala index ed3fe85eb22e6..c1a87ee56b4fa 100644 --- a/modules/common/src/test/StringTest.scala +++ b/modules/common/src/test/StringTest.scala @@ -1,8 +1,8 @@ package lila.common -import scalatags.Text.all._ +import scalatags.Text.all.* -class StringTest extends munit.FunSuite { +class StringTest extends munit.FunSuite: given config.NetDomain = config.NetDomain("lichess.org") @@ -122,5 +122,3 @@ class StringTest extends munit.FunSuite { assertEquals(String.noShouting("HELLO SIR"), "hello sir") assertEquals(String.noShouting("1. Nf3 O-O-O#"), "1. Nf3 O-O-O#") } - -} diff --git a/modules/common/src/test/WMMatchingTest.scala b/modules/common/src/test/WMMatchingTest.scala index 77e72dc2e3cef..8983aca4509f0 100644 --- a/modules/common/src/test/WMMatchingTest.scala +++ b/modules/common/src/test/WMMatchingTest.scala @@ -1,44 +1,39 @@ package lila.common import scala.util.{ Failure, Success } -class WMMatchingTest extends munit.FunSuite { +class WMMatchingTest extends munit.FunSuite: - def toMate(n: Int, l: List[(Int, Int)]): Array[Int] = { + def toMate(n: Int, l: List[(Int, Int)]): Array[Int] = val a = Array.fill(n)(-1) - l.foreach { case (i, j) => { a(i) = j; a(j) = i; } } - if (a.count(_ >= 0) != 2 * l.length) null else a - } - def check0(a: Array[(Int, Int, Int)], maxcardinality: Boolean, expectedMate: Seq[Int]) = { + l.foreach { case (i, j) => a(i) = j; a(j) = i; } + if a.count(_ >= 0) != 2 * l.length then null else a + def check0(a: Array[(Int, Int, Int)], maxcardinality: Boolean, expectedMate: Seq[Int]) = val n = a.view.map(p => p._1.max(p._2)).max + 1 val e = Array.newBuilder[Int] val w = Array.newBuilder[Int] - for (p <- a) { + for p <- a do e += p._1 e += p._2 w += p._3 - } val l = toMate(n, WMMatching.maxWeightMatching(e.result(), w.result(), maxcardinality)) - assert(if (l eq null) false else expectedMate.sameElements(l)) - } + assert(if l eq null then false else expectedMate.sameElements(l)) // check(Array((0,1,1)), false, List (1, 0)) - def check(n: Int, a: Array[Int], res: (Int, Int)) = { + def check(n: Int, a: Array[Int], res: (Int, Int)) = val v = Array.range(0, n) def f(x: Int) = (x * (x + 1)) / 2 def off(i: Int) = f(n - 1) - f(n - 1 - i) - def pairScore(i: Int, j: Int): Option[Int] = { - if (i > j) pairScore(j, i) + def pairScore(i: Int, j: Int): Option[Int] = + if i > j then pairScore(j, i) else { val o = off(i) + (j - (i + 1)) - if (a(o) < 0) None else Some(a(o)) + if a(o) < 0 then None else Some(a(o)) } - } def score(l: List[(Int, Int)]): (Int, Int) = (l.length, l.map(t => pairScore(t._1, t._2).head).sum) def checkScore(ans: (Int, Int)): Boolean = res == ans assert(WMMatching(v, pairScore) match case Success(l) => checkScore(score(l)) case Failure(_) => false ) - } test("create S-blossom and use it for augmentation") { check0(Array((1, 2, 8), (1, 3, 9), (2, 3, 10), (3, 4, 7)), false, List(-1, 2, 1, 4, 3)) @@ -860,4 +855,3 @@ class WMMatchingTest extends munit.FunSuite { ) } -} diff --git a/modules/db/src/main/BSON.scala b/modules/db/src/main/BSON.scala index aff68e5f61b3d..86a93b0cc8c23 100644 --- a/modules/db/src/main/BSON.scala +++ b/modules/db/src/main/BSON.scala @@ -84,23 +84,23 @@ object BSON extends Handlers: final class Writer: def apply[A](a: A)(using writer: BSONWriter[A]): BSONValue = writer.writeTry(a).get - def boolO(b: Boolean): Option[BSONBoolean] = if (b) Some(BSONBoolean(true)) else None + def boolO(b: Boolean): Option[BSONBoolean] = if b then Some(BSONBoolean(true)) else None def str(s: String): BSONString = BSONString(s) - def strO(s: String): Option[BSONString] = if (s.nonEmpty) Some(BSONString(s)) else None - def int(i: Int): BSONInteger = BSONInteger(i) - def intO(i: Int): Option[BSONInteger] = if (i != 0) Some(BSONInteger(i)) else None + def strO(s: String): Option[BSONString] = if s.nonEmpty then Some(BSONString(s)) else None + def int(i: Int): BSONInteger = BSONInteger(i) + def intO(i: Int): Option[BSONInteger] = if i != 0 then Some(BSONInteger(i)) else None def date(d: Instant)(using handler: BSONHandler[Instant]): BSONValue = handler.writeTry(d).get def byteArrayO(b: ByteArray)(using handler: BSONHandler[ByteArray]): Option[BSONValue] = - if (b.isEmpty) None else handler.writeOpt(b) + if b.isEmpty then None else handler.writeOpt(b) def bytesO(b: Array[Byte]): Option[BSONValue] = byteArrayO(ByteArray(b)) def bytes(b: Array[Byte]): BSONBinary = BSONBinary(b, ByteArray.subtype) def listO[A](list: List[A])(using writer: BSONWriter[A]): Option[Barr] = - if (list.isEmpty) None + if list.isEmpty then None else Some(BSONArray(list flatMap writer.writeOpt)) - def docO(o: Bdoc): Option[Bdoc] = if (o.isEmpty) None else Some(o) + def docO(o: Bdoc): Option[Bdoc] = if o.isEmpty then None else Some(o) def double(i: Double): BSONDouble = BSONDouble(i) - def doubleO(i: Double): Option[BSONDouble] = if (i != 0) Some(BSONDouble(i)) else None - def zero[A](a: A)(using zero: Zero[A]): Option[A] = if (zero.zero == a) None else Some(a) + def doubleO(i: Double): Option[BSONDouble] = if i != 0 then Some(BSONDouble(i)) else None + def zero[A](a: A)(using zero: Zero[A]): Option[A] = if zero.zero == a then None else Some(a) def yesnoO[A](a: A)(using sr: SameRuntime[A, Boolean]): Option[BSONBoolean] = boolO(sr(a)) diff --git a/modules/db/src/main/ByteArray.scala b/modules/db/src/main/ByteArray.scala index cd17d714cb67e..f672e29d6453f 100644 --- a/modules/db/src/main/ByteArray.scala +++ b/modules/db/src/main/ByteArray.scala @@ -37,7 +37,7 @@ object ByteArray: var i = s.length - 1 var sum = 0 var mult = 1 - while (i >= 0) + while i >= 0 do s.charAt(i) match case '1' => sum += mult case '0' => @@ -57,7 +57,7 @@ object ByteArray: val bytes = new Array[Byte](sz) var i = 0 - while (i < sz) + while i < sz do val t = 2 * i bytes(i) = Integer.parseInt(str.substring(t, t + 2), 16).toByte i += 1 @@ -70,7 +70,7 @@ object ByteArray: val hex = new Array[Char](2 * len) var i = 0 - while (i < len) + while i < len do val b = bytes(i) val t = 2 * i // index in output buffer diff --git a/modules/db/src/main/Handlers.scala b/modules/db/src/main/Handlers.scala index b1ee07159987f..a470be49b460b 100644 --- a/modules/db/src/main/Handlers.scala +++ b/modules/db/src/main/Handlers.scala @@ -163,7 +163,7 @@ trait Handlers: given BSONHandler[chess.Mode] = BSONBooleanHandler.as[chess.Mode](chess.Mode.apply, _.rated) given [T: BSONHandler]: BSONHandler[(T, T)] = tryHandler[(T, T)]( - { case arr: BSONArray => for { a <- arr.getAsTry[T](0); b <- arr.getAsTry[T](1) } yield (a, b) }, + { case arr: BSONArray => for a <- arr.getAsTry[T](0); b <- arr.getAsTry[T](1) yield (a, b) }, { case (a, b) => BSONArray(a, b) } ) @@ -191,10 +191,10 @@ trait Handlers: val clockConfigHandler = tryHandler[chess.Clock.Config]( { case doc: BSONDocument => import chess.Clock.* - for { + for limit <- doc.getAsTry[LimitSeconds]("limit") inc <- doc.getAsTry[IncrementSeconds]("increment") - } yield Config(limit, inc) + yield Config(limit, inc) }, c => BSONDocument( diff --git a/modules/db/src/main/SingleFutureCache.scala b/modules/db/src/main/SingleFutureCache.scala index d0722c5d98e69..4cca7f1baef51 100644 --- a/modules/db/src/main/SingleFutureCache.scala +++ b/modules/db/src/main/SingleFutureCache.scala @@ -12,7 +12,7 @@ final private class SingleFutureCache[A](compute: () => Fu[A], expireAfterMillis def get: Fu[A] = val now = nowMillis - if (now > expiresAt) + if now > expiresAt then expiresAt = now + expireAfterMillis current = compute() current diff --git a/modules/db/src/main/dsl.scala b/modules/db/src/main/dsl.scala index 20649293bea14..89bd8f3b12e27 100644 --- a/modules/db/src/main/dsl.scala +++ b/modules/db/src/main/dsl.scala @@ -135,7 +135,7 @@ trait dsl: $doc("$addToSet" -> $doc((Seq(item) ++ items)*)) def $pop(item: (String, Int)): Bdoc = - if (item._2 != -1 && item._2 != 1) + if item._2 != -1 && item._2 != 1 then throw new IllegalArgumentException(s"${item._2} is not equal to: -1 | 1") $doc("$pop" -> $doc(item)) @@ -149,7 +149,7 @@ trait dsl: def $pull(item: ElementProducer): Bdoc = $doc("$pull" -> $doc(item)) def $addOrPull[T: BSONWriter](key: String, value: T, add: Boolean): Bdoc = - $doc((if (add) "$addToSet" else "$pull") -> $doc(key -> value)) + $doc((if add then "$addToSet" else "$pull") -> $doc(key -> value)) // End ofTop Level Array Update Operators // **********************************************************************************************// @@ -193,7 +193,8 @@ trait dsl: this.value ++ value /** MongoDB comparison operators. */ - trait ComparisonOperators { self: ElementBuilder => + trait ComparisonOperators: + self: ElementBuilder => def $eq[T: BSONWriter](value: T): SimpleExpression[BSONValue] = SimpleExpression(field, summon[BSONWriter[T]].writeTry(value).get) @@ -229,13 +230,12 @@ trait dsl: def $nin[T: BSONWriter](values: Iterable[T]): SimpleExpression[Bdoc] = SimpleExpression(field, $doc("$nin" -> values)) - } - - trait ElementOperators { self: ElementBuilder => + trait ElementOperators: + self: ElementBuilder => def $exists(v: Boolean): SimpleExpression[Bdoc] = SimpleExpression(field, $doc("$exists" -> v)) - } - trait EvaluationOperators { self: ElementBuilder => + trait EvaluationOperators: + self: ElementBuilder => def $mod(divisor: Int, remainder: Int): SimpleExpression[Bdoc] = SimpleExpression(field, $doc("$mod" -> BSONArray(divisor, remainder))) @@ -244,9 +244,9 @@ trait dsl: def $startsWith(value: String, options: String = ""): SimpleExpression[BSONRegex] = $regex(s"^$value", options) - } - trait ArrayOperators { self: ElementBuilder => + trait ArrayOperators: + self: ElementBuilder => def $all[T: BSONWriter](values: Seq[T]): SimpleExpression[Bdoc] = SimpleExpression(field, $doc("$all" -> values)) @@ -254,7 +254,6 @@ trait dsl: SimpleExpression(field, $doc("$elemMatch" -> $doc(query*))) def $size(s: Int): SimpleExpression[Bdoc] = SimpleExpression(field, $doc("$size" -> s)) - } object $sort: diff --git a/modules/evalCache/src/main/BSONHandlers.scala b/modules/evalCache/src/main/BSONHandlers.scala index 0b61173228d13..06cb235d5cabb 100644 --- a/modules/evalCache/src/main/BSONHandlers.scala +++ b/modules/evalCache/src/main/BSONHandlers.scala @@ -43,7 +43,7 @@ private object BSONHandlers: given BSONHandler[Id] = tryHandler[Id]( { case BSONString(value) => - value split ':' match { + value split ':' match case Array(fen) => Success(Id(chess.variant.Standard, SmallFen(fen))) case Array(variantId, fen) => import chess.variant.Variant @@ -56,11 +56,10 @@ private object BSONHandlers: ) ) case _ => lila.db.BSON.handlerBadValue(s"Invalid evalcache id $value") - } }, x => BSONString { - if (x.variant.standard || x.variant.fromPosition) x.smallFen.value + if x.variant.standard || x.variant.fromPosition then x.smallFen.value else s"${x.variant.id}:${x.smallFen.value}" } ) diff --git a/modules/evalCache/src/main/EvalCacheApi.scala b/modules/evalCache/src/main/EvalCacheApi.scala index 8b23cc1750238..f6c8abff84821 100644 --- a/modules/evalCache/src/main/EvalCacheApi.scala +++ b/modules/evalCache/src/main/EvalCacheApi.scala @@ -38,4 +38,4 @@ final class EvalCacheApi(coll: AsyncCollFailingSilently, cacheApi: lila.memo.Cac coll: c => c.one[EvalCacheEntry]($id(id)) .addEffect: res => - if (res.isDefined) c.updateFieldUnchecked($id(id), "usedAt", nowInstant) + if res.isDefined then c.updateFieldUnchecked($id(id), "usedAt", nowInstant) diff --git a/modules/evaluation/src/main/Display.scala b/modules/evaluation/src/main/Display.scala index 5f0969c499acf..0b469ee6156d5 100644 --- a/modules/evaluation/src/main/Display.scala +++ b/modules/evaluation/src/main/Display.scala @@ -23,4 +23,4 @@ object Display: case (_, true) => 4 case _ => 1 - def holdSig(pa: PlayerAssessment): Int = if (pa.flags.suspiciousHoldAlert) 5 else 1 + def holdSig(pa: PlayerAssessment): Int = if pa.flags.suspiciousHoldAlert then 5 else 1 diff --git a/modules/evaluation/src/main/PlayerAggregateAssessment.scala b/modules/evaluation/src/main/PlayerAggregateAssessment.scala index b04b0e2410b70..71d6a431f9a32 100644 --- a/modules/evaluation/src/main/PlayerAggregateAssessment.scala +++ b/modules/evaluation/src/main/PlayerAggregateAssessment.scala @@ -26,7 +26,7 @@ case class PlayerAggregateAssessment( (scoreCheatingGames(8) || scoreLikelyCheatingGames(16)) val reportable: Boolean = isWorthLookingAt && - (cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (if (isNewRatedUser) 2 + (cheatingSum >= 2 || cheatingSum + likelyCheatingSum >= (if isNewRatedUser then 2 else 4)) && (scoreCheatingGames(5) || scoreLikelyCheatingGames(10)) @@ -45,13 +45,13 @@ case class PlayerAggregateAssessment( val difFlags = difs map (sigDif(10)).tupled difFlags.forall(_.isEmpty) || difFlags.exists(~_) || assessmentsCount < 50 - if (actionable) - if (markable && bannable) EngineAndBan - else if (markable) Engine - else if (reportable) reportVariousReasons + if actionable then + if markable && bannable then EngineAndBan + else if markable then Engine + else if reportable then reportVariousReasons else Nothing - else if (markable) reportVariousReasons - else if (reportable) reportVariousReasons + else if markable then reportVariousReasons + else if reportable then reportVariousReasons else Nothing def countAssessmentValue(assessment: GameAssessment) = @@ -67,8 +67,8 @@ case class PlayerAggregateAssessment( def weightedAssessmentValue(assessment: GameAssessment): Double = playerAssessments map { pa => - if (pa.assessment != assessment) 0.0 - else pa.tcFactor.getOrElse(1.0) * (if (pa.flags.highlyConsistentMoveTimes) 1.6 else 1.0) + if pa.assessment != assessment then 0.0 + else pa.tcFactor.getOrElse(1.0) * (if pa.flags.highlyConsistentMoveTimes then 1.6 else 1.0) } sum val weightedCheatingSum = weightedAssessmentValue(Cheating) @@ -78,7 +78,7 @@ case class PlayerAggregateAssessment( def sfAvgGiven(predicate: PlayerAssessment => Boolean): Option[(Int, Int, Int)] = val filteredAssessments = playerAssessments.filter(predicate) val n = filteredAssessments.size - if (n < 2) none + if n < 2 then none else val filteredSfAvg = filteredAssessments.map(_.analysis.avg) val avg = listAverage(filteredSfAvg) diff --git a/modules/evaluation/src/main/PlayerAssessment.scala b/modules/evaluation/src/main/PlayerAssessment.scala index 79377ad655dfd..d57f9faebd67b 100644 --- a/modules/evaluation/src/main/PlayerAssessment.scala +++ b/modules/evaluation/src/main/PlayerAssessment.scala @@ -47,16 +47,14 @@ object PlayerAssessment: flags: PlayerFlags ): GameAssessment = import pov.{ color, game } - if ( - game.variant != chess.variant.Antichess || + if game.variant != chess.variant.Antichess || (assessment != GameAssessment.Cheating && assessment != GameAssessment.LikelyCheating) - ) assessment - else if ( - flags.highlyConsistentMoveTimes && flags.suspiciousErrorRate && game.playedTurns < 50 && game + then assessment + else if flags.highlyConsistentMoveTimes && flags.suspiciousErrorRate && game.playedTurns < 50 && game .sansOf(!color) .takeRight(12) .count(_.value.startsWith("B")) > 6 - ) GameAssessment.Unclear + then GameAssessment.Unclear else assessment def makeBasics(pov: Pov, holdAlerts: Option[Player.HoldAlert]): PlayerAssessment.Basics = @@ -97,11 +95,11 @@ object PlayerAssessment: } lazy val suspiciousErrorRate: Boolean = - listAverage(AccuracyCP.diffsList(pov.sideAndStart, analysis).flatten) < (game.speed match { + listAverage(AccuracyCP.diffsList(pov.sideAndStart, analysis).flatten) < (game.speed match case Speed.Bullet => 25 case Speed.Blitz => 20 case _ => 15 - }) + ) lazy val alwaysHasAdvantage: Boolean = !analysis.infos.exists { info => @@ -152,10 +150,10 @@ object PlayerAssessment: case PlayerFlags(F, F, _, _, _, _, _, _) => NotCheating // low accuracy, doesn't hold advantage case _ => NotCheating - if (flags.suspiciousHoldAlert) assessment - else if (~game.wonBy(color)) antichessCorrectedGameAssessment(assessment, pov, flags) - else if (assessment == Cheating) LikelyCheating - else if (assessment == LikelyCheating) Unclear + if flags.suspiciousHoldAlert then assessment + else if ~game.wonBy(color) then antichessCorrectedGameAssessment(assessment, pov, flags) + else if assessment == Cheating then LikelyCheating + else if assessment == LikelyCheating then Unclear else assessment val tcFactor: Double = game.speed match diff --git a/modules/evaluation/src/main/Statistics.scala b/modules/evaluation/src/main/Statistics.scala index c9f818e789893..ac66df98c649f 100644 --- a/modules/evaluation/src/main/Statistics.scala +++ b/modules/evaluation/src/main/Statistics.scala @@ -30,10 +30,10 @@ object Statistics: coefVariation(a.map(_.centis + 10)) def moveTimeCoefVariation(pov: lila.game.Pov): Option[Float] = - for { + for mt <- moveTimes(pov) coef <- moveTimeCoefVariation(mt) - } yield coef + yield coef def moveTimes(pov: lila.game.Pov): Option[List[Centis]] = pov.game.moveTimes(pov.color) diff --git a/modules/evaluation/src/test/StatisticsTest.scala b/modules/evaluation/src/test/StatisticsTest.scala index c1a21edd397e1..a216ebe89a729 100644 --- a/modules/evaluation/src/test/StatisticsTest.scala +++ b/modules/evaluation/src/test/StatisticsTest.scala @@ -1,9 +1,9 @@ package lila.evaluation import chess.Centis -import Statistics._ +import Statistics.* -class StatisticsTest extends munit.FunSuite { +class StatisticsTest extends munit.FunSuite: test("be highly consistent (1)") { assert( cvIndicatesHighlyFlatTimes( @@ -93,4 +93,3 @@ class StatisticsTest extends munit.FunSuite { ) ) } -} diff --git a/modules/fishnet/src/main/Analyser.scala b/modules/fishnet/src/main/Analyser.scala index 6870dd7752af5..c6b6917fb1005 100644 --- a/modules/fishnet/src/main/Analyser.scala +++ b/modules/fishnet/src/main/Analyser.scala @@ -65,9 +65,10 @@ final class Analyser( else import req.* val sender = Work.Sender(req.userId, none, mod = false, system = false) - (if (req.unlimited) fuccess(Analyser.Result.Ok) + (if req.unlimited then fuccess(Analyser.Result.Ok) else limiter(sender, ignoreConcurrentCheck = true, ownGame = false)) flatMap { result => - if (!result.ok) logger.info(s"Study request declined: ${req.studyId}/${req.chapterId} by $sender") + if !result.ok then + logger.info(s"Study request declined: ${req.studyId}/${req.chapterId} by $sender") result.ok so { val work = makeWork( game = Work.Game( diff --git a/modules/fishnet/src/main/AnalysisBuilder.scala b/modules/fishnet/src/main/AnalysisBuilder.scala index fc6ebe09a36a6..b56f32d59a6da 100644 --- a/modules/fishnet/src/main/AnalysisBuilder.scala +++ b/modules/fishnet/src/main/AnalysisBuilder.scala @@ -44,7 +44,7 @@ final private class AnalysisBuilder(evalCache: IFishnetEvalCache)(using Executor ) ) errors.foreach(e => logger.debug(s"[UciToPgn] $debug $e")) - if (analysis.valid) then + if analysis.valid then if !isPartial && analysis.emptyRatio >= 1d / 10 then fufail: s"${work.game.variant.key} analysis $debug has ${analysis.nbEmptyInfos} empty infos out of ${analysis.infos.size}" @@ -83,6 +83,6 @@ final private class AnalysisBuilder(evalCache: IFishnetEvalCache)(using Executor eval = Eval(after.score.cp, after.score.mate, best), variation = variation.map(uci => SanStr(uci.uci)) // temporary, for UciToSan ) - if (info.ply.isOdd) info.invert else info + if info.ply.isOdd then info.invert else info case ((_, _), index) => Info(startedAtPly + index + 1, Eval.empty, Nil) } diff --git a/modules/fishnet/src/main/Client.scala b/modules/fishnet/src/main/Client.scala index 1cc65ba780ded..7d466c2e042ab 100644 --- a/modules/fishnet/src/main/Client.scala +++ b/modules/fishnet/src/main/Client.scala @@ -54,9 +54,9 @@ object Client: case class Instance(version: Version, ip: IpAddress, seenAt: Instant): def update(i: Instance): Option[Instance] = - if (i.version != version) i.some - else if (i.ip != ip) i.some - else if (i.seenAt isAfter seenAt.plusMinutes(5)) i.some + if i.version != version then i.some + else if i.ip != ip then i.some + else if i.seenAt isAfter seenAt.plusMinutes(5) then i.some else none def seenRecently = seenAt isAfter Instance.recentSince diff --git a/modules/fishnet/src/main/Env.scala b/modules/fishnet/src/main/Env.scala index ad3555c637702..91f0613fda25f 100644 --- a/modules/fishnet/src/main/Env.scala +++ b/modules/fishnet/src/main/Env.scala @@ -103,16 +103,17 @@ final class Env( // api actor system.actorOf( - Props(new Actor { - def receive = { - case lila.hub.actorApi.fishnet.AutoAnalyse(gameId) => - analyser( - gameId, - Work.Sender(userId = lila.user.User.lichessId, ip = none, mod = false, system = true) - ).unit - case req: lila.hub.actorApi.fishnet.StudyChapterRequest => analyser.study(req).unit - } - }), + Props( + new Actor: + def receive = { + case lila.hub.actorApi.fishnet.AutoAnalyse(gameId) => + analyser( + gameId, + Work.Sender(userId = lila.user.User.lichessId, ip = none, mod = false, system = true) + ).unit + case req: lila.hub.actorApi.fishnet.StudyChapterRequest => analyser.study(req).unit + } + ), name = config.actorName ) diff --git a/modules/fishnet/src/main/FishnetApi.scala b/modules/fishnet/src/main/FishnetApi.scala index f4e512dfd67f0..a49e0ad6ceb08 100644 --- a/modules/fishnet/src/main/FishnetApi.scala +++ b/modules/fishnet/src/main/FishnetApi.scala @@ -30,7 +30,7 @@ final class FishnetApi( def keyExists(key: Client.Key) = repo.getEnabledClient(key).map(_.isDefined) def authenticateClient(req: JsonApi.Request, ip: IpAddress): Fu[Try[Client]] = { - if (config.offlineMode) repo.getOfflineClient map some + if config.offlineMode then repo.getOfflineClient map some else repo.getEnabledClient(req.fishnet.apikey) } map { case None => Failure(LilaNoStackTrace("Can't authenticate: invalid key or disabled client")) @@ -85,7 +85,7 @@ final class FishnetApi( Monitor.notFound(workId, client) fufail(WorkNotFound) case Some(work) if work isAcquiredBy client => - data.completeOrPartial match { + data.completeOrPartial match case complete: CompleteAnalysis => { analysisBuilder(client, work, complete.analysis) flatMap { analysis => @@ -106,7 +106,7 @@ final class FishnetApi( } else fuccess(PostAnalysisResult.UnusedPartial) } - }: Fu[PostAnalysisResult] + : Fu[PostAnalysisResult] case Some(work) => Monitor.notAcquired(work, client) fufail(NotAcquired) diff --git a/modules/fishnet/src/main/FishnetAwaiter.scala b/modules/fishnet/src/main/FishnetAwaiter.scala index 99c2aacd19ffe..e0868827bf7d2 100644 --- a/modules/fishnet/src/main/FishnetAwaiter.scala +++ b/modules/fishnet/src/main/FishnetAwaiter.scala @@ -14,7 +14,7 @@ final class FishnetAwaiter(using Executor, Scheduler): val listener = Bus.subscribeFun(busChannel): case lila.analyse.actorApi.AnalysisReady(game, _) if remainingIds(game.id) => remainingIds = remainingIds - game.id - if (remainingIds.isEmpty) promise.success {} + if remainingIds.isEmpty then promise.success {} promise.future.withTimeoutDefault(atMost, {}) addEffectAnyway { Bus.unsubscribe(listener, busChannel) } diff --git a/modules/fishnet/src/main/FishnetOpeningBook.scala b/modules/fishnet/src/main/FishnetOpeningBook.scala index fcc82bc0cac89..3fd2335446356 100644 --- a/modules/fishnet/src/main/FishnetOpeningBook.scala +++ b/modules/fishnet/src/main/FishnetOpeningBook.scala @@ -44,7 +44,7 @@ final private class FishnetOpeningBook( case res => for data <- res.body[JsValue].validate[Response].asOpt - _ = if (data.moves.isEmpty) outOfBook.put(game.id) + _ = if data.moves.isEmpty then outOfBook.put(game.id) move <- data randomPonderedMove (game.turnColor, level) yield move.uci } diff --git a/modules/fishnet/src/main/FishnetPlayer.scala b/modules/fishnet/src/main/FishnetPlayer.scala index 310386e983fa8..c28dd5023c6e0 100644 --- a/modules/fishnet/src/main/FishnetPlayer.scala +++ b/modules/fishnet/src/main/FishnetPlayer.scala @@ -38,9 +38,9 @@ final class FishnetPlayer( private val defaultClock = Clock(Clock.LimitSeconds(300), Clock.IncrementSeconds(0)) private def delayFor(g: Game): Option[FiniteDuration] = - if (!g.bothPlayersHaveMoved) 2.seconds.some + if !g.bothPlayersHaveMoved then 2.seconds.some else - for { + for pov <- g.aiPov clock = g.clock | defaultClock totalTime = clock.estimateTotalTime.centis @@ -51,13 +51,13 @@ final class FishnetPlayer( if sleep > 25 millis = sleep * 10 randomized = millis + millis * (ThreadLocalRandom.nextDouble() - 0.5) - divided = randomized / (if (g.ply > 9) 1 else 2) - } yield divided.toInt.millis + divided = randomized / (if g.ply > 9 then 1 else 2) + yield divided.toInt.millis private def makeWork(game: Game, level: Int): Fu[Work.Move] = - if (game.situation playable true) - if (game.ply <= maxPlies) gameRepo.initialFen(game) zip uciMemo.get(game) map { - case (initialFen, moves) => + if game.situation playable true then + if game.ply <= maxPlies then + gameRepo.initialFen(game) zip uciMemo.get(game) map { case (initialFen, moves) => Work.Move( _id = Work.makeId, game = Work.Game( @@ -68,7 +68,7 @@ final class FishnetPlayer( moves = moves mkString " " ), level = - if (level < 3 && game.clock.exists(_.config.limit.toSeconds < 60)) 3 + if level < 3 && game.clock.exists(_.config.limit.toSeconds < 60) then 3 else level, clock = game.clock.map { clk => Work.Clock( @@ -78,6 +78,6 @@ final class FishnetPlayer( ) } ) - } + } else fufail(s"[fishnet] Too many moves (${game.ply}), won't play ${game.id}") else fufail(s"[fishnet] invalid position on ${game.id}") diff --git a/modules/fishnet/src/main/FishnetRedis.scala b/modules/fishnet/src/main/FishnetRedis.scala index e0c5326bd2963..be49efba21fed 100644 --- a/modules/fishnet/src/main/FishnetRedis.scala +++ b/modules/fishnet/src/main/FishnetRedis.scala @@ -22,22 +22,22 @@ final class FishnetRedis( private var stopping = false def request(work: Work.Move): Unit = - if (!stopping) connOut.async.publish(chanOut, writeWork(work)).unit + if !stopping then connOut.async.publish(chanOut, writeWork(work)).unit connIn.async.subscribe(chanIn) - connIn.addListener(new RedisPubSubAdapter[String, String] { + connIn.addListener( + new RedisPubSubAdapter[String, String]: - override def message(chan: String, msg: String): Unit = - msg split ' ' match { - case Array("start") => Bus.publish(TellAll(FishnetStart), "roundSocket") - case Array(gameId, sign, uci) => - Uci(uci) foreach { move => - Bus.publish(Tell(gameId, FishnetPlay(move, sign)), "roundSocket") - } - case _ => - } - }) + override def message(chan: String, msg: String): Unit = + msg split ' ' match + case Array("start") => Bus.publish(TellAll(FishnetStart), "roundSocket") + case Array(gameId, sign, uci) => + Uci(uci) foreach { move => + Bus.publish(Tell(gameId, FishnetPlay(move, sign)), "roundSocket") + } + case _ => + ) Lilakka.shutdown(shutdown, _.PhaseServiceUnbind, "Stopping the fishnet redis pool") { () => Future { diff --git a/modules/fishnet/src/main/FishnetRepo.scala b/modules/fishnet/src/main/FishnetRepo.scala index 10e20284ae2d4..100439eb56748 100644 --- a/modules/fishnet/src/main/FishnetRepo.scala +++ b/modules/fishnet/src/main/FishnetRepo.scala @@ -43,7 +43,7 @@ final private class FishnetRepo( def updateAnalysis(ana: Work.Analysis) = analysisColl.update.one($id(ana.id), ana).void def deleteAnalysis(ana: Work.Analysis) = analysisColl.delete.one($id(ana.id)).void def updateOrGiveUpAnalysis(ana: Work.Analysis, update: Work.Analysis => Work.Analysis) = - if (ana.isOutOfTries) + if ana.isOutOfTries then logger.warn(s"Give up on analysis $ana") deleteAnalysis(ana) else updateAnalysis(update(ana)) diff --git a/modules/fishnet/src/main/JsonApi.scala b/modules/fishnet/src/main/JsonApi.scala index df3a87bbab339..eae2a2eb8d581 100644 --- a/modules/fishnet/src/main/JsonApi.scala +++ b/modules/fishnet/src/main/JsonApi.scala @@ -40,7 +40,7 @@ object JsonApi: ) extends Request: def completeOrPartial = - if (analysis.headOption.so(_.isDefined)) CompleteAnalysis(fishnet, stockfish, analysis.flatten) + if analysis.headOption.so(_.isDefined) then CompleteAnalysis(fishnet, stockfish, analysis.flatten) else PartialAnalysis(fishnet, stockfish, analysis) case class CompleteAnalysis( @@ -87,7 +87,7 @@ object JsonApi: case class Score(cp: Option[Cp], mate: Option[Mate]): def invert = copy(cp.map(_.invert), mate.map(_.invert)) - def invertIf(cond: Boolean) = if (cond) invert else this + def invertIf(cond: Boolean) = if cond then invert else this val npsCeil = 10_000_000 @@ -100,7 +100,7 @@ object JsonApi: def fromGame(g: W.Game) = Game( - game_id = if (g.studyId.isDefined) "" else g.id, + game_id = if g.studyId.isDefined then "" else g.id, position = g.initialFen | g.variant.initialFen, variant = g.variant, moves = g.moves diff --git a/modules/fishnet/src/main/Monitor.scala b/modules/fishnet/src/main/Monitor.scala index 82dc5aefa2f28..955ce6f4e6f63 100644 --- a/modules/fishnet/src/main/Monitor.scala +++ b/modules/fishnet/src/main/Monitor.scala @@ -32,7 +32,7 @@ final private class Monitor( monBy.totalSecond(userId).increment(sumOf(result.evaluations)(_.time) / 1000) - if (result.stockfish.isNnue) + if result.stockfish.isNnue then monBy .totalMeganode(userId) .increment(sumOf(result.evaluations) { eval => @@ -48,7 +48,7 @@ final private class Monitor( } (nb > 0) option (sum / nb) avgOf(_.time) foreach { monBy.movetime(userId).record(_) } - if (result.stockfish.isNnue) + if result.stockfish.isNnue then avgOf(_.nodes) foreach { monBy.node(userId).record(_) } avgOf(_.cappedNps) foreach { monBy.nps(userId).record(_) } avgOf(e => Depth raw e.depth) foreach { monBy.depth(userId).record(_) } @@ -61,7 +61,7 @@ final private class Monitor( monBy.pv(userId, isLong = true).increment(significantPvSizes.count(_ >= 6)) private def sample[A](elems: List[A], n: Int) = - if (elems.sizeIs <= n) elems else ThreadLocalRandom shuffle elems take n + if elems.sizeIs <= n then elems else ThreadLocalRandom shuffle elems take n private def monitorClients(): Funit = repo.allRecentClients map { clients => @@ -123,7 +123,7 @@ object Monitor: monResult.success(client.userId.value).increment() work.acquiredAt foreach { acquiredAt => - lila.mon.fishnet.queueTime(if (work.sender.system) "system" else "user").record { + lila.mon.fishnet.queueTime(if work.sender.system then "system" else "user").record { acquiredAt.toMillis - work.createdAt.toMillis } } diff --git a/modules/fishnet/src/main/SemVer.scala b/modules/fishnet/src/main/SemVer.scala index 473411ad595c0..cdf862487c663 100644 --- a/modules/fishnet/src/main/SemVer.scala +++ b/modules/fishnet/src/main/SemVer.scala @@ -18,7 +18,7 @@ object SemVer: y, z, { val e = extras.reverse ::: bits.drop(3).toList - if (e.isEmpty) None else Some(e.mkString("-")) + if e.isEmpty then None else Some(e.mkString("-")) }, version ) @@ -28,7 +28,7 @@ object SemVer: y, 0, { val e = extras.reverse ::: bits.drop(2).toList - if (e.isEmpty) None else Some(e.mkString("-")) + if e.isEmpty then None else Some(e.mkString("-")) }, version ) @@ -38,7 +38,7 @@ object SemVer: 0, 0, { val e = extras.reverse ::: bits.drop(1).toList - if (e.isEmpty) None else Some(e.mkString("-")) + if e.isEmpty then None else Some(e.mkString("-")) }, version ) @@ -65,9 +65,9 @@ case class SemVer(major: Long, minor: Long, point: Long, extra: Option[String], case _ => false def compare(o: SemVer): Int = - if (major != o.major) major.compare(o.major) - else if (minor != o.minor) minor.compare(o.minor) - else if (point != o.point) point.compare(o.point) + if major != o.major then major.compare(o.major) + else if minor != o.minor then minor.compare(o.minor) + else if point != o.point then point.compare(o.point) else import scala.util.control.Exception.* val thsNumPrefix: Option[Long] = allCatch opt extra.get.takeWhile(_.isDigit).toLong diff --git a/modules/fishnet/src/main/Work.scala b/modules/fishnet/src/main/Work.scala index 294bc9e74db0f..d47cebdc42ae3 100644 --- a/modules/fishnet/src/main/Work.scala +++ b/modules/fishnet/src/main/Work.scala @@ -59,7 +59,7 @@ object Work: ): override def toString = - if (system) lila.user.User.lichessId.value + if system then lila.user.User.lichessId.value else userId.value case class Clock(wtime: Int, btime: Int, inc: chess.Clock.IncrementSeconds) diff --git a/modules/fishnet/src/test/UciToSanTest.scala b/modules/fishnet/src/test/UciToSanTest.scala index d0c8a0147e1b9..2aeba3df3a2e7 100644 --- a/modules/fishnet/src/test/UciToSanTest.scala +++ b/modules/fishnet/src/test/UciToSanTest.scala @@ -6,19 +6,18 @@ import chess.format.pgn.{ SanStr, Reader } import lila.analyse.{ Analysis, Info } import lila.tree.Eval -import lila.tree.Eval._ +import lila.tree.Eval.* -final class UciToSanTest extends munit.FunSuite { +final class UciToSanTest extends munit.FunSuite: private given Conversion[Int, Ply] = Ply(_) private val now = nowInstant private def evenIncomplete(result: Reader.Result): Replay = - result match { + result match case Reader.Result.Complete(replay) => replay case Reader.Result.Incomplete(replay, _) => replay - } test("convert UCI analysis to PGN") { val uciAnalysis = Analysis( @@ -306,4 +305,3 @@ final class UciToSanTest extends munit.FunSuite { UciToSan(rep, uciAnalysis) match case (_, errs) => assertEquals(errs, Nil) } -} diff --git a/modules/forum/src/main/DetectLanguage.scala b/modules/forum/src/main/DetectLanguage.scala index b6c665680acf3..97fecba2280e4 100644 --- a/modules/forum/src/main/DetectLanguage.scala +++ b/modules/forum/src/main/DetectLanguage.scala @@ -26,7 +26,7 @@ final class DetectLanguage( private val defaultLang = Lang("en") def apply(message: String): Fu[Option[Lang]] = - if (config.key.value.isEmpty) fuccess(defaultLang.some) + if config.key.value.isEmpty then fuccess(defaultLang.some) else ws.url(config.url) .post( diff --git a/modules/forum/src/main/ForumCateg.scala b/modules/forum/src/main/ForumCateg.scala index 47b3790cad5a1..6352aff4a507b 100644 --- a/modules/forum/src/main/ForumCateg.scala +++ b/modules/forum/src/main/ForumCateg.scala @@ -19,22 +19,22 @@ case class ForumCateg( inline def id = _id - def nbTopics(forUser: Option[User]): Int = if (forUser.exists(_.marks.troll)) nbTopicsTroll else nbTopics - def nbPosts(forUser: Option[User]): Int = if (forUser.exists(_.marks.troll)) nbPostsTroll else nbPosts + def nbTopics(forUser: Option[User]): Int = if forUser.exists(_.marks.troll) then nbTopicsTroll else nbTopics + def nbPosts(forUser: Option[User]): Int = if forUser.exists(_.marks.troll) then nbPostsTroll else nbPosts def lastPostId(forUser: Option[User]): ForumPostId = - if (forUser.exists(_.marks.troll)) lastPostIdTroll else lastPostId + if forUser.exists(_.marks.troll) then lastPostIdTroll else lastPostId def isTeam = team.nonEmpty def withPost(topic: ForumTopic, post: ForumPost): ForumCateg = copy( // the `Topic` object is created before adding the post, hence why nbPosts is compared to 0 and not to 1 - nbTopics = if (post.troll || topic.nbPosts > 0) nbTopics else nbTopics + 1, - nbPosts = if (post.troll) nbPosts else nbPosts + 1, - lastPostId = if (post.troll || topic.isTooBig) lastPostId else post.id, - nbTopicsTroll = if (topic.nbPostsTroll == 0) nbTopicsTroll + 1 else nbTopicsTroll, + nbTopics = if post.troll || topic.nbPosts > 0 then nbTopics else nbTopics + 1, + nbPosts = if post.troll then nbPosts else nbPosts + 1, + lastPostId = if post.troll || topic.isTooBig then lastPostId else post.id, + nbTopicsTroll = if topic.nbPostsTroll == 0 then nbTopicsTroll + 1 else nbTopicsTroll, nbPostsTroll = nbPostsTroll + 1, - lastPostIdTroll = if (topic.isTooBig) lastPostIdTroll else post.id + lastPostIdTroll = if topic.isTooBig then lastPostIdTroll else post.id ) def slug = id diff --git a/modules/forum/src/main/ForumCategApi.scala b/modules/forum/src/main/ForumCategApi.scala index 0c4109007cac1..fa845a1a24259 100644 --- a/modules/forum/src/main/ForumCategApi.scala +++ b/modules/forum/src/main/ForumCategApi.scala @@ -57,7 +57,7 @@ final class ForumCategApi( } def denormalize(categ: ForumCateg): Funit = - for { + for nbTopics <- topicRepo countByCateg categ nbPosts <- postRepo countByCateg categ lastPost <- postRepo lastByCateg categ @@ -78,4 +78,4 @@ final class ForumCategApi( ) ) .void - } yield () + yield () diff --git a/modules/forum/src/main/ForumPaginator.scala b/modules/forum/src/main/ForumPaginator.scala index e07b3c51d8ad8..bfb0f90ab52f1 100644 --- a/modules/forum/src/main/ForumPaginator.scala +++ b/modules/forum/src/main/ForumPaginator.scala @@ -35,10 +35,10 @@ final class ForumPaginator( Paginator( currentPage = page, maxPerPage = config.topicMaxPerPage, - adapter = new AdapterLike[TopicView] { + adapter = new AdapterLike[TopicView]: def nbResults: Fu[Int] = - if (categ.isTeam) topicRepo.coll countSel selector + if categ.isTeam then topicRepo.coll countSel selector else fuccess(1000) def slice(offset: Int, length: Int): Fu[Seq[TopicView]] = @@ -65,5 +65,4 @@ final class ForumPaginator( yield TopicView(categ, topic, post, topic lastPage config.postMaxPerPage, me) private def selector = topicRepo.forUser(me) byCategNotStickyQuery categ - } ) diff --git a/modules/forum/src/main/ForumPost.scala b/modules/forum/src/main/ForumPost.scala index a7f18c5501690..65d0e24449a0a 100644 --- a/modules/forum/src/main/ForumPost.scala +++ b/modules/forum/src/main/ForumPost.scala @@ -28,9 +28,9 @@ case class ForumPost( inline def id = _id private def showAuthor: String = - author.map(_.trim).filter("" !=) | (if (~modIcon) User.anonymous.value else User.anonMod) + author.map(_.trim).filter("" !=) | (if ~modIcon then User.anonymous.value else User.anonMod) - def showUserIdOrAuthor: String = if (erased) "" else userId.fold(showAuthor)(_.value) + def showUserIdOrAuthor: String = if erased then "" else userId.fold(showAuthor)(_.value) def isTeam = ForumCateg.isTeamSlug(categId) diff --git a/modules/forum/src/main/ForumPostApi.scala b/modules/forum/src/main/ForumPostApi.scala index 1aacab03cc8f4..b88473fd0745e 100644 --- a/modules/forum/src/main/ForumPostApi.scala +++ b/modules/forum/src/main/ForumPostApi.scala @@ -172,7 +172,7 @@ final class ForumPostApi( def nbByUser(userId: UserId) = postRepo.coll.countSel($doc("userId" -> userId)) def categsForUser(teams: Iterable[TeamId], forUser: Option[User]): Fu[List[CategView]] = - for { + for categs <- categRepo visibleWithTeams teams views <- categs.map { categ => get(categ lastPostId forUser) map { topicPost => @@ -185,7 +185,7 @@ final class ForumPostApi( ) } }.parallel - } yield views + yield views private def recentUserIds(topic: ForumTopic, newPostNumber: Int) = postRepo.coll diff --git a/modules/forum/src/main/ForumPostRepo.scala b/modules/forum/src/main/ForumPostRepo.scala index efdfbfaea16e5..fb8fe7e948145 100644 --- a/modules/forum/src/main/ForumPostRepo.scala +++ b/modules/forum/src/main/ForumPostRepo.scala @@ -14,7 +14,7 @@ final class ForumPostRepo(val coll: Coll, filter: Filter = Safe)(using withFilter(user.filter(_.marks.troll).fold[Filter](Safe) { u => SafeAnd(u.id) }) - def withFilter(f: Filter) = if (f == filter) this else new ForumPostRepo(coll, f) + def withFilter(f: Filter) = if f == filter then this else new ForumPostRepo(coll, f) def unsafe = withFilter(Unsafe) import BSONHandlers.given @@ -81,7 +81,7 @@ final class ForumPostRepo(val coll: Coll, filter: Filter = Safe)(using val selectNotErased = $doc("erasedAt" $exists false) def selectLangs(langs: List[String]) = - if (langs.isEmpty) $empty + if langs.isEmpty then $empty else $doc("lang" $in langs) def findDuplicate(post: ForumPost): Fu[Option[ForumPost]] = diff --git a/modules/forum/src/main/ForumTopic.scala b/modules/forum/src/main/ForumTopic.scala index 098c97b64f6be..4d03ca08f91ea 100644 --- a/modules/forum/src/main/ForumTopic.scala +++ b/modules/forum/src/main/ForumTopic.scala @@ -28,11 +28,11 @@ case class ForumTopic( inline def id = _id def updatedAt(forUser: Option[User]): Instant = - if (forUser.exists(_.marks.troll)) updatedAtTroll else updatedAt - def nbPosts(forUser: Option[User]): Int = if (forUser.exists(_.marks.troll)) nbPostsTroll else nbPosts + if forUser.exists(_.marks.troll) then updatedAtTroll else updatedAt + def nbPosts(forUser: Option[User]): Int = if forUser.exists(_.marks.troll) then nbPostsTroll else nbPosts def nbReplies(forUser: Option[User]): Int = nbPosts(forUser) - 1 def lastPostId(forUser: Option[User]): ForumPostId = - if (forUser.exists(_.marks.troll)) lastPostIdTroll else lastPostId + if forUser.exists(_.marks.troll) then lastPostIdTroll else lastPostId def open = !closed @@ -49,12 +49,12 @@ case class ForumTopic( def withPost(post: ForumPost): ForumTopic = copy( - nbPosts = if (post.troll) nbPosts else nbPosts + 1, - lastPostId = if (post.troll) lastPostId else post.id, - updatedAt = if (isTooBig || post.troll) updatedAt else post.createdAt, + nbPosts = if post.troll then nbPosts else nbPosts + 1, + lastPostId = if post.troll then lastPostId else post.id, + updatedAt = if isTooBig || post.troll then updatedAt else post.createdAt, nbPostsTroll = nbPostsTroll + 1, lastPostIdTroll = post.id, - updatedAtTroll = if (isTooBig) updatedAt else post.createdAt + updatedAtTroll = if isTooBig then updatedAt else post.createdAt ) def incNbPosts = copy(nbPosts = nbPosts + 1) @@ -72,7 +72,7 @@ object ForumTopic: def nameToId(name: String) = (lila.common.String slugify name) pipe { slug => // if most chars are not latin, go for random slug - if (slug.lengthIs > (name.lengthIs / 2)) slug else ThreadLocalRandom nextString 8 + if slug.lengthIs > (name.lengthIs / 2) then slug else ThreadLocalRandom nextString 8 } val idSize = 8 diff --git a/modules/forum/src/main/ForumTopicApi.scala b/modules/forum/src/main/ForumTopicApi.scala index 7bfbc45cdf65f..4f381a0676f66 100644 --- a/modules/forum/src/main/ForumTopicApi.scala +++ b/modules/forum/src/main/ForumTopicApi.scala @@ -90,10 +90,10 @@ final private class ForumTopicApi( promotion.save(post.text) shutup ! { val text = s"${topic.name} ${post.text}" - if (post.isTeam) lila.hub.actorApi.shutup.RecordTeamForumMessage(me, text) + if post.isTeam then lila.hub.actorApi.shutup.RecordTeamForumMessage(me, text) else lila.hub.actorApi.shutup.RecordPublicForumMessage(me, text) } - if (!post.troll && !categ.quiet) + if !post.troll && !categ.quiet then timeline ! Propagate(TimelinePost(me, topic.id, topic.name, post.id)) .toFollowersOf(me) .withTeam(categ.team) diff --git a/modules/forum/src/main/ForumTopicRepo.scala b/modules/forum/src/main/ForumTopicRepo.scala index fd5b83960eec2..273e0286c8f50 100644 --- a/modules/forum/src/main/ForumTopicRepo.scala +++ b/modules/forum/src/main/ForumTopicRepo.scala @@ -14,7 +14,7 @@ final private class ForumTopicRepo(val coll: Coll, filter: Filter = Safe)(using withFilter(user.filter(_.marks.troll).fold[Filter](Safe) { u => SafeAnd(u.id) }) - def withFilter(f: Filter) = if (f == filter) this else new ForumTopicRepo(coll, f) + def withFilter(f: Filter) = if f == filter then this else new ForumTopicRepo(coll, f) def unsafe = withFilter(Unsafe) private val noTroll = $doc("troll" -> false) @@ -56,7 +56,7 @@ final private class ForumTopicRepo(val coll: Coll, filter: Filter = Safe)(using val slug = ForumTopic.nameToId(name) + ~(it != 1).option("-" + it) // also take troll topic into accounts unsafe.byTree(categ.id, slug) flatMap { found => - if (found.isDefined) nextSlug(categ, name, it + 1) + if found.isDefined then nextSlug(categ, name, it + 1) else fuccess(slug) } diff --git a/modules/forumSearch/src/main/Env.scala b/modules/forumSearch/src/main/Env.scala index 76f6bc76b502c..3f392cc3a3fc9 100644 --- a/modules/forumSearch/src/main/Env.scala +++ b/modules/forumSearch/src/main/Env.scala @@ -44,13 +44,13 @@ final class Env( private lazy val paginatorBuilder = lila.search.PaginatorBuilder(api, config.maxPerPage) system.actorOf( - Props(new Actor { + Props(new Actor: import lila.forum.* def receive = { case InsertPost(post) => api.store(post).unit case RemovePost(id) => client.deleteById(id into Id).unit case RemovePosts(ids) => client.deleteByIds(Id.from[List, ForumPostId](ids)).unit } - }), + ), name = config.actorName ) diff --git a/modules/game/src/main/BSONHandlers.scala b/modules/game/src/main/BSONHandlers.scala index 8742bfcb3f2f0..99cdcb6107fe7 100644 --- a/modules/game/src/main/BSONHandlers.scala +++ b/modules/game/src/main/BSONHandlers.scala @@ -63,7 +63,7 @@ object BSONHandlers: { case arr: BSONArray => Success(arr.values.foldLeft(GameDrawOffers.empty) { case (offers, BSONInteger(p)) => - if (p > 0) offers.copy(white = offers.white incl Ply(p)) + if p > 0 then offers.copy(white = offers.white incl Ply(p)) else offers.copy(black = offers.black incl Ply(-p)) case (offers, _) => offers }) @@ -127,10 +127,10 @@ object BSONHandlers: halfMoveClock = decoded.halfMoveClock, positionHashes = decoded.positionHashes, unmovedRooks = decoded.unmovedRooks, - checkCount = if (gameVariant.threeCheck) { + checkCount = if gameVariant.threeCheck then val counts = r.intsD(F.checkCount) CheckCount(~counts.headOption, ~counts.lastOption) - } else Game.emptyCheckCount + else Game.emptyCheckCount ), variant = gameVariant, crazyData = gameVariant.crazyhouse option r.get[Crazyhouse.Data](F.crazyData) @@ -217,7 +217,7 @@ object BSONHandlers: F.analysed -> w.boolO(o.metadata.analysed), F.rules -> o.metadata.nonEmptyRules ) ++ { - if (o.variant.standard) + if o.variant.standard then $doc(F.huffmanPgn -> PgnStorage.Huffman.encode(o.sans take Game.maxPlies.value)) else val f = PgnStorage.OldBin diff --git a/modules/game/src/main/BinaryFormat.scala b/modules/game/src/main/BinaryFormat.scala index 87cfed1f42d37..6e90ab4ea6e10 100644 --- a/modules/game/src/main/BinaryFormat.scala +++ b/modules/game/src/main/BinaryFormat.scala @@ -29,13 +29,13 @@ object BinaryFormat: private val logger = lila.log("clockHistory") def writeSide(start: Centis, times: Vector[Centis], flagged: Boolean) = - val timesToWrite = if (flagged) times.dropRight(1) else times + val timesToWrite = if flagged then times.dropRight(1) else times ByteArray(ClockEncoder.encode(Centis.raw(timesToWrite).to(Array), start.centis)) def readSide(start: Centis, ba: ByteArray, flagged: Boolean) = val decoded: Vector[Centis] = Centis from ClockEncoder.decode(ba.value, start.centis).to(Vector) - if (flagged) decoded :+ Centis(0) else decoded + if flagged then decoded :+ Centis(0) else decoded def read(start: Centis, bw: ByteArray, bb: ByteArray, flagged: Option[Color]) = Try { @@ -44,7 +44,9 @@ object BinaryFormat: readSide(start, bb, flagged has Black) ) }.fold( - e => { logger.warn(s"Exception decoding history", e); none }, + e => + logger.warn(s"Exception decoding history", e); none + , some ) @@ -94,14 +96,14 @@ object BinaryFormat: } def read(ba: ByteArray, whiteBerserk: Boolean, blackBerserk: Boolean): Color => Clock = - color => { + color => val ia = ba.value map toInt // ba.size might be greater than 12 with 5 bytes timers // ba.size might be 8 if there was no timer. // #TODO remove 5 byte timer case! But fix the DB first! val timer = - if (ia.lengthIs == 12) readTimer(readInt(ia(8), ia(9), ia(10), ia(11))) + if ia.lengthIs == 12 then readTimer(readInt(ia(8), ia(9), ia(10), ia(11))) else None ia match @@ -122,7 +124,6 @@ object BinaryFormat: timer = timer ) case _ => sys error s"BinaryFormat.clock.read invalid bytes: ${ba.showBytes}" - } private def writeTimer(timer: Timestamp) = val centis = (timer - start).centis @@ -137,7 +138,7 @@ object BinaryFormat: writeInt(nonZero) private def readTimer(l: Int) = - if (l != 0) Some(start + Centis(l)) else None + if l != 0 then Some(start + Centis(l)) else None private def writeClockLimit(limit: Int): Byte = // The database expects a byte for a limit, and this is limit / 60. @@ -146,7 +147,7 @@ object BinaryFormat: // The max limit where limit % 60 == 0, returns 180 for limit / 60 // So, for the limits where limit % 30 == 0, we can use the space // from 181-255, where 181 represents 0.25 and 182 represents 0.50... - (if (limit % 60 == 0) limit / 60 else limit / 15 + 180).toByte + (if limit % 60 == 0 then limit / 60 else limit / 15 + 180).toByte object clock: def apply(start: Instant) = new clock(Timestamp(start.toMillis)) @@ -156,7 +157,7 @@ object BinaryFormat: case Array(b1, b2, _*) => Clock.Config(readClockLimit(b1), Clock.IncrementSeconds(b2)).some case _ => None - def readClockLimit(i: Int) = Clock.LimitSeconds(if (i < 181) i * 60 else (i - 180) * 15) + def readClockLimit(i: Int) = Clock.LimitSeconds(if i < 181 then i * 60 else (i - 180) * 15) object castleLastMove: @@ -181,11 +182,11 @@ object BinaryFormat: private def doRead(b1: Int, b2: Int) = CastleLastMove( castles = Castles(b1 > 127, (b1 & 64) != 0, (b1 & 32) != 0, (b1 & 16) != 0), - lastMove = for { + lastMove = for orig <- Square.at((b1 & 15) >> 1, ((b1 & 1) << 2) + (b2 >> 6)) dest <- Square.at((b2 & 63) >> 3, b2 & 7) if orig != Square.A1 || dest != Square.A1 - } yield Uci.Move(orig, dest) + yield Uci.Move(orig, dest) ) object piece: @@ -246,13 +247,13 @@ object BinaryFormat: val emptyByteArray = ByteArray(Array(0, 0)) def write(o: UnmovedRooks): ByteArray = - if (o.isEmpty) emptyByteArray + if o.isEmpty then emptyByteArray else ByteArray { var white = 0 var black = 0 o.toList.foreach { pos => - if (pos.rank == Rank.First) white = white | (1 << (7 - pos.file.index)) + if pos.rank == Rank.First then white = white | (1 << (7 - pos.file.index)) else black = black | (1 << (7 - pos.file.index)) } Array(white.toByte, black.toByte) @@ -269,11 +270,11 @@ object BinaryFormat: var set = Set.empty[Square] arrIndexes.foreach { i => val int = ba.value(i).toInt - if (int != 0) - if (int == -127) set = if (i == 0) whiteStd else set ++ blackStd + if int != 0 then + if int == -127 then set = if i == 0 then whiteStd else set ++ blackStd else bitIndexes.foreach { j => - if (bitAt(int, j) == 1) set = set + Square.at(7 - j, 7 * i).get + if bitAt(int, j) == 1 then set = set + Square.at(7 - j, 7 * i).get } } UnmovedRooks(set) @@ -281,19 +282,19 @@ object BinaryFormat: @inline private def toInt(b: Byte): Int = b & 0xff def writeInt24(int: Int) = - val i = if (int < (1 << 24)) int else 0 + val i = if int < (1 << 24) then int else 0 Array((i >>> 16).toByte, (i >>> 8).toByte, i.toByte) private val int23Max = 1 << 23 def writeSignedInt24(int: Int) = - val i = if (int < 0) int23Max - int else math.min(int, int23Max) + val i = if int < 0 then int23Max - int else math.min(int, int23Max) writeInt24(i) def readInt24(b1: Int, b2: Int, b3: Int) = (b1 << 16) | (b2 << 8) | b3 def readSignedInt24(b1: Int, b2: Int, b3: Int) = val i = readInt24(b1, b2, b3) - if (i > int23Max) int23Max - i else i + if i > int23Max then int23Max - i else i def writeInt(i: Int) = Array( diff --git a/modules/game/src/main/Blurs.scala b/modules/game/src/main/Blurs.scala index 2a9c4792f6770..b30f177b8493d 100644 --- a/modules/game/src/main/Blurs.scala +++ b/modules/game/src/main/Blurs.scala @@ -23,7 +23,7 @@ object Blurs extends OpaqueLong[Blurs]: def nb = java.lang.Long.bitCount(bits) def add(moveIndex: Int): Blurs = - if (moveIndex < 0 || moveIndex > 63) bits + if moveIndex < 0 || moveIndex > 63 then bits else Blurs(bits | (1L << moveIndex)) def asInt = ((bits >>> 32) == 0) option bits.toInt diff --git a/modules/game/src/main/Captcher.scala b/modules/game/src/main/Captcher.scala index f2f3581d87f48..250a890f2cca2 100644 --- a/modules/game/src/main/Captcher.scala +++ b/modules/game/src/main/Captcher.scala @@ -45,8 +45,7 @@ final private class Captcher(gameRepo: GameRepo)(using Executor) extends Actor: private var challenges = NonEmptyList.one(Captcha.default) private def add(c: Captcha): Unit = - if (find(c.gameId).isEmpty) - challenges = NonEmptyList(c, challenges.toList take capacity) + if find(c.gameId).isEmpty then challenges = NonEmptyList(c, challenges.toList take capacity) private def find(id: GameId): Option[Captcha] = challenges.find(_.gameId == id) diff --git a/modules/game/src/main/Crosstable.scala b/modules/game/src/main/Crosstable.scala index 66d6c2b2275f2..4e31cf36b8b7e 100644 --- a/modules/game/src/main/Crosstable.scala +++ b/modules/game/src/main/Crosstable.scala @@ -38,8 +38,8 @@ object Crosstable: val nbGames = (user1.score + user2.score) / 10 def user(id: UserId): Option[User] = - if (id == user1.id) Some(user1) - else if (id == user2.id) Some(user2) + if id == user1.id then Some(user1) + else if id == user2.id then Some(user2) else None def toList = List(user1, user2) @@ -51,17 +51,17 @@ object Crosstable: case x => x def showOpponentScore(userId: UserId) = - if (userId == user1.id) showScore(user2.id).some - else if (userId == user2.id) showScore(user1.id).some + if userId == user1.id then showScore(user2.id).some + else if userId == user2.id then showScore(user1.id).some else none def fromPov(userId: UserId) = - if (userId == user2.id) copy(user1 = user2, user2 = user1) + if userId == user2.id then copy(user1 = user2, user2 = user1) else this def winnerId = - if (user1.score > user2.score) Some(user1.id) - else if (user1.score < user2.score) Some(user2.id) + if user1.score > user2.score then Some(user1.id) + else if user1.score < user2.score then Some(user2.id) else None case class Result(gameId: GameId, winnerId: Option[UserId]) @@ -78,7 +78,7 @@ object Crosstable: ) private[game] def makeKey(u1: UserId, u2: UserId): String = - if (u1.value < u2.value) s"$u1/$u2" else s"$u2/$u1" + if u1.value < u2.value then s"$u1/$u2" else s"$u2/$u1" import reactivemongo.api.bson.* import lila.db.BSON @@ -99,12 +99,11 @@ object Crosstable: Crosstable( users = Users(User(UserId(u1Id), r intD score1), User(UserId(u2Id), r intD score2)), results = r.get[List[String]](results).map { r => - r drop 8 match { + r drop 8 match case "" => Result(GameId(r), Some(UserId(u1Id))) case "-" => Result(GameId(r take 8), Some(UserId(u2Id))) case "=" => Result(GameId(r take 8), none) case _ => sys error s"Invalid result string $r" - } } ) case x => sys error s"Invalid crosstable id $x" diff --git a/modules/game/src/main/Divider.scala b/modules/game/src/main/Divider.scala index b0927c3a6ba70..a73519ff193d1 100644 --- a/modules/game/src/main/Divider.scala +++ b/modules/game/src/main/Divider.scala @@ -17,7 +17,7 @@ final class Divider: apply(game.id, game.sans, game.variant, initialFen) def apply(id: GameId, sans: => Vector[SanStr], variant: Variant, initialFen: Option[Fen.Epd]) = - if (!Variant.list.divisionSensibleVariants(variant)) Division.empty + if !Variant.list.divisionSensibleVariants(variant) then Division.empty else cache.get(id, _ => noCache(sans, variant, initialFen)) def noCache(sans: Vector[SanStr], variant: Variant, initialFen: Option[Fen.Epd]) = diff --git a/modules/game/src/main/Game.scala b/modules/game/src/main/Game.scala index a9b946302b259..5142375e2e3d6 100644 --- a/modules/game/src/main/Game.scala +++ b/modules/game/src/main/Game.scala @@ -137,14 +137,14 @@ case class Game( .map: (first, second) => { val d = first - second - if (pairs.hasNext || !noLastInc) d + inc else d + if pairs.hasNext || !noLastInc then d + inc else d }.nonNeg .toList } } orElse binaryMoveTimes.map: binary => // TODO: make movetime.read return List after writes are disabled. val base = BinaryFormat.moveTime.read(binary, playedTurns) - val mts = if (color == startColor) base else base.drop(1) + val mts = if color == startColor then base else base.drop(1) everyOther(mts.toList) def moveTimes: Option[Vector[Centis]] = for @@ -155,7 +155,7 @@ case class Game( def bothClockStates: Option[Vector[Centis]] = clockHistory.map(_ bothClockStates startColor) def sansOf(color: Color): Vector[SanStr] = - val pivot = if (color == startColor) 0 else 1 + val pivot = if color == startColor then 0 else 1 sans.zipWithIndex.collect: case (e, i) if (i % 2) == pivot => e @@ -797,8 +797,7 @@ private def interleave[A](a: Seq[A], b: Seq[A]): Vector[A] = val iterA = a.iterator val iterB = b.iterator val builder = Vector.newBuilder[A] - while (iterA.hasNext && iterB.hasNext) - builder += iterA.next() += iterB.next() + while iterA.hasNext && iterB.hasNext do builder += iterA.next() += iterB.next() builder ++= iterA ++= iterB builder.result() diff --git a/modules/game/src/main/GameDiff.scala b/modules/game/src/main/GameDiff.scala index 62e7fa9e151c3..11c3146c60f00 100644 --- a/modules/game/src/main/GameDiff.scala +++ b/modules/game/src/main/GameDiff.scala @@ -28,14 +28,14 @@ object GameDiff: def d[A](name: String, getter: Game => A, toBson: A => BSONValue): Unit = val vb = getter(b) - if (getter(a) != vb) - if (vb == None || vb == null || vb == "") unsetBuilder += (name -> bTrue) - else setBuilder += name -> toBson(vb) + if getter(a) != vb then + if vb == None || vb == null || vb == "" then unsetBuilder += (name -> bTrue) + else setBuilder += name -> toBson(vb) def dOpt[A](name: String, getter: Game => A, toBson: A => Option[BSONValue]): Unit = val vb = getter(b) - if (getter(a) != vb) - if (vb == None || vb == null || vb == "") unsetBuilder += (name -> bTrue) + if getter(a) != vb then + if vb == None || vb == null || vb == "" then unsetBuilder += (name -> bTrue) else toBson(vb) match case None => unsetBuilder += (name -> bTrue) @@ -45,19 +45,19 @@ object GameDiff: d[A](name, getter, a => toBson(a).get) def getClockHistory(color: Color)(g: Game): Option[ClockHistorySide] = - for { + for clk <- g.clock history <- g.clockHistory curColor = g.turnColor times = history(color) - } yield (clk.limit, times, g.flagged has color) + yield (clk.limit, times, g.flagged has color) def clockHistoryToBytes(o: Option[ClockHistorySide]) = o.flatMap { case (x, y, z) => byteArrayHandler.writeOpt(BinaryFormat.clockHistory.writeSide(x, y, z)) } - if (a.variant.standard) dTry(huffmanPgn, _.sans, writeBytes compose PgnStorage.Huffman.encode) + if a.variant.standard then dTry(huffmanPgn, _.sans, writeBytes compose PgnStorage.Huffman.encode) else val f = PgnStorage.OldBin dTry(oldPgn, _.sans, writeBytes compose f.encode) @@ -66,13 +66,13 @@ object GameDiff: dTry(unmovedRooks, _.history.unmovedRooks, writeBytes compose BinaryFormat.unmovedRooks.write) dTry(castleLastMove, makeCastleLastMove, CastleLastMove.castleLastMoveHandler.writeTry) // since variants are always OldBin - if (a.variant.threeCheck) + if a.variant.threeCheck then dOpt( checkCount, _.history.checkCount, (o: CheckCount) => o.nonEmpty so { BSONHandlers.checkCountWriter writeOpt o } ) - if (a.variant.crazyhouse) + if a.variant.crazyhouse then dOpt( crazyData, _.board.crazyData, @@ -91,10 +91,10 @@ object GameDiff: } ) dTry(drawOffers, _.drawOffers, BSONHandlers.gameDrawOffersHandler.writeTry) - for (i <- 0 to 1) + for i <- 0 to 1 do import Player.BSONFields.* val name = s"p$i." - val player: Game => Player = if (i == 0) (_.whitePlayer) else (_.blackPlayer) + val player: Game => Player = if i == 0 then (_.whitePlayer) else (_.blackPlayer) dOpt(s"$name$isOfferingDraw", player(_).isOfferingDraw, w.boolO) dOpt(s"$name$proposeTakebackAt", player(_).proposeTakebackAt, ply => w.intO(ply.value)) dTry(s"$name$blursBits", player(_).blurs, Blurs.blursHandler.writeTry) diff --git a/modules/game/src/main/GameRepo.scala b/modules/game/src/main/GameRepo.scala index a74cb8818f635..1d08ef6e21d0d 100644 --- a/modules/game/src/main/GameRepo.scala +++ b/modules/game/src/main/GameRepo.scala @@ -188,7 +188,7 @@ final class GameRepo(val coll: Coll)(using Executor): .void private def nonEmptyMod(mod: String, doc: Bdoc) = - if (doc.isEmpty) $empty else $doc(mod -> doc) + if doc.isEmpty then $empty else $doc(mod -> doc) def setRatingDiffs(id: GameId, diffs: RatingDiffs) = coll.update.one( @@ -328,12 +328,12 @@ final class GameRepo(val coll: Coll)(using Executor): val idColors = povs.view.map { p => p.gameId -> p.color }.toMap - val holds = for { + val holds = for doc <- docs id <- doc.getAsOpt[GameId]("_id") color <- idColors get id holds <- holdAlertOf(doc, color) - } yield id -> holds + yield id -> holds holds.toMap } @@ -392,7 +392,7 @@ final class GameRepo(val coll: Coll)(using Executor): def insertDenormalized(g: Game, initialFen: Option[chess.format.Fen.Epd] = None): Funit = val g2 = - if (g.rated && (g.userIds.distinct.size != 2 || !Game.allowRated(g.variant, g.clock.map(_.config)))) + if g.rated && (g.userIds.distinct.size != 2 || !Game.allowRated(g.variant, g.clock.map(_.config))) then g.copy(mode = chess.Mode.Casual) else g val userIds = g2.userIds.distinct @@ -402,9 +402,9 @@ final class GameRepo(val coll: Coll)(using Executor): .filterNot(_.isInitial) } val checkInHours = - if (g2.isPgnImport) none - else if (g2.fromApi) some(24 * 7) - else if (g2.hasClock) 1.some + if g2.isPgnImport then none + else if g2.fromApi then some(24 * 7) + else if g2.hasClock then 1.some else some(24 * 10) val bson = (gameBSONHandler write g2) ++ $doc( F.initialFen -> fen, @@ -438,10 +438,11 @@ final class GameRepo(val coll: Coll)(using Executor): coll.primitiveOne[Fen.Epd]($id(gameId), F.initialFen) def initialFen(game: Game): Fu[Option[Fen.Epd]] = - if (game.imported || !game.variant.standardInitialPosition) initialFen(game.id) dmap { - case None if game.variant == chess.variant.Chess960 => Fen.initial.some - case fen => fen - } + if game.imported || !game.variant.standardInitialPosition then + initialFen(game.id) dmap { + case None if game.variant == chess.variant.Chess960 => Fen.initial.some + case fen => fen + } else fuccess(none) def gameWithInitialFen(gameId: GameId): Fu[Option[Game.WithInitialFen]] = diff --git a/modules/game/src/main/GamesByIdsStream.scala b/modules/game/src/main/GamesByIdsStream.scala index 58bf8080a2574..08337a5929f65 100644 --- a/modules/game/src/main/GamesByIdsStream.scala +++ b/modules/game/src/main/GamesByIdsStream.scala @@ -46,5 +46,5 @@ final class GamesByIdsStream(gameRepo: lila.game.GameRepo)(using private def streamChan(streamId: String) = s"gamesByIdsStream:$streamId" private def gameSource(ids: Set[GameId]) = - if (ids.isEmpty) Source.empty[Game] + if ids.isEmpty then Source.empty[Game] else gameRepo.cursor($inIds(ids)).documentSource().throttle(50, 1.second) diff --git a/modules/game/src/main/GamesByUsersStream.scala b/modules/game/src/main/GamesByUsersStream.scala index 4968e57857242..c233d58e328f7 100644 --- a/modules/game/src/main/GamesByUsersStream.scala +++ b/modules/game/src/main/GamesByUsersStream.scala @@ -16,7 +16,7 @@ final class GamesByUsersStream(gameRepo: lila.game.GameRepo)(using private val chans = List("startGame", "finishGame") def apply(userIds: Set[UserId], withCurrentGames: Boolean): Source[JsValue, ?] = - val initialGames = if (withCurrentGames) currentGamesSource(userIds) else Source.empty + val initialGames = if withCurrentGames then currentGamesSource(userIds) else Source.empty val startStream = Source.queue[Game](150, akka.stream.OverflowStrategy.dropHead) mapMaterializedValue { queue => def matches(game: Game) = diff --git a/modules/game/src/main/GifExport.scala b/modules/game/src/main/GifExport.scala index dbc5f501513d9..70cc4231b2e77 100644 --- a/modules/game/src/main/GifExport.scala +++ b/modules/game/src/main/GifExport.scala @@ -112,7 +112,7 @@ final class GifExport( case Some(median) => val scale = targetMedianTime.centis.toFloat / median.centis.atLeast(1).toFloat moveTimes.map { t => - if (t * 2 < median) t atMost (targetMedianTime *~ 0.5) + if t * 2 < median then t atMost (targetMedianTime *~ 0.5) else t *~ scale atLeast (targetMedianTime *~ 0.5) atMost targetMaxTime } case None => moveTimes.map(_ atMost targetMaxTime) @@ -139,7 +139,7 @@ final class GifExport( arr case ((game, uci), scaledMoveTime) :: tail => // longer delay for last frame - val delay = if (tail.isEmpty) Centis(500).some else scaledMoveTime + val delay = if tail.isEmpty then Centis(500).some else scaledMoveTime framesRec(tail, arr :+ frame(game.situation, uci, delay)) private def frame(situation: Situation, uci: Option[Uci], delay: Option[Centis]) = diff --git a/modules/game/src/main/IdGenerator.scala b/modules/game/src/main/IdGenerator.scala index 8c8ceb6cab14b..5d4fc3ca6b319 100644 --- a/modules/game/src/main/IdGenerator.scala +++ b/modules/game/src/main/IdGenerator.scala @@ -17,9 +17,9 @@ final class IdGenerator(gameRepo: GameRepo)(using Executor): } def games(nb: Int): Fu[Set[GameId]] = - if (nb < 1) fuccess(Set.empty) - else if (nb == 1) game.dmap(Set(_)) - else if (nb < 5) Set.fill(nb)(game).parallel + if nb < 1 then fuccess(Set.empty) + else if nb == 1 then game.dmap(Set(_)) + else if nb < 5 then Set.fill(nb)(game).parallel else val ids = Set.fill(nb)(uncheckedGame) gameRepo.coll.distinctEasy[GameId, Set]("_id", $inIds(ids)) flatMap { collisions => diff --git a/modules/game/src/main/PgnDump.scala b/modules/game/src/main/PgnDump.scala index 02f4f20a69a61..2789373faefaa 100644 --- a/modules/game/src/main/PgnDump.scala +++ b/modules/game/src/main/PgnDump.scala @@ -76,7 +76,7 @@ final class PgnDump( private def ratingDiffTag(p: Player, tag: Tag.type => TagType) = p.ratingDiff.map { rd => - Tag(tag(Tag), s"${if (rd >= 0) "+" else ""}$rd") + Tag(tag(Tag), s"${if rd >= 0 then "+" else ""}$rd") } def tags( @@ -94,7 +94,7 @@ final class PgnDump( List[Option[Tag]]( Tag( _.Event, - imported.flatMap(_.tags(_.Event)) | { if (game.imported) "Import" else eventOf(game) } + imported.flatMap(_.tags(_.Event)) | { if game.imported then "Import" else eventOf(game) } ).some, Tag(_.Site, imported.flatMap(_.tags(_.Site)) | gameUrl(game.id)).some, Tag(_.Date, importedDate | Tag.UTCDate.format.print(game.createdAt)).some, diff --git a/modules/game/src/main/PgnStorage.scala b/modules/game/src/main/PgnStorage.scala index 060c2654e3641..f3e05e270a03d 100644 --- a/modules/game/src/main/PgnStorage.scala +++ b/modules/game/src/main/PgnStorage.scala @@ -36,13 +36,11 @@ private object PgnStorage: def decode(bytes: ByteArray, plies: Ply, id: GameId): Decoded = monitor(_.game.pgn.decode("huffman")) { val decoded = - try { - Encoder.decode(bytes.value, plies.value) - } catch { + try Encoder.decode(bytes.value, plies.value) + catch case e: java.nio.BufferUnderflowException => logger.error(s"Can't decode game $id PGN", e) throw e - } val unmovedRooks = decoded.unmovedRooks.asScala.view.map(Square(_)).toSet Decoded( sans = SanStr from decoded.pgnMoves.toVector, diff --git a/modules/game/src/main/Pov.scala b/modules/game/src/main/Pov.scala index 0b34bb43920db..954a15fc0ca23 100644 --- a/modules/game/src/main/Pov.scala +++ b/modules/game/src/main/Pov.scala @@ -78,14 +78,14 @@ object Pov: private def isFresher(a: Pov, b: Pov) = a.game.movedAt isAfter b.game.movedAt def priority(a: Pov, b: Pov) = - if (!a.isMyTurn && !b.isMyTurn) isFresher(a, b) - else if (!a.isMyTurn && b.isMyTurn) false - else if (a.isMyTurn && !b.isMyTurn) true + if !a.isMyTurn && !b.isMyTurn then isFresher(a, b) + else if !a.isMyTurn && b.isMyTurn then false + else if a.isMyTurn && !b.isMyTurn then true // first move has priority over games with more than 30s left - else if (orInf(a.remainingSeconds) < 30 && orInf(b.remainingSeconds) > 30) true - else if (orInf(b.remainingSeconds) < 30 && orInf(a.remainingSeconds) > 30) false - else if (!a.hasMoved && b.hasMoved) true - else if (!b.hasMoved && a.hasMoved) false + else if orInf(a.remainingSeconds) < 30 && orInf(b.remainingSeconds) > 30 then true + else if orInf(b.remainingSeconds) < 30 && orInf(a.remainingSeconds) > 30 then false + else if !a.hasMoved && b.hasMoved then true + else if !b.hasMoved && a.hasMoved then false else orInf(a.remainingSeconds) < orInf(b.remainingSeconds) case class PovRef(gameId: GameId, color: Color): diff --git a/modules/game/src/main/Query.scala b/modules/game/src/main/Query.scala index cfc6936bbfaeb..a46cded2d40fc 100644 --- a/modules/game/src/main/Query.scala +++ b/modules/game/src/main/Query.scala @@ -33,7 +33,7 @@ object Query: val notFinished: Bdoc = F.status $lte Status.Started.id def analysed(an: Boolean): Bdoc = - if (an) F.analysed $eq true + if an then F.analysed $eq true else F.analysed $ne true val frozen: Bdoc = F.status $gte Status.Mate.id @@ -112,7 +112,7 @@ object Query: def checkableOld = F.checkAt $lt nowInstant.minusHours(1) def variant(v: chess.variant.Variant) = - $doc(F.variant -> (if (v.standard) $exists(false) else $int(v.id))) + $doc(F.variant -> (if v.standard then $exists(false) else $int(v.id))) lazy val variantStandard = variant(chess.variant.Standard) diff --git a/modules/game/src/main/UciMemo.scala b/modules/game/src/main/UciMemo.scala index 5c3db25fedba1..4449320f31e66 100644 --- a/modules/game/src/main/UciMemo.scala +++ b/modules/game/src/main/UciMemo.scala @@ -38,7 +38,7 @@ final class UciMemo(gameRepo: GameRepo)(using Executor): } private def compute(game: Game, max: Int): Fu[UciVector] = - for { + for fen <- gameRepo initialFen game uciMoves <- UciDump(game.sans take max, fen, game.variant, force960Notation = true).toFuture - } yield uciMoves.toVector + yield uciMoves.toVector diff --git a/modules/game/src/test/BinaryCLMTest.scala b/modules/game/src/test/BinaryCLMTest.scala index ef78c9a6d2ca7..d80ad1d9eace8 100644 --- a/modules/game/src/test/BinaryCLMTest.scala +++ b/modules/game/src/test/BinaryCLMTest.scala @@ -1,11 +1,11 @@ package lila.game -import chess._ +import chess.* import chess.format.Uci import lila.db.ByteArray -class BinaryCLMTest extends munit.FunSuite { +class BinaryCLMTest extends munit.FunSuite: val _0_ = "00000000" def write(all: CastleLastMove): List[String] = @@ -52,4 +52,3 @@ class BinaryCLMTest extends munit.FunSuite { // check from old format ignored assertEquals(read("11110000" :: _0_ :: "00000001" :: "10000110" :: "10011111" :: "00111111" :: Nil), clmt) } -} diff --git a/modules/game/src/test/BinaryClockTest.scala b/modules/game/src/test/BinaryClockTest.scala index 130549f2ccea6..d94cbfa50cb74 100644 --- a/modules/game/src/test/BinaryClockTest.scala +++ b/modules/game/src/test/BinaryClockTest.scala @@ -1,12 +1,12 @@ package lila.game import chess.{ Centis, Clock, White } -import scala.util.chaining._ +import scala.util.chaining.* import lila.db.ByteArray import lila.common.Maths -class BinaryClockTest extends munit.FunSuite { +class BinaryClockTest extends munit.FunSuite: val _0_ = "00000000" val since = nowInstant.minusHours(1) @@ -88,4 +88,3 @@ class BinaryClockTest extends munit.FunSuite { val b3 = Clock(60, 2).goBerserk(White) assertEquals(readBytes(writeBytes(b3), true), b3) } -} diff --git a/modules/game/src/test/BinaryMoveTimeTest.scala b/modules/game/src/test/BinaryMoveTimeTest.scala index c65546f9c6ea7..9df9d1afef142 100644 --- a/modules/game/src/test/BinaryMoveTimeTest.scala +++ b/modules/game/src/test/BinaryMoveTimeTest.scala @@ -5,7 +5,7 @@ import scala.language.implicitConversions import lila.db.ByteArray import chess.{ Ply, Centis } -class BinaryMoveTimeTest extends munit.FunSuite { +class BinaryMoveTimeTest extends munit.FunSuite: private given Conversion[Int, Ply] = Ply(_) @@ -53,4 +53,3 @@ class BinaryMoveTimeTest extends munit.FunSuite { val again = BinaryFormat.moveTime.read(BinaryFormat.moveTime.write(rounded), 3) assertEquals(again, rounded) } -} diff --git a/modules/game/src/test/BinaryPieceTest.scala b/modules/game/src/test/BinaryPieceTest.scala index e4f28830b7c45..269c8a7a4ee42 100644 --- a/modules/game/src/test/BinaryPieceTest.scala +++ b/modules/game/src/test/BinaryPieceTest.scala @@ -6,7 +6,7 @@ import chess.Square.* import lila.db.ByteArray import chess.variant.Standard -class BinaryPieceTest extends munit.FunSuite { +class BinaryPieceTest extends munit.FunSuite: val noop = "00000000" def write(all: PieceMap): List[String] = @@ -50,4 +50,3 @@ class BinaryPieceTest extends munit.FunSuite { test("read B1 black pawn") { assertEquals(read("00001110" :: List.fill(31)(noop)), Map(B1 -> Black.pawn)) } -} diff --git a/modules/game/src/test/BinaryUnmovedRooksTest.scala b/modules/game/src/test/BinaryUnmovedRooksTest.scala index dcd0ef4f68649..b8daeed7643df 100644 --- a/modules/game/src/test/BinaryUnmovedRooksTest.scala +++ b/modules/game/src/test/BinaryUnmovedRooksTest.scala @@ -1,11 +1,11 @@ package lila.game -import chess._ -import chess.Square._ +import chess.* +import chess.Square.* import lila.db.ByteArray -class BinaryUnmovedRooksTest extends munit.FunSuite { +class BinaryUnmovedRooksTest extends munit.FunSuite: val _0_ = "00000000" val _1_ = "11111111" @@ -28,4 +28,3 @@ class BinaryUnmovedRooksTest extends munit.FunSuite { assertEquals(read(List("11100000", _0_)), UnmovedRooks(Set(A1, B1, C1))) assertEquals(read(List(_0_, "11100000")), UnmovedRooks(Set(A8, B8, C8))) } -} diff --git a/modules/gameSearch/src/main/GameSearchApi.scala b/modules/gameSearch/src/main/GameSearchApi.scala index efb71bc0fa1ec..6ad518fd825bd 100644 --- a/modules/gameSearch/src/main/GameSearchApi.scala +++ b/modules/gameSearch/src/main/GameSearchApi.scala @@ -41,11 +41,11 @@ final class GameSearchApi( private def toDoc(game: Game, analysed: Boolean) = Json .obj( - Fields.status -> (game.status match { + Fields.status -> (game.status match case s if s.is(_.Timeout) => chess.Status.Resign case s if s.is(_.NoStart) => chess.Status.Resign case _ => game.status - }).id, + ).id, Fields.turns -> (game.ply.value + 1) / 2, Fields.rated -> game.rated, Fields.perf -> game.perfType.id, diff --git a/modules/gathering/src/main/GatheringClock.scala b/modules/gathering/src/main/GatheringClock.scala index 6451889657aee..58a6e47065f85 100644 --- a/modules/gathering/src/main/GatheringClock.scala +++ b/modules/gathering/src/main/GatheringClock.scala @@ -12,7 +12,7 @@ object GatheringClock: val timeDefault = 2d private def formatLimit(l: Double) = Clock.Config(LimitSeconds((l * 60).toInt), IncrementSeconds(0)).limitString + { - if (l <= 1) " minute" else " minutes" + if l <= 1 then " minute" else " minutes" } val timeChoices = optionsDouble(times, formatLimit) diff --git a/modules/hub/src/main/AsyncActor.scala b/modules/hub/src/main/AsyncActor.scala index 8fb70ddb49767..2acb6c4527c07 100644 --- a/modules/hub/src/main/AsyncActor.scala +++ b/modules/hub/src/main/AsyncActor.scala @@ -16,7 +16,7 @@ abstract class AsyncActor(using Executor) extends lila.common.Tellable: protected val process: ReceiveAsync def !(msg: Matchable): Unit = - if (stateRef.getAndUpdate(state => Some(state.fold(Queue.empty[Matchable])(_ enqueue msg))).isEmpty) + if stateRef.getAndUpdate(state => Some(state.fold(Queue.empty[Matchable])(_ enqueue msg))).isEmpty then run(msg) def ask[A](makeMsg: Promise[A] => Matchable): Fu[A] = @@ -46,10 +46,9 @@ object AsyncActor: private val postRunUpdate = new UnaryOperator[State]: override def apply(state: State): State = state flatMap { q => - if (q.isEmpty) None else Some(q.tail) + if q.isEmpty then None else Some(q.tail) } - private val fallback = { (msg: Matchable) => + private val fallback = (msg: Matchable) => lila.log("asyncActor").warn(s"unhandled msg: $msg") funit - } diff --git a/modules/hub/src/main/AsyncActorConcMap.scala b/modules/hub/src/main/AsyncActorConcMap.scala index cfcda27368a6c..9e783e0853ce4 100644 --- a/modules/hub/src/main/AsyncActorConcMap.scala +++ b/modules/hub/src/main/AsyncActorConcMap.scala @@ -60,10 +60,9 @@ final class AsyncActorConcMap[Id, D <: AsyncActor]( asyncActors .computeIfPresent( id, - (_, d) => { + (_, d) => lastWill(d) nullD - } ) .unit diff --git a/modules/hub/src/main/BoundedAsyncActor.scala b/modules/hub/src/main/BoundedAsyncActor.scala index 76677653a6628..982778c2d7b48 100644 --- a/modules/hub/src/main/BoundedAsyncActor.scala +++ b/modules/hub/src/main/BoundedAsyncActor.scala @@ -19,7 +19,7 @@ final class BoundedAsyncActor(maxSize: Max, name: String, logging: Boolean = tru stateRef.getAndUpdate { state => Some { state.fold(emptyQueue) { q => - if (q.size >= maxSize.value) q + if q.size >= maxSize.value then q else q enqueue msg } } @@ -29,17 +29,16 @@ final class BoundedAsyncActor(maxSize: Max, name: String, logging: Boolean = tru true case Some(q) => val success = q.size < maxSize.value - if (!success) + if !success then lila.mon.asyncActor.overflow(name).increment() - if (logging) lila.log("asyncActor").warn(s"[$name] queue is full ($maxSize)") - else if (logging && q.size >= monitorQueueSize) - lila.mon.asyncActor.queueSize(name).record(q.size) + if logging then lila.log("asyncActor").warn(s"[$name] queue is full ($maxSize)") + else if logging && q.size >= monitorQueueSize then lila.mon.asyncActor.queueSize(name).record(q.size) success def ask[A](makeMsg: Promise[A] => Matchable): Fu[A] = val promise = Promise[A]() val success = this ! makeMsg(promise) - if (!success) promise failure new EnqueueException(s"The $name asyncActor queue is full ($maxSize)") + if !success then promise failure new EnqueueException(s"The $name asyncActor queue is full ($maxSize)") promise.future def queueSize = stateRef.get().fold(0)(_.size + 1) @@ -59,10 +58,9 @@ final class BoundedAsyncActor(maxSize: Max, name: String, logging: Boolean = tru private[this] val postRun = (_: Matchable) => stateRef.getAndUpdate(postRunUpdate) flatMap (_.headOption) foreach run - private[this] lazy val fallback = { (msg: Any) => + private[this] lazy val fallback = (msg: Any) => lila.log("asyncActor").warn(s"[$name] unhandled msg: $msg") funit - } object BoundedAsyncActor: diff --git a/modules/hub/src/main/SyncActor.scala b/modules/hub/src/main/SyncActor.scala index c4123f0961ce4..abe88aeee4f7e 100644 --- a/modules/hub/src/main/SyncActor.scala +++ b/modules/hub/src/main/SyncActor.scala @@ -24,12 +24,10 @@ abstract class SyncActor(using Executor) extends lila.common.Tellable: isAlive = false def !(msg: Matchable): Unit = - if ( - isAlive && stateRef + if isAlive && stateRef .getAndUpdate(state => Some(state.fold(Queue.empty[Matchable])(_ enqueue msg))) .isEmpty - ) - run(msg) + then run(msg) def ask[A](makeMsg: Promise[A] => Matchable): Fu[A] = val promise = Promise[A]() @@ -66,7 +64,7 @@ object SyncActor: private val postRunUpdate = new UnaryOperator[State]: override def apply(state: State): State = state flatMap { q => - if (q.isEmpty) None else Some(q.tail) + if q.isEmpty then None else Some(q.tail) } def stub(using Executor) = diff --git a/modules/i18n/src/main/I18nQuantity.scala b/modules/i18n/src/main/I18nQuantity.scala index 8bc625351282e..8afaa9924cfea 100644 --- a/modules/i18n/src/main/I18nQuantity.scala +++ b/modules/i18n/src/main/I18nQuantity.scala @@ -23,88 +23,88 @@ private object I18nQuantity: private object selectors: def default(c: Count) = - if (c == 1) One + if c == 1 then One else Other def french(c: Count) = - if (c <= 1) One + if c <= 1 then One else Other def czech(c: Count) = - if (c == 1) One - else if (c >= 2 && c <= 4) Few + if c == 1 then One + else if c >= 2 && c <= 4 then Few else Other def balkan(c: Count) = val rem100 = c % 100 val rem10 = c % 10 - if (rem10 == 1 && rem100 != 11) One - else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) Few - else if (rem10 == 0 || (rem10 >= 5 && rem10 <= 9) || (rem100 >= 11 && rem100 <= 14)) Many + if rem10 == 1 && rem100 != 11 then One + else if rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14) then Few + else if rem10 == 0 || (rem10 >= 5 && rem10 <= 9) || (rem100 >= 11 && rem100 <= 14) then Many else Other def latvian(c: Count) = - if (c == 0) Zero - else if (c % 10 == 1 && c % 100 != 11) One + if c == 0 then Zero + else if c % 10 == 1 && c % 100 != 11 then One else Other def lithuanian(c: Count) = val rem100 = c % 100 val rem10 = c % 10 - if (rem10 == 1 && !(rem100 >= 11 && rem100 <= 19)) One - else if (rem10 >= 2 && rem10 <= 9 && !(rem100 >= 11 && rem100 <= 19)) Few + if rem10 == 1 && !(rem100 >= 11 && rem100 <= 19) then One + else if rem10 >= 2 && rem10 <= 9 && !(rem100 >= 11 && rem100 <= 19) then Few else Other def polish(c: Count) = val rem100 = c % 100 val rem10 = c % 10 - if (c == 1) One - else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) Few + if c == 1 then One + else if rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14) then Few else Other def romanian(c: Count) = val rem100 = c % 100 - if (c == 1) One - else if (c == 0 || (rem100 >= 1 && rem100 <= 19)) Few + if c == 1 then One + else if c == 0 || (rem100 >= 1 && rem100 <= 19) then Few else Other def slovenian(c: Count) = val rem100 = c % 100 - if (rem100 == 1) One - else if (rem100 == 2) Two - else if (rem100 >= 3 && rem100 <= 4) Few + if rem100 == 1 then One + else if rem100 == 2 then Two + else if rem100 >= 3 && rem100 <= 4 then Few else Other def arabic(c: Count) = val rem100 = c % 100 - if (c == 0) Zero - else if (c == 1) One - else if (c == 2) Two - else if (rem100 >= 3 && rem100 <= 10) Few - else if (rem100 >= 11 && rem100 <= 99) Many + if c == 0 then Zero + else if c == 1 then One + else if c == 2 then Two + else if rem100 >= 3 && rem100 <= 10 then Few + else if rem100 >= 11 && rem100 <= 99 then Many else Other def macedonian(c: Count) = - if (c % 10 == 1 && c != 11) One else Other + if c % 10 == 1 && c != 11 then One else Other def welsh(c: Count) = - if (c == 0) Zero - else if (c == 1) One - else if (c == 2) Two - else if (c == 3) Few - else if (c == 6) Many + if c == 0 then Zero + else if c == 1 then One + else if c == 2 then Two + else if c == 3 then Few + else if c == 6 then Many else Other def maltese(c: Count) = val rem100 = c % 100 - if (c == 1) One - else if (c == 0 || (rem100 >= 2 && rem100 <= 10)) Few - else if (rem100 >= 11 && rem100 <= 19) Many + if c == 1 then One + else if c == 0 || (rem100 >= 2 && rem100 <= 10) then Few + else if rem100 >= 11 && rem100 <= 19 then Many else Other def two(c: Count) = - if (c == 1) One - else if (c == 2) Two + if c == 1 then One + else if c == 2 then Two else Other def none(c: Count) = Other @@ -112,7 +112,7 @@ private object I18nQuantity: import selectors.* private val langMap: Map[Language, Selector] = LangList.all.map { (lang, _) => - lang.language -> lang.language.match { + lang.language -> lang.language.match case "fr" | "ff" | "kab" | "co" | "ak" | "am" | "bh" | "fil" | "tl" | "guw" | "hi" | "ln" | "mg" | "nso" | "ti" | "wa" => @@ -148,5 +148,4 @@ private object I18nQuantity: selectors.none case _ => default - } } diff --git a/modules/i18n/src/main/JsDump.scala b/modules/i18n/src/main/JsDump.scala index 3cfff96042c74..9042c40797bcf 100644 --- a/modules/i18n/src/main/JsDump.scala +++ b/modules/i18n/src/main/JsDump.scala @@ -17,7 +17,7 @@ object JsDump: def removeDbPrefix(key: I18nKey): String = val index = key.value.indexOf(':') - if (index > 0) key.value.drop(index + 1) else key.value + if index > 0 then key.value.drop(index + 1) else key.value private def translatedJs(fullKey: I18nKey, t: Translation): JsTrans = val k = removeDbPrefix(fullKey) diff --git a/modules/i18n/src/main/Translation.scala b/modules/i18n/src/main/Translation.scala index 578c10853179f..e493f483d2d44 100644 --- a/modules/i18n/src/main/Translation.scala +++ b/modules/i18n/src/main/Translation.scala @@ -9,11 +9,11 @@ sealed private trait Translation final private class Simple(val message: String) extends Translation: def formatTxt(args: Seq[Any]): String = - if (args.isEmpty) message + if args.isEmpty then message else message.format(args*) def format(args: Seq[RawFrag]): RawFrag = - if (args.isEmpty) RawFrag(message) + if args.isEmpty then RawFrag(message) else RawFrag(message.format(args.map(_.v)*)) override def toString = s"Simple($message)" @@ -21,11 +21,11 @@ final private class Simple(val message: String) extends Translation: final private class Escaped(val message: String, escaped: String) extends Translation: def formatTxt(args: Seq[Any]): String = - if (args.isEmpty) message + if args.isEmpty then message else message.format(args*) def format(args: Seq[RawFrag]): RawFrag = - if (args.isEmpty) RawFrag(escaped) + if args.isEmpty then RawFrag(escaped) else RawFrag(escaped.format(args.map(_.v)*)) override def toString = s"Escaped($message)" @@ -40,14 +40,14 @@ final private class Plurals(val messages: Map[I18nQuantity, String]) extends Tra def formatTxt(quantity: I18nQuantity, args: Seq[Any]): Option[String] = messageFor(quantity).map { message => - if (args.isEmpty) message + if args.isEmpty then message else message.format(args*) } def format(quantity: I18nQuantity, args: Seq[RawFrag]): Option[RawFrag] = messageFor(quantity).map { message => val escaped = escapeHtml(Html(message)) - if (args.isEmpty) escaped + if args.isEmpty then escaped else RawFrag(escaped.v.format(args.map(_.v)*)) } diff --git a/modules/i18n/src/test/TranslationTest.scala b/modules/i18n/src/test/TranslationTest.scala index 25d9dd2d3ed5d..4646fa40d61cf 100644 --- a/modules/i18n/src/test/TranslationTest.scala +++ b/modules/i18n/src/test/TranslationTest.scala @@ -1,21 +1,20 @@ package lila.i18n -import scala.jdk.CollectionConverters._ +import scala.jdk.CollectionConverters.* import play.api.i18n.Lang -class TranslationTest extends munit.FunSuite { +class TranslationTest extends munit.FunSuite: test("be valid") { val en = Registry.all.get(defaultLang).get var tested = 0 val errors: List[String] = LangList.all.flatMap { (lang, name) => Registry.all.get(lang).get.asScala.toMap flatMap { (k, v) => - try { - val enTrans: String = en.get(k) match { + try + val enTrans: String = en.get(k) match case literal: Simple => literal.message case literal: Escaped => literal.message case plurals: Plurals => plurals.messages.getOrElse(I18nQuantity.Other, plurals.messages.head._2) - } val args = argsForKey(enTrans) v match case literal: Simple => @@ -30,10 +29,9 @@ class TranslationTest extends munit.FunSuite { assert(plurals.formatTxt(qty, args).nonEmpty) } None - } catch { + catch case _: MatchError => None // Extra translation case e: Exception => Some(s"${lang.code} $name $k -> $v - ${e.getMessage}") - } } }.toList println(s"$tested translations tested") @@ -66,10 +64,9 @@ Voir les link3 sur ce coup pour vous entraîner.""" } private def argsForKey(k: String): List[String] = - if (k contains "%s") List("arg1") - else if (k contains "%4$s") List("arg1", "arg2", "arg3", "arg4") - else if (k contains "%3$s") List("arg1", "arg2", "arg3") - else if (k contains "%2$s") List("arg1", "arg2") - else if (k contains "%1$s") List("arg1") + if k contains "%s" then List("arg1") + else if k contains "%4$s" then List("arg1", "arg2", "arg3", "arg4") + else if k contains "%3$s" then List("arg1", "arg2", "arg3") + else if k contains "%2$s" then List("arg1", "arg2") + else if k contains "%1$s" then List("arg1") else Nil -} diff --git a/modules/importer/src/main/ImporterForm.scala b/modules/importer/src/main/ImporterForm.scala index 0b1ac3fc2b72b..0bb7111e05b81 100644 --- a/modules/importer/src/main/ImporterForm.scala +++ b/modules/importer/src/main/ImporterForm.scala @@ -59,29 +59,27 @@ case class ImportData(pgn: PgnStr, analyse: Option[String]): val fromPosition = initBoard.nonEmpty && !parsed.tags.fen.exists(_.isInitial) val variant = { parsed.tags.variant | { - if (fromPosition) chess.variant.FromPosition + if fromPosition then chess.variant.FromPosition else chess.variant.Standard } - } match { + } match case chess.variant.Chess960 if !Chess960.isStartPosition(setup.board) => chess.variant.FromPosition case chess.variant.FromPosition if parsed.tags.fen.isEmpty => chess.variant.Standard case chess.variant.Standard if fromPosition => chess.variant.FromPosition case v => v - } val game = state.copy(situation = state.situation withVariant variant) val initialFen = parsed.tags.fen flatMap { Fen.readWithMoveNumber(variant, _) } map Fen.write - val status = parsed.tags(_.Termination).map(_.toLowerCase) match { + val status = parsed.tags(_.Termination).map(_.toLowerCase) match case Some("normal") => game.situation.status | Status.Resign case Some("abandoned") => Status.Aborted case Some("time forfeit") => Status.Outoftime case Some("rules infraction") => Status.Cheat case Some(txt) if txt contains "won on time" => Status.Outoftime case _ => Status.UnknownFinish - } val date = parsed.tags.anyDate diff --git a/modules/insight/src/main/AggregationClusters.scala b/modules/insight/src/main/AggregationClusters.scala index 1a59105570e73..bbf7fac00483d 100644 --- a/modules/insight/src/main/AggregationClusters.scala +++ b/modules/insight/src/main/AggregationClusters.scala @@ -7,18 +7,18 @@ object AggregationClusters: def apply[X](question: Question[X], aggDocs: List[Bdoc]): List[Cluster[X]] = postSort(question) { - if (InsightMetric isStacked question.metric) stacked(question, aggDocs) + if InsightMetric isStacked question.metric then stacked(question, aggDocs) else single(question, aggDocs) } private def single[X](question: Question[X], aggDocs: List[Bdoc]): List[Cluster[X]] = - for { + for doc <- aggDocs x <- getId[X](doc)(question.dimension.bson) value <- doc.double("v") nb <- doc.int("nb") ids = ~doc.getAsOpt[List[String]]("ids") - } yield Cluster(x, Insight.Single(Point(value)), nb, ids) + yield Cluster(x, Insight.Single(Point(value)), nb, ids) private def getId[X](doc: Bdoc)(reader: BSONReader[X]): Option[X] = doc.get("_id") flatMap reader.readOpt @@ -27,7 +27,7 @@ object AggregationClusters: private given BSONDocumentReader[StackEntry] = Macros.reader private def stacked[X](question: Question[X], aggDocs: List[Bdoc]): List[Cluster[X]] = - for { + for doc <- aggDocs metricValues = InsightMetric valuesOf question.metric x <- getId[X](doc)(question.dimension.bson) @@ -37,13 +37,13 @@ object AggregationClusters: } total = stack.map(_.v.toInt.get).sum percents = - if (total == 0) points + if total == 0 then points else points.map { case (n, p) => n -> Point(100 * p.value / total) } ids = ~doc.getAsOpt[List[String]]("ids") - } yield Cluster(x, Insight.Stacked(percents.toList), total, ids) + yield Cluster(x, Insight.Stacked(percents.toList), total, ids) private def postSort[X](q: Question[X])(clusters: List[Cluster[X]]): List[Cluster[X]] = q.dimension match diff --git a/modules/insight/src/main/AggregationPipeline.scala b/modules/insight/src/main/AggregationPipeline.scala index 9780133b0f438..0f49d0e112b35 100644 --- a/modules/insight/src/main/AggregationPipeline.scala +++ b/modules/insight/src/main/AggregationPipeline.scala @@ -113,7 +113,7 @@ final private class AggregationPipeline(store: InsightStorage)(using (acc, mat) => $doc( "$cond" -> $arr( - $doc((if (mat.negative) "$lt" else "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)), + $doc((if mat.negative then "$lt" else "$lte") -> $arr("$" + F.moves("i"), mat.imbalance)), mat.id, acc ) @@ -169,7 +169,7 @@ final private class AggregationPipeline(store: InsightStorage)(using val bsonRatioToPercent = $doc("v" -> $divide("$v", ratioBsonMultiplier / 100)) def group(d: InsightDimension[?], f: GroupFunction): List[Option[PipelineOperator]] = - List(dimensionGrouping(d) match { + List(dimensionGrouping(d) match case Grouping.Group => groupOptions(dimensionGroupId(d))( "v" -> f.some, @@ -182,7 +182,7 @@ final private class AggregationPipeline(store: InsightStorage)(using "nb" -> SumAll.some, "ids" -> addGameId ) - }) map some + ) map some def groupMulti(d: InsightDimension[?], metricDbKey: String): List[Option[PipelineOperator]] = dimensionGrouping(d) ap { diff --git a/modules/insight/src/main/BSONHandlers.scala b/modules/insight/src/main/BSONHandlers.scala index 8316e774e897e..4824c90bdc99b 100644 --- a/modules/insight/src/main/BSONHandlers.scala +++ b/modules/insight/src/main/BSONHandlers.scala @@ -36,7 +36,7 @@ object BSONHandlers: private val BSONBooleanNullHandler = quickHandler[Boolean]( { case BSONBoolean(v) => v; case BSONNull => false }, - v => if (v) BSONBoolean(true) else BSONNull + v => if v then BSONBoolean(true) else BSONNull ) given BSONHandler[TimeVariance] = BSONIntegerHandler.as[TimeVariance]( diff --git a/modules/insight/src/main/Chart.scala b/modules/insight/src/main/Chart.scala index b9f4225206e97..03027e5b8da46 100644 --- a/modules/insight/src/main/Chart.scala +++ b/modules/insight/src/main/Chart.scala @@ -65,7 +65,7 @@ object Chart: val key = metric.name acc.updated( key, - acc.get(key) match { + acc.get(key) match case None => Serie( name = metric.name, @@ -74,14 +74,13 @@ object Chart: data = List(point.value) ) case Some(s) => s.copy(data = point.value :: s.data) - } ) case Insight.Stacked(points) => points.foldLeft(acc) { case (acc, (metricValueName, point)) => val key = s"${metric.name}/${metricValueName}" acc.updated( key, - acc.get(key) match { + acc.get(key) match case None => Serie( name = metricValueName.value, @@ -90,7 +89,6 @@ object Chart: data = List(point.value) ) case Some(s) => s.copy(data = point.value :: s.data) - } ) } } @@ -115,10 +113,10 @@ object Chart: } povs.map { pov => - for { + for user1 <- gameUserJson(pov.player) user2 <- gameUserJson(pov.opponent) - } yield Json.obj( + yield Json.obj( "id" -> pov.gameId, "fen" -> (chess.format.Fen writeBoard pov.game.board), "color" -> pov.player.color.name, diff --git a/modules/insight/src/main/Gaussian.scala b/modules/insight/src/main/Gaussian.scala index 9e942a44b99d5..46b0f390e1fa2 100644 --- a/modules/insight/src/main/Gaussian.scala +++ b/modules/insight/src/main/Gaussian.scala @@ -15,12 +15,11 @@ final class Gaussian(mu: Double, sigma: Double): * @return * x s.t. cdf(x) = numYes */ - def inverseCdf(p: Double): Double = { + def inverseCdf(p: Double): Double = require(p >= 0) require(p <= 1) mu + sigma * sqrt2 * erfInv(2 * p - 1) - } /** Computes the cumulative density function of the value x. */ diff --git a/modules/insight/src/main/InsightDimension.scala b/modules/insight/src/main/InsightDimension.scala index 5435294953345..562c15f214f03 100644 --- a/modules/insight/src/main/InsightDimension.scala +++ b/modules/insight/src/main/InsightDimension.scala @@ -292,7 +292,7 @@ object InsightDimension: ) def valueKey[X](d: InsightDimension[X])(v: X): String = - (d match { + (d match case Date => v.toString case Period => v.days.toString case Perf => v.key @@ -315,7 +315,7 @@ object InsightDimension: case ClockPercentRange => v.bottom.toInt case Blur => v.id case TimeVariance => v.id - }).toString + ).toString def valueJson[X](d: InsightDimension[X])(v: X)(using lang: Lang): JsValue = d match @@ -376,11 +376,9 @@ object InsightDimension: $doc( "$or" -> many.map { range => val intRange = lila.insight.MaterialRange.toRange(range) - if (intRange._1 == intRange._2) $doc(d.dbKey -> intRange._1) - else if (range.negative) - $doc(d.dbKey $gte intRange._1 $lt intRange._2) - else - $doc(d.dbKey $gt intRange._1 $lte intRange._2) + if intRange._1 == intRange._2 then $doc(d.dbKey -> intRange._1) + else if range.negative then $doc(d.dbKey $gte intRange._1 $lt intRange._2) + else $doc(d.dbKey $gt intRange._1 $lte intRange._2) } ) case InsightDimension.EvalRange => @@ -390,10 +388,8 @@ object InsightDimension: $doc( "$or" -> many.map { range => val intRange = lila.insight.EvalRange.toRange(range) - if (range.eval < 0) - $doc(d.dbKey $gte intRange._1 $lt intRange._2) - else - $doc(d.dbKey $gt intRange._1 $lte intRange._2) + if range.eval < 0 then $doc(d.dbKey $gte intRange._1 $lt intRange._2) + else $doc(d.dbKey $gt intRange._1 $lte intRange._2) } ) case InsightDimension.WinPercentRange => diff --git a/modules/insight/src/main/InsightIndexer.scala b/modules/insight/src/main/InsightIndexer.scala index c5943620a5045..dd48ac11aacc5 100644 --- a/modules/insight/src/main/InsightIndexer.scala +++ b/modules/insight/src/main/InsightIndexer.scala @@ -53,7 +53,7 @@ final private class InsightIndexer( private val maxGames = 10_000 private def fetchFirstGame(user: User): Fu[Option[Game]] = - if (user.count.rated == 0) fuccess(none) + if user.count.rated == 0 then fuccess(none) else { (user.count.rated >= maxGames) so gameRepo.coll diff --git a/modules/insight/src/main/InsightStorage.scala b/modules/insight/src/main/InsightStorage.scala index ea262eed5f055..2e8da044d3cba 100644 --- a/modules/insight/src/main/InsightStorage.scala +++ b/modules/insight/src/main/InsightStorage.scala @@ -67,10 +67,10 @@ final private class InsightStorage(val coll: AsyncColl)(using Executor): ) }.map { _.flatMap { doc => - for { + for perfType <- doc.getAsOpt[PerfType]("_id") nb <- doc.int("nb") - } yield perfType -> nb + yield perfType -> nb }.toMap } } diff --git a/modules/insight/src/main/JsonQuestion.scala b/modules/insight/src/main/JsonQuestion.scala index 269874a3b0f50..5c5a490aebcad 100644 --- a/modules/insight/src/main/JsonQuestion.scala +++ b/modules/insight/src/main/JsonQuestion.scala @@ -10,45 +10,43 @@ case class JsonQuestion( def question: Option[Question[?]] = import InsightDimension.* - for { + for realMetric <- InsightMetric.byKey get metric realFilters = filters - .flatMap { - case (filterKey, valueKeys) => { - def build[X](dimension: InsightDimension[X]) = - Filter[X]( - dimension, - valueKeys.flatMap { - InsightDimension.valueByKey(dimension, _) - } - ).some + .flatMap { case (filterKey, valueKeys) => + def build[X](dimension: InsightDimension[X]) = + Filter[X]( + dimension, + valueKeys.flatMap { + InsightDimension.valueByKey(dimension, _) + } + ).some - filterKey match - case Period.key => build(Period) - case Perf.key => build(Perf) - case Phase.key => build(Phase) - case Result.key => build(Result) - case Termination.key => build(Termination) - case Color.key => build(Color) - case OpeningFamily.key => build(OpeningFamily) - case OpeningVariation.key => build(OpeningVariation) - case OpponentStrength.key => build(OpponentStrength) - case PieceRole.key => build(PieceRole) - case MovetimeRange.key => build(MovetimeRange) - case MyCastling.key => build(MyCastling) - case OpCastling.key => build(OpCastling) - case QueenTrade.key => build(QueenTrade) - case MaterialRange.key => build(MaterialRange) - case CplRange.key => build(CplRange) - case AccuracyPercentRange.key => build(AccuracyPercentRange) - case EvalRange.key => build(EvalRange) - case WinPercentRange.key => build(WinPercentRange) - case ClockPercentRange.key => build(ClockPercentRange) - case Blur.key => build(Blur) - case TimeVariance.key => build(TimeVariance) - case _ => none - } + filterKey match + case Period.key => build(Period) + case Perf.key => build(Perf) + case Phase.key => build(Phase) + case Result.key => build(Result) + case Termination.key => build(Termination) + case Color.key => build(Color) + case OpeningFamily.key => build(OpeningFamily) + case OpeningVariation.key => build(OpeningVariation) + case OpponentStrength.key => build(OpponentStrength) + case PieceRole.key => build(PieceRole) + case MovetimeRange.key => build(MovetimeRange) + case MyCastling.key => build(MyCastling) + case OpCastling.key => build(OpCastling) + case QueenTrade.key => build(QueenTrade) + case MaterialRange.key => build(MaterialRange) + case CplRange.key => build(CplRange) + case AccuracyPercentRange.key => build(AccuracyPercentRange) + case EvalRange.key => build(EvalRange) + case WinPercentRange.key => build(WinPercentRange) + case ClockPercentRange.key => build(ClockPercentRange) + case Blur.key => build(Blur) + case TimeVariance.key => build(TimeVariance) + case _ => none } .filterNot(_.isEmpty) .toList @@ -78,7 +76,7 @@ case class JsonQuestion( case Blur.key => build(Blur) case TimeVariance.key => build(TimeVariance) case _ => none - } yield question + yield question object JsonQuestion: diff --git a/modules/insight/src/main/PovToEntry.scala b/modules/insight/src/main/PovToEntry.scala index 36de663613988..44dae3acfb669 100644 --- a/modules/insight/src/main/PovToEntry.scala +++ b/modules/insight/src/main/PovToEntry.scala @@ -33,14 +33,14 @@ final private class PovToEntry( (_ flatMap convert toRight game) private def removeWrongAnalysis(game: Game): Boolean = - if (game.metadata.analysed && !game.analysable) + if game.metadata.analysed && !game.analysable then gameRepo setUnanalysed game.id analysisRepo remove game.id.value true else false private def enrich(game: Game, userId: UserId, provisional: Boolean): Fu[Option[RichPov]] = - if (removeWrongAnalysis(game)) fuccess(none) + if removeWrongAnalysis(game) then fuccess(none) else lila.game.Pov(game, userId) so { pov => gameRepo.initialFen(game) zip @@ -91,7 +91,7 @@ final private class PovToEntry( } val roles = from.pov.game.sansOf(from.pov.color) map sanToRole val situations = - val pivot = if (from.pov.color == from.pov.game.startColor) 0 else 1 + val pivot = if from.pov.color == from.pov.game.startColor then 0 else 1 from.situations.toList.zipWithIndex.collect { case (e, i) if (i % 2) == pivot => e } @@ -124,7 +124,7 @@ final private class PovToEntry( } val accuracyPercent = accuracyPercents flatMap { accs => accs lift i orElse { - if (i == situations.size - 1) // last eval missing if checkmate + if i == situations.size - 1 then // last eval missing if checkmate ~from.pov.win && from.pov.game.status.is(_.Mate) option AccuracyPercent.perfect else none // evals can be missing in super long games (300 plies, used to be 200) } @@ -150,7 +150,7 @@ final private class PovToEntry( private def slidingMoveTimesCvs(movetimes: Vector[Centis]): Seq[Option[Float]] = val sliding = 13 // should be odd val nb = movetimes.size - if (nb < sliding) Vector.fill(nb)(none[Float]) + if nb < sliding then Vector.fill(nb)(none[Float]) else val sides = Vector.fill(sliding / 2)(none[Float]) val cvs = movetimes @@ -192,7 +192,7 @@ final private class PovToEntry( myCastling = Castling.fromMoves(game sansOf pov.color), rating = myRating, opponentRating = opRating, - opponentStrength = for { m <- myRating; o <- opRating } yield RelativeStrength(m, o), + opponentStrength = for m <- myRating; o <- opRating yield RelativeStrength(m, o), opponentCastling = Castling.fromMoves(game sansOf !pov.color), moves = makeMoves(from), queenTrade = queenTrade(from), diff --git a/modules/insight/src/main/TutorRange.scala b/modules/insight/src/main/TutorRange.scala index 75d6358347a98..cf23c03b8bbc0 100644 --- a/modules/insight/src/main/TutorRange.scala +++ b/modules/insight/src/main/TutorRange.scala @@ -53,7 +53,7 @@ object MaterialRange: def reversedButEqualAndLast = values.diff(List(Equal, Up4)).reverse val byId = values.mapBy(_.id) def toRange(mr: MaterialRange): (Int, Int) = - if (mr.id == Equal.id) (0, 0) + if mr.id == Equal.id then (0, 0) else ( byId.get(mr.id - 1).fold(Int.MinValue)(_.imbalance), @@ -72,7 +72,7 @@ object TimeVariance: def apply(v: Float) = values.find(_.id >= v) | VeryVariable val intFactor: Int = 100_000 // multiply variance by that to get an Int for storage def toRange(tv: TimeVariance): (Int, Int) = - if (tv == VeryVariable) (QuiteVariable.intFactored, Int.MaxValue) + if tv == VeryVariable then (QuiteVariable.intFactored, Int.MaxValue) else ( values.indexOption(tv).map(_ - 1).flatMap(values.lift).fold(0)(_.intFactored), @@ -83,7 +83,7 @@ final class CplRange(val name: String, val cpl: Int) object CplRange: val all = List(0, 10, 25, 50, 100, 200, 500, 99999).map { cpl => CplRange( - name = if (cpl == 0) "Perfect" else if (cpl == 99999) "> 500 CPL" else s"≤ $cpl CPL", + name = if cpl == 0 then "Perfect" else if cpl == 99999 then "> 500 CPL" else s"≤ $cpl CPL", cpl = cpl ) } diff --git a/modules/insight/src/main/model.scala b/modules/insight/src/main/model.scala index e4c30280a468f..9eb4951e855bf 100644 --- a/modules/insight/src/main/model.scala +++ b/modules/insight/src/main/model.scala @@ -117,10 +117,10 @@ enum QueenTrade(val id: Boolean, val name: String): case Yes extends QueenTrade(true, "Queen trade") case No extends QueenTrade(false, "No queen trade") object QueenTrade: - def apply(v: Boolean): QueenTrade = if (v) Yes else No + def apply(v: Boolean): QueenTrade = if v then Yes else No enum Blur(val id: Boolean, val name: String): case Yes extends Blur(true, "Blur") case No extends Blur(false, "No blur") object Blur: - def apply(v: Boolean): Blur = if (v) Yes else No + def apply(v: Boolean): Blur = if v then Yes else No diff --git a/modules/irc/src/main/IrcApi.scala b/modules/irc/src/main/IrcApi.scala index eb44585091f60..f0091e7213c93 100644 --- a/modules/irc/src/main/IrcApi.scala +++ b/modules/irc/src/main/IrcApi.scala @@ -65,7 +65,7 @@ final class IrcApi( def commlog(user: User, reportBy: Option[UserId])(using mod: Me): Funit = zulip(_.mod.adminLog, "private comms checks"): val checkedOut = - val finalS = if (user.username.value endsWith "s") "" else "s" + val finalS = if user.username.value endsWith "s" then "" else "s" s"**${markdown modLink mod.username}** checked out **${markdown userLink user.username}**'$finalS communications " checkedOut + reportBy .filterNot(_ is mod) @@ -79,7 +79,8 @@ final class IrcApi( def chatPanic(mod: Me, v: Boolean): Funit = val msg = - s":stop: ${markdown.modLink(mod.username)} ${if (v) "enabled" else "disabled"} ${markdown.lichessLink("/mod/chat-panic", " Chat Panic")}" + s":stop: ${markdown.modLink(mod.username)} ${if v then "enabled" else "disabled"} ${markdown + .lichessLink("/mod/chat-panic", " Chat Panic")}" zulip(_.mod.log, "chat panic")(msg) >> zulip(_.mod.commsPublic, "main")(msg) def broadcastError(id: RelayRoundId, name: String, error: String): Funit = @@ -158,7 +159,7 @@ final class IrcApi( zulip(_.general, "lila")(markdown.linkifyUsers(text)) private def userAt(username: UserName) = - if (username == UserName("Anonymous")) username + if username == UserName("Anonymous") then username else s"@$username" private def amount(cents: Int) = s"$$${BigDecimal(cents.toLong, 2)}" diff --git a/modules/irc/src/main/ZulipClient.scala b/modules/irc/src/main/ZulipClient.scala index 8cd61d3b61d80..eeb4cd6645b73 100644 --- a/modules/irc/src/main/ZulipClient.scala +++ b/modules/irc/src/main/ZulipClient.scala @@ -40,7 +40,7 @@ final private class ZulipClient(ws: StandaloneWSClient, config: ZulipClient.Conf } private def send(msg: ZulipMessage): Fu[Option[ZulipMessage.ID]] = dedupMsg(msg) so { - if (config.domain.isEmpty) fuccess(lila.log("zulip").info(msg.toString)) inject None + if config.domain.isEmpty then fuccess(lila.log("zulip").info(msg.toString)) inject None else ws .url(s"https://${config.domain}/api/v1/messages") diff --git a/modules/irwin/src/main/Env.scala b/modules/irwin/src/main/Env.scala index c8bd45df60a95..594fc46db45ff 100644 --- a/modules/irwin/src/main/Env.scala +++ b/modules/irwin/src/main/Env.scala @@ -42,7 +42,7 @@ final class Env( def mk = (coll: AsyncColl) => wire[KaladinApi] mk(insightDb(CollName("kaladin_queue"))) - if (appConfig.get[Boolean]("kaladin.enabled")) + if appConfig.get[Boolean]("kaladin.enabled") then scheduler.scheduleWithFixedDelay(5 minutes, 5 minutes): () => (for diff --git a/modules/irwin/src/main/IrwinApi.scala b/modules/irwin/src/main/IrwinApi.scala index 11be3e6c9dbcc..4fda1902b0a90 100644 --- a/modules/irwin/src/main/IrwinApi.scala +++ b/modules/irwin/src/main/IrwinApi.scala @@ -35,12 +35,12 @@ final class IrwinApi( object reports: - def insert(data: IrwinReport) = for { + def insert(data: IrwinReport) = for prev <- get(data.userId) report = prev.fold(data)(_ add data) _ <- reportColl.update.one($id(report._id), report, upsert = true) _ <- markOrReport(report) - } yield + yield notification(report) lila.mon.mod.irwin.ownerReport(report.owner).increment().unit @@ -66,21 +66,22 @@ final class IrwinApi( private def markOrReport(report: IrwinReport): Funit = userRepo.getTitle(report.suspectId.value) flatMap { title => - if (report.activation >= thresholds.get().mark && title.isEmpty) + if report.activation >= thresholds.get().mark && title.isEmpty then modApi.autoMark(report.suspectId, report.note)(using User.irwinId.into(Me.Id)) >>- lila.mon.mod.irwin.mark.increment().unit - else if (report.activation >= thresholds.get().report) for { - suspect <- getSuspect(report.suspectId.value) - irwin <- userRepo.irwin orFail s"Irwin user not found" dmap Mod.apply - _ <- reportApi.create( - Report.Candidate( - reporter = Reporter(irwin.user), - suspect = suspect, - reason = lila.report.Reason.Cheat, - text = s"${report.activation}% over ${report.games.size} games" + else if report.activation >= thresholds.get().report then + for + suspect <- getSuspect(report.suspectId.value) + irwin <- userRepo.irwin orFail s"Irwin user not found" dmap Mod.apply + _ <- reportApi.create( + Report.Candidate( + reporter = Reporter(irwin.user), + suspect = suspect, + reason = lila.report.Reason.Cheat, + text = s"${report.activation}% over ${report.games.size} games" + ) ) - ) - } yield lila.mon.mod.irwin.report.increment().unit + yield lila.mon.mod.irwin.report.increment().unit else funit } diff --git a/modules/irwin/src/main/KaladinApi.scala b/modules/irwin/src/main/KaladinApi.scala index fabbeac3abfbe..5c4fdec8d9457 100644 --- a/modules/irwin/src/main/KaladinApi.scala +++ b/modules/irwin/src/main/KaladinApi.scala @@ -105,7 +105,7 @@ final class KaladinApi( private def markOrReport(user: KaladinUser, pred: KaladinUser.Pred): Funit = - def sendReport = for { + def sendReport = for suspect <- getSuspect(user.suspectId.value) kaladin <- userRepo.kaladin orFail s"Kaladin user not found" dmap Mod.apply _ <- reportApi.create( @@ -117,16 +117,16 @@ final class KaladinApi( text = pred.note ) ) - } yield lila.mon.mod.kaladin.report.increment().unit + yield lila.mon.mod.kaladin.report.increment().unit - if (pred.percent >= thresholds.get().mark) + if pred.percent >= thresholds.get().mark then userRepo.hasTitle(user.id) flatMap { if _ then sendReport else modApi.autoMark(user.suspectId, pred.note)(using User.kaladinId.into(Me.Id)) >>- lila.mon.mod.kaladin.mark.increment().unit } - else if (pred.percent >= thresholds.get().report) sendReport + else if pred.percent >= thresholds.get().report then sendReport else funit object notification: @@ -166,8 +166,8 @@ final class KaladinApi( private val minMoves = 1050 private case class Counter(blitz: Int, rapid: Int): def add(nb: Int, speed: Speed) = - if (speed == Speed.Blitz) copy(blitz = blitz + nb) - else if (speed == Speed.Rapid) copy(rapid = rapid + nb) + if speed == Speed.Blitz then copy(blitz = blitz + nb) + else if speed == Speed.Rapid then copy(rapid = rapid + nb) else this def isEnough = blitz >= minMoves || rapid >= minMoves private val cache = cacheApi[UserId, Boolean](1024, "kaladin.hasEnoughRecentMoves") { diff --git a/modules/irwin/src/main/KaladinUser.scala b/modules/irwin/src/main/KaladinUser.scala index 49594d6ae2eb3..e1de60c7cddfe 100644 --- a/modules/irwin/src/main/KaladinUser.scala +++ b/modules/irwin/src/main/KaladinUser.scala @@ -20,12 +20,12 @@ case class KaladinUser( def recentlyQueued = queuedAt isAfter nowInstant.minusWeeks(1) def queueAgain(by: KaladinUser.Requester): Option[KaladinUser] = - if (startedAt.isEmpty && by.priority > priority) + if startedAt.isEmpty && by.priority > priority then copy( priority = by.priority, queuedBy = by ).some - else if (by.isMod || !recentlyQueued) + else if by.isMod || !recentlyQueued then copy( priority = by.priority, queuedAt = nowInstant, diff --git a/modules/lobby/src/main/Hook.scala b/modules/lobby/src/main/Hook.scala index 4b07123be7dbf..e4412628b2587 100644 --- a/modules/lobby/src/main/Hook.scala +++ b/modules/lobby/src/main/Hook.scala @@ -67,7 +67,7 @@ case class Hook( "perf" -> perfType.key, "t" -> clock.estimateTotalSeconds, "s" -> speed.id, - "i" -> (if (clock.incrementSeconds > 0) 1 else 0) + "i" -> (if clock.incrementSeconds > 0 then 1 else 0) ) .add("prov" -> perf.map(_.provisional)) .add("u" -> user.map(_.username)) diff --git a/modules/lobby/src/main/LobbySocket.scala b/modules/lobby/src/main/LobbySocket.scala index 6cec2e0064977..5608e4a437044 100644 --- a/modules/lobby/src/main/LobbySocket.scala +++ b/modules/lobby/src/main/LobbySocket.scala @@ -81,7 +81,7 @@ final class LobbySocket( case RemoveHook(hookId) => removedHookIds.append(hookId).unit case SendHookRemovals => - if (removedHookIds.nonEmpty) + if removedHookIds.nonEmpty then tellActiveHookSubscribers(makeMessage("hrm", removedHookIds.toString)) removedHookIds.clear() scheduler.scheduleOnce(1249 millis)(this ! SendHookRemovals).unit @@ -155,7 +155,11 @@ final class LobbySocket( def controller(member: Member): SocketController = case ("join", o) if !member.bot => - HookPoolLimit(member, cost = if (member.isAuth) 4 else 5, msg = s"join $o ${member.userId | "anon"}") { + HookPoolLimit( + member, + cost = if member.isAuth then 4 else 5, + msg = s"join $o ${member.userId | "anon"}" + ) { o str "d" foreach { id => lobby ! BiteHook(id, member.sri, member.user) } @@ -166,30 +170,30 @@ final class LobbySocket( } case ("joinSeek", o) if !member.bot => HookPoolLimit(member, cost = 5, msg = s"joinSeek $o") { - for { + for id <- o str "d" user <- member.user - } lobby ! BiteSeek(id, user) + do lobby ! BiteSeek(id, user) } case ("cancelSeek", o) => HookPoolLimit(member, cost = 1, msg = s"cancelSeek $o") { - for { + for id <- o str "d" user <- member.user - } lobby ! CancelSeek(id, user) + do lobby ! CancelSeek(id, user) } case ("idle", o) => actor ! SetIdle(member.sri, ~(o boolean "d")) // entering a pool case ("poolIn", o) if !member.bot => HookPoolLimit(member, cost = 1, msg = s"poolIn $o") { - for { + for user <- member.user d <- o obj "d" id <- d str "id" perfType <- poolApi.poolPerfTypes get PoolConfig.Id(id) ratingRange = d str "range" flatMap RatingRange.apply blocking = d.get[UserId]("blocking") - } yield + yield lobby ! CancelHook(member.sri) // in case there's one... perfsRepo.glicko(user.id, perfType) foreach { glicko => poolApi.join( @@ -291,12 +295,12 @@ private object LobbySocket: case _ => P.In.baseReader(raw) object Out: def pairings(pairings: List[PoolApi.Pairing]) = - val redirs = for { + val redirs = for pairing <- pairings color <- chess.Color.all sri = pairing sri color fullId = pairing.game fullIdOf color - } yield s"$sri:$fullId" + yield s"$sri:$fullId" s"lobby/pairings ${P.Out.commas(redirs)}" def tellLobby(payload: JsObject) = s"tell/lobby ${Json stringify payload}" def tellLobbyActive(payload: JsObject) = s"tell/lobby/active ${Json stringify payload}" diff --git a/modules/lobby/src/main/LobbySyncActor.scala b/modules/lobby/src/main/LobbySyncActor.scala index c0502d1856791..25e770342c259 100644 --- a/modules/lobby/src/main/LobbySyncActor.scala +++ b/modules/lobby/src/main/LobbySyncActor.scala @@ -160,7 +160,7 @@ final private class LobbySyncActor( private object recentlyAbortedUserIdPairs: private val cache = lila.memo.ExpireSetMemo[CacheKey](1 hour) private def makeKey(u1: UserId, u2: UserId) = CacheKey: - if (u1.value < u2.value) s"$u1/$u2" else s"$u2/$u1" + if u1.value < u2.value then s"$u1/$u2" else s"$u2/$u1" def register(g: Game) = for diff --git a/modules/lobby/src/main/MultiKeyMap.scala b/modules/lobby/src/main/MultiKeyMap.scala index fce9d676f771d..21b5e5c1528f4 100644 --- a/modules/lobby/src/main/MultiKeyMap.scala +++ b/modules/lobby/src/main/MultiKeyMap.scala @@ -40,7 +40,7 @@ final private class MultiKeyMap[K1, K2, V](index1: Map[K1, V], index2: Map[K2, V index2 = index2 -- k2s ) - def reset(newValues: Set[V]) = if (newValues == values) this else MultiKeyMap(newValues)(toK1, toK2) + def reset(newValues: Set[V]) = if newValues == values then this else MultiKeyMap(newValues)(toK1, toK2) private def copy(index1: Map[K1, V], index2: Map[K2, V]) = new MultiKeyMap(index1, index2)(toK1, toK2) diff --git a/modules/lobby/src/main/SeekApi.scala b/modules/lobby/src/main/SeekApi.scala index ae94e37654dcf..f64d0cc3fd9b2 100644 --- a/modules/lobby/src/main/SeekApi.scala +++ b/modules/lobby/src/main/SeekApi.scala @@ -59,7 +59,7 @@ final class SeekApi( case ((res, h), seek) if seek.user.id == user.id => (seek :: res, h) case ((res, h), seek) => val seekH = List(seek.variant, seek.daysPerTurn, seek.mode, seek.color, seek.user.id) mkString "," - if (h contains seekH) (res, h) + if h contains seekH then (res, h) else (seek :: res, h + seekH) } ._1 diff --git a/modules/mailer/src/main/AutomaticEmail.scala b/modules/mailer/src/main/AutomaticEmail.scala index 5a98d48decb1e..2aaca07401690 100644 --- a/modules/mailer/src/main/AutomaticEmail.scala +++ b/modules/mailer/src/main/AutomaticEmail.scala @@ -160,7 +160,7 @@ To make a new donation, head to $baseUrl/patron""" userRepo.pair(from, to) map { _.foreach: (from, to) => val wings = - if (lifetime) "lifetime Patron wings" + if lifetime then "lifetime Patron wings" else "Patron wings for one month" alsoSendAsPrivateMessage(from): _ => s"""You gift @${to.username} the $wings. Thank you so much!""" diff --git a/modules/mailer/src/main/Mailer.scala b/modules/mailer/src/main/Mailer.scala index 115886484127d..0d679f04ae4ef 100644 --- a/modules/mailer/src/main/Mailer.scala +++ b/modules/mailer/src/main/Mailer.scala @@ -26,11 +26,11 @@ final class Mailer( private val secondaryClient = SMTPMailer(config.secondary.toClientConfig) private def randomClient(): (SMTPMailer, Mailer.Smtp) = - if (ThreadLocalRandom.nextInt(1000) < getSecondaryPermille()) (secondaryClient, config.secondary) + if ThreadLocalRandom.nextInt(1000) < getSecondaryPermille() then (secondaryClient, config.secondary) else (primaryClient, config.primary) def send(msg: Mailer.Message): Funit = - if (msg.to.isNoReply) + if msg.to.isNoReply then logger.warn(s"Can't send ${msg.subject} to noreply email ${msg.to}") funit else diff --git a/modules/mod/src/main/AssessApi.scala b/modules/mod/src/main/AssessApi.scala index 72b4b36fa5a7b..13cce84c06168 100644 --- a/modules/mod/src/main/AssessApi.scala +++ b/modules/mod/src/main/AssessApi.scala @@ -127,13 +127,13 @@ final class AssessApi( def consistentMoveTimes(game: Game)(player: Player) = Statistics.moderatelyConsistentMoveTimes(Pov(game, player)) val shouldAssess = - if (!game.source.exists(assessableSources.contains)) false - else if (game.mode.casual) false - else if (Player.HoldAlert suspicious holdAlerts) true - else if (game.isCorrespondence) false - else if (game.playedTurns < PlayerAssessment.minPlies) false - else if (game.players exists consistentMoveTimes(game)) true - else if (game.createdAt isBefore bottomDate) false + if !game.source.exists(assessableSources.contains) then false + else if game.mode.casual then false + else if Player.HoldAlert suspicious holdAlerts then true + else if game.isCorrespondence then false + else if game.playedTurns < PlayerAssessment.minPlies then false + else if game.players exists consistentMoveTimes(game) then true + else if game.createdAt isBefore bottomDate then false else true shouldAssess.so { createPlayerAssessment(PlayerAssessment.make(game pov White, analysis, holdAlerts.white)) >> @@ -206,39 +206,39 @@ final class AssessApi( yield wR <= lR - 300) val shouldAnalyse: Fu[Option[AutoAnalysis.Reason]] = - if (!game.analysable) fuccess(none) - else if (game.speed >= chess.Speed.Blitz && (white.hasTitle || black.hasTitle)) + if !game.analysable then fuccess(none) + else if game.speed >= chess.Speed.Blitz && (white.hasTitle || black.hasTitle) then fuccess(TitledPlayer.some) - else if (!game.source.exists(assessableSources.contains)) fuccess(none) + else if !game.source.exists(assessableSources.contains) then fuccess(none) // give up on correspondence games - else if (game.isCorrespondence) fuccess(none) + else if game.isCorrespondence then fuccess(none) // stop here for short games - else if (game.playedTurns < PlayerAssessment.minPlies) fuccess(none) + else if game.playedTurns < PlayerAssessment.minPlies then fuccess(none) // stop here for long games - else if (game.playedTurns > 95) fuccess(none) + else if game.playedTurns > 95 then fuccess(none) // stop here for casual games - else if (!game.mode.rated) fuccess(none) + else if !game.mode.rated then fuccess(none) // discard old games - else if (game.createdAt isBefore bottomDate) fuccess(none) - else if (isUpset) fuccess(Upset.some) + else if game.createdAt isBefore bottomDate then fuccess(none) + else if isUpset then fuccess(Upset.some) // white has consistent move times - else if (whiteSuspCoefVariation.isDefined) fuccess(WhiteMoveTime.some) + else if whiteSuspCoefVariation.isDefined then fuccess(WhiteMoveTime.some) // black has consistent move times - else if (blackSuspCoefVariation.isDefined) fuccess(BlackMoveTime.some) + else if blackSuspCoefVariation.isDefined then fuccess(BlackMoveTime.some) else // someone is using a bot gameRepo.holdAlert game game map { holdAlerts => - if (Player.HoldAlert suspicious holdAlerts) HoldAlert.some + if Player.HoldAlert suspicious holdAlerts then HoldAlert.some // don't analyse most of other bullet games - else if (game.speed == chess.Speed.Bullet && randomPercent(70)) none + else if game.speed == chess.Speed.Bullet && randomPercent(70) then none // someone blurs a lot - else if (game.players exists manyBlurs) Blurs.some + else if game.players exists manyBlurs then Blurs.some // the winner shows a great rating progress - else if (game.players exists winnerGreatProgress) WinnerRatingProgress.some + else if game.players exists winnerGreatProgress then WinnerRatingProgress.some // analyse some tourney games // else if (game.isTournament) randomPercent(20) option "Tourney random" /// analyse new player games - else if (winnerNbGames.so(40 >) && randomPercent(75)) NewPlayerWin.some + else if winnerNbGames.so(40 >) && randomPercent(75) then NewPlayerWin.some else none } diff --git a/modules/mod/src/main/Gamify.scala b/modules/mod/src/main/Gamify.scala index 3cde4f473ae80..df4290479da82 100644 --- a/modules/mod/src/main/Gamify.scala +++ b/modules/mod/src/main/Gamify.scala @@ -46,8 +46,8 @@ final class Gamify( private def buildHistoryAfter(afterYear: Int, afterMonth: Int, until: LocalDateTime): Funit = (afterYear to until.getYear) .flatMap { year => - ((if (year == afterYear) afterMonth + 1 else 1) to - (if (year == until.getYear) until.getMonthValue else 12)).map { month => + ((if year == afterYear then afterMonth + 1 else 1) to + (if year == until.getYear then until.getMonthValue else 12)).map { month => mixedLeaderboard( after = instantOf(year, month, 1, 0, 0).pp("compute mod history"), before = instantOf(year, month, 1, 0, 0).plusMonths(1).some diff --git a/modules/mod/src/main/ModActivity.scala b/modules/mod/src/main/ModActivity.scala index e23aac77be7c8..4ab5288be3dd6 100644 --- a/modules/mod/src/main/ModActivity.scala +++ b/modules/mod/src/main/ModActivity.scala @@ -122,8 +122,8 @@ object ModActivity: case Week, Month, Year object Period: def apply(str: String): Period = - if (str == "year") Year - else if (str == "month") Month + if str == "year" then Year + else if str == "month" then Month else Week def dateSince(period: Period) = period match case Period.Week => nowInstant.minusWeeks(1) diff --git a/modules/mod/src/main/ModApi.scala b/modules/mod/src/main/ModApi.scala index 916e070e466f6..832bfa3a63171 100644 --- a/modules/mod/src/main/ModApi.scala +++ b/modules/mod/src/main/ModApi.scala @@ -20,7 +20,7 @@ final class ModApi( _ <- userRepo.setAlt(prev.user.id, v) sus = prev.set(_.withMarks(_.set(_.Alt, v))) _ <- logApi.alt(sus, v) - yield if (v) notifier.reporters(me.modId, sus).unit + yield if v then notifier.reporters(me.modId, sus).unit def setEngine(prev: Suspect, v: Boolean)(using me: Me.Id): Funit = (prev.user.marks.engine != v) so { @@ -30,7 +30,7 @@ final class ModApi( _ <- logApi.engine(sus, v) yield Bus.publish(lila.hub.actorApi.mod.MarkCheater(sus.user.id, v), "adjustCheater") - if (v) + if v then notifier.reporters(me.modId, sus) refunder schedule sus } @@ -70,7 +70,7 @@ final class ModApi( Bus.publish(lila.hub.actorApi.mod.Shadowban(sus.user.id, value), "shadowban") } } >>- { - if (value) notifier.reporters(me.modId, sus).unit + if value then notifier.reporters(me.modId, sus).unit } inject sus def autoTroll(sus: Suspect, note: String): Funit = @@ -143,7 +143,7 @@ final class ModApi( def setRankban(sus: Suspect, v: Boolean)(using Me.Id): Funit = (sus.user.marks.rankban != v) so { - if (v) Bus.publish(lila.hub.actorApi.mod.KickFromRankings(sus.user.id), "kickFromRankings") + if v then Bus.publish(lila.hub.actorApi.mod.KickFromRankings(sus.user.id), "kickFromRankings") userRepo.setRankban(sus.user.id, v) >> logApi.rankban(sus, v) } diff --git a/modules/mod/src/main/ModlogApi.scala b/modules/mod/src/main/ModlogApi.scala index cb01f14f99407..390f3d42abc6c 100644 --- a/modules/mod/src/main/ModlogApi.scala +++ b/modules/mod/src/main/ModlogApi.scala @@ -24,7 +24,7 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin Modlog(streamerId.some, Modlog.streamerDecline) def streamerList(streamerId: UserId, v: Boolean)(using Me.Id) = add: - Modlog(streamerId.some, if (v) Modlog.streamerList else Modlog.streamerUnlist) + Modlog(streamerId.some, if v then Modlog.streamerList else Modlog.streamerUnlist) def streamerTier(streamerId: UserId, v: Int)(using Me.Id) = add: Modlog(streamerId.some, Modlog.streamerTier, v.toString.some) @@ -98,14 +98,14 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin def toggleCloseTopic(categ: ForumCategId, topicSlug: String, closed: Boolean)(using Me) = add: Modlog( none, - if (closed) Modlog.closeTopic else Modlog.openTopic, + if closed then Modlog.closeTopic else Modlog.openTopic, details = s"$categ/$topicSlug".some ) def toggleStickyTopic(categ: ForumCategId, topicSlug: String, sticky: Boolean)(using Me) = add: Modlog( none, - if (sticky) Modlog.stickyTopic else Modlog.unstickyTopic, + if sticky then Modlog.stickyTopic else Modlog.unstickyTopic, details = s"$categ/$topicSlug".some ) @@ -119,7 +119,7 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin )(using Me.Id) = add: Modlog( none, - if (edit) Modlog.editAsAnonMod else Modlog.postAsAnonMod, + if edit then Modlog.editAsAnonMod else Modlog.postAsAnonMod, details = s"$categ/$topic id: $postId ${text.take(400)}".some ) @@ -133,7 +133,7 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin def toggleTeam(id: String, closing: Boolean, explain: String)(using Me.Id) = add: Modlog( none, - if (closing) Modlog.disableTeam else Modlog.enableTeam, + if closing then Modlog.disableTeam else Modlog.enableTeam, details = s"$id: ${explain take 200}".some ) indexAs "team" @@ -156,7 +156,7 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin Modlog.permissions, details = permissions .map: (p, dir) => - s"${if (dir) "+" else "-"}${p}" + s"${if dir then "+" else "-"}${p}" .mkString(", ") .some ) @@ -207,10 +207,10 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(usin Modlog.make(sus, Modlog.garbageCollect) def rankban(sus: Suspect, v: Boolean)(using Me.Id) = add: - Modlog.make(sus, if (v) Modlog.rankban else Modlog.unrankban) + Modlog.make(sus, if v then Modlog.rankban else Modlog.unrankban) def prizeban(sus: Suspect, v: Boolean)(using Me.Id) = add: - Modlog.make(sus, if (v) Modlog.prizeban else Modlog.unprizeban) + Modlog.make(sus, if v then Modlog.prizeban else Modlog.unprizeban) def teamKick(user: UserId, teamName: String)(using Me.Id) = add: Modlog(user.some, Modlog.teamKick, details = Some(teamName take 140)) diff --git a/modules/mod/src/main/Presets.scala b/modules/mod/src/main/Presets.scala index 9eb1f28e7abd9..4777b80dfdca7 100644 --- a/modules/mod/src/main/Presets.scala +++ b/modules/mod/src/main/Presets.scala @@ -68,17 +68,16 @@ object ModPresets: .map(_.linesIterator.toList) .filter(_.nonEmpty) .flatMap { - case perms :: rest => { + case perms :: rest => val cleanRest = rest.dropWhile(_.isEmpty) - for { + for name <- cleanRest.headOption text = cleanRest.tail - } yield ModPreset( + yield ModPreset( name, text.dropWhile(_.isEmpty) mkString "\n", toPermisssions(perms) ) - } case _ => none } } diff --git a/modules/mod/src/main/RatingRefund.scala b/modules/mod/src/main/RatingRefund.scala index 820471c0f83aa..a342e38f3cf06 100644 --- a/modules/mod/src/main/RatingRefund.scala +++ b/modules/mod/src/main/RatingRefund.scala @@ -84,7 +84,7 @@ private object RatingRefund: case class Refunds(all: List[Refund]): def add(victim: UserId, perf: PerfType, diff: IntRatingDiff, rating: IntRating) = - copy(all = all.find(_.is(victim, perf)) match { + copy(all = all.find(_.is(victim, perf)) match case None => Refund(victim, perf, diff, rating) :: all case Some(r) => r.add(diff, rating) :: all.filterNot(_ is r) - }) + ) diff --git a/modules/mod/src/main/SandbagWatch.scala b/modules/mod/src/main/SandbagWatch.scala index 8a4c6d44cf693..8db6047dd0fd6 100644 --- a/modules/mod/src/main/SandbagWatch.scala +++ b/modules/mod/src/main/SandbagWatch.scala @@ -75,12 +75,12 @@ final private class SandbagWatch( .playerByUserId(userId) .ifTrue(isSandbag(game)) .fold[Outcome](Good): player => - if (player.color == loser) game.winnerUserId.fold[Outcome](Good)(Sandbag.apply) + if player.color == loser then game.winnerUserId.fold[Outcome](Good)(Sandbag.apply) else game.loserUserId.fold[Outcome](Good)(Boost.apply) private def isSandbag(game: Game): Boolean = game.playedTurns <= { - if (game.variant == chess.variant.Atomic) 3 + if game.variant == chess.variant.Atomic then 3 else 8 } && game.winner.so(~_.ratingDiff > 0) diff --git a/modules/msg/src/main/MsgCompat.scala b/modules/msg/src/main/MsgCompat.scala index a6c2f70f50a9a..cc27b20260636 100644 --- a/modules/msg/src/main/MsgCompat.scala +++ b/modules/msg/src/main/MsgCompat.scala @@ -70,8 +70,8 @@ final class MsgCompat( "name" -> c.contact.name, "posts" -> c.msgs.reverse.map: msg => Json.obj( - "sender" -> renderUser(if (msg.user == c.contact.id) c.contact else me.light), - "receiver" -> renderUser(if (msg.user != c.contact.id) c.contact else me.light), + "sender" -> renderUser(if msg.user == c.contact.id then c.contact else me.light), + "receiver" -> renderUser(if msg.user != c.contact.id then c.contact else me.light), "text" -> msg.text, "createdAt" -> msg.date ) diff --git a/modules/msg/src/main/MsgSecurity.scala b/modules/msg/src/main/MsgSecurity.scala index 600ad36a4f9f1..829226cf572a6 100644 --- a/modules/msg/src/main/MsgSecurity.scala +++ b/modules/msg/src/main/MsgSecurity.scala @@ -27,12 +27,12 @@ final private class MsgSecurity( val verified = 5 val hog = 1 def apply(u: User.Contact): Int = - if (u.isApiHog) hog - else if (u.isVerified) verified - else if (u isDaysOld 30) normal - else if (u isDaysOld 7) normal * 2 - else if (u isDaysOld 3) normal * 3 - else if (u isHoursOld 12) normal * 4 + if u.isApiHog then hog + else if u.isVerified then verified + else if u isDaysOld 30 then normal + else if u isDaysOld 7 then normal * 2 + else if u isDaysOld 3 then normal * 3 + else if u isHoursOld 12 then normal * 4 else normal * 5 private val CreateLimitPerUser = RateLimit[UserId]( @@ -159,7 +159,7 @@ final private class MsgSecurity( private def kidCheck(contacts: User.Contacts, isNew: Boolean): Fu[Boolean] = import contacts.* - if (!isNew || !hasKid) fuTrue + if !isNew || !hasKid then fuTrue else (orig.isKid, dest.isKid) match case (true, true) => Bus.ask[Boolean]("clas") { AreKidsInSameClass(orig.id, dest.id, _) } diff --git a/modules/msg/src/main/MsgThread.scala b/modules/msg/src/main/MsgThread.scala index ff8fee3c78199..8b9af6fd32016 100644 --- a/modules/msg/src/main/MsgThread.scala +++ b/modules/msg/src/main/MsgThread.scala @@ -15,7 +15,7 @@ case class MsgThread( def users = List(user1, user2) - def other(userId: UserId): UserId = if (user1 == userId) user2 else user1 + def other(userId: UserId): UserId = if user1 == userId then user2 else user1 def other(using me: Me): UserId = other(me.userId) def other(user: LightUser): UserId = other(user.id) @@ -57,4 +57,4 @@ object MsgThread: ) private def sortUsers(u1: UserId, u2: UserId): (UserId, UserId) = - if (u1.value < u2.value) (u1, u2) else (u2, u1) + if u1.value < u2.value then (u1, u2) else (u2, u1) diff --git a/modules/notify/src/main/NotifyApi.scala b/modules/notify/src/main/NotifyApi.scala index 1629f93003166..f7e4474193233 100644 --- a/modules/notify/src/main/NotifyApi.scala +++ b/modules/notify/src/main/NotifyApi.scala @@ -105,14 +105,13 @@ final class NotifyApi( def notifyOne[U: UserIdOf](to: U, content: NotificationContent): Funit = val note = Notification.make(to, content) !shouldSkip(note) flatMapz { - NotificationPref.Event.byKey.get(content.key) match { + NotificationPref.Event.byKey.get(content.key) match case None => bellOne(note) case Some(event) => prefs.allows(note.to, event) map { allows => if allows.bell then bellOne(note) if allows.push then pushOne(NotifyAllows(note.to, allows), note.content) } - } } // notifyMany tells clients that an update is available to bump their bell. there's no need diff --git a/modules/notify/src/main/NotifyCli.scala b/modules/notify/src/main/NotifyCli.scala index 6acf74b3f8b85..4c1863813abd7 100644 --- a/modules/notify/src/main/NotifyCli.scala +++ b/modules/notify/src/main/NotifyCli.scala @@ -21,7 +21,7 @@ final private class NotifyCli(api: NotifyApi, userRepo: UserRepo)(using Material .mapConcat(_.getAsOpt[UserId]("_id").toList) notifyUrlTo(userIds, url, words) - private def notifyUrlTo(userIds: Source[UserId, _], url: String, words: List[String]) = + private def notifyUrlTo(userIds: Source[UserId, ?], url: String, words: List[String]) = val title = words.takeWhile(_ != "|").mkString(" ").some.filter(_.nonEmpty) val text = words.dropWhile(_ != "|").drop(1).mkString(" ").some.filter(_.nonEmpty) val notification = GenericLink(url, title, text, lila.common.licon.InfoCircle) diff --git a/modules/opening/src/main/OpeningApi.scala b/modules/opening/src/main/OpeningApi.scala index 4f38469c25ab6..36f1977546b7f 100644 --- a/modules/opening/src/main/OpeningApi.scala +++ b/modules/opening/src/main/OpeningApi.scala @@ -71,7 +71,7 @@ final class OpeningApi( private val allGamesHistory = cacheApi[OpeningConfig, PopularityHistoryAbsolute](32, "opening.allGamesHistory") { - _.expireAfterWrite(1 hour).buildAsyncFuture(config => { + _.expireAfterWrite(1 hour).buildAsyncFuture(config => explorer.stats(Vector.empty, config, Crawler(false)).map(_.so(_.popularityHistory)) - }) + ) } diff --git a/modules/opening/src/main/OpeningConfig.scala b/modules/opening/src/main/OpeningConfig.scala index 65820d2d993c4..ae03fabe6632f 100644 --- a/modules/opening/src/main/OpeningConfig.scala +++ b/modules/opening/src/main/OpeningConfig.scala @@ -28,8 +28,8 @@ case class OpeningConfig(ratings: Set[Int], speeds: Set[Speed]): case first :: rest => val many = first :: rest val hash = many.mkString(",") - if (reference == hash) "All" - else if (reference contains hash) s"$first to ${rest.lastOption | first}" + if reference == hash then "All" + else if reference contains hash then s"$first to ${rest.lastOption | first}" else many mkString ", " final class OpeningConfigStore(baker: LilaCookie): diff --git a/modules/opening/src/main/OpeningPage.scala b/modules/opening/src/main/OpeningPage.scala index d8d2afb4d6b7b..93a5a067cbe32 100644 --- a/modules/opening/src/main/OpeningPage.scala +++ b/modules/opening/src/main/OpeningPage.scala @@ -60,9 +60,8 @@ case class OpeningExplored( games: List[GameWithPgn], next: List[OpeningNext], history: PopularityHistoryPercent -) { +): def lastPopularityPercent: Option[Float] = history.lastOption -} object OpeningPage: def apply( @@ -80,13 +79,13 @@ object OpeningPage: games = games, next = exp.moves .flatMap { m => - for { + for uci <- Uci.Move(m.uci) move <- query.position.move(uci).toOption result = ResultCounts(m.white, m.draws, m.black) fen = Fen writeOpening move.situationAfter opening = OpeningDb findByOpeningFen fen - } yield OpeningNext( + yield OpeningNext( m.san, uci, fen, diff --git a/modules/opening/src/main/OpeningQuery.scala b/modules/opening/src/main/OpeningQuery.scala index 472a80236445d..24527930605a4 100644 --- a/modules/opening/src/main/OpeningQuery.scala +++ b/modules/opening/src/main/OpeningQuery.scala @@ -50,7 +50,7 @@ object OpeningQuery: ) def apply(q: Query, config: OpeningConfig): Option[OpeningQuery] = - if (q.key.isEmpty && q.moves.isEmpty) fromPgn(PgnMovesStr(""), config) + if q.key.isEmpty && q.moves.isEmpty then fromPgn(PgnMovesStr(""), config) else q.moves.flatMap(fromPgn(_, config)) orElse byOpening(q.key, config) private lazy val openingsByLowerCaseKey: Map[OpeningKey, Opening] = @@ -63,10 +63,10 @@ object OpeningQuery: } }.map(_.pgn) flatMap { fromPgn(_, config) } - private def fromPgn(pgn: PgnMovesStr, config: OpeningConfig) = for { + private def fromPgn(pgn: PgnMovesStr, config: OpeningConfig) = for parsed <- chess.format.pgn.Reader.full(pgn into PgnStr).toOption replay <- parsed.valid.toOption - } yield OpeningQuery(replay, config) + yield OpeningQuery(replay, config) val firstYear = 2017 val firstMonth = s"$firstYear-01" diff --git a/modules/opening/src/main/OpeningSearch.scala b/modules/opening/src/main/OpeningSearch.scala index 8ca055044ff95..633595992352a 100644 --- a/modules/opening/src/main/OpeningSearch.scala +++ b/modules/opening/src/main/OpeningSearch.scala @@ -86,23 +86,21 @@ private object OpeningSearch: def exactMatch(token: Token) = entry.tokens(token) || entry.tokens(s"${token}s") // King's and Queen's can be matched by king and queen - if ( - entry.opening.pgn.value.startsWith(query.raw) || + if entry.opening.pgn.value.startsWith(query.raw) || entry.opening.pgn.value.startsWith(query.numberedPgn) || entry.opening.uci.value.startsWith(query.raw) - ) - (query.raw.size * 1000 - entry.opening.nbMoves) + then (query.raw.size * 1000 - entry.opening.nbMoves) else query.tokens .foldLeft((query.tokens, 0)) { case ((remaining, score), token) => - if (exactMatch(token)) (remaining - token, score + token.size * 100) + if exactMatch(token) then (remaining - token, score + token.size * 100) else (remaining, score) } match case (remaining, score) => score + remaining.map { t => entry.tokens.map { e => - if (e startsWith t) t.size * 50 - else if (e contains t) t.size * 20 + if e startsWith t then t.size * 50 + else if e contains t then t.size * 20 else 0 }.sum }.sum diff --git a/modules/opening/src/main/OpeningWiki.scala b/modules/opening/src/main/OpeningWiki.scala index fac55d1996638..7a1ff4f2c7357 100644 --- a/modules/opening/src/main/OpeningWiki.scala +++ b/modules/opening/src/main/OpeningWiki.scala @@ -123,7 +123,7 @@ object OpeningWiki: private def filterMarkupForMove(move: String)(markup: Html) = markup map { _.linesIterator collect { case MoveLiRegex(m, content) => - if (m.toLowerCase == move.toLowerCase) s"

${content.trim}

" else "" + if m.toLowerCase == move.toLowerCase then s"

${content.trim}

" else "" case html => html } mkString "\n" } diff --git a/modules/opening/src/test/OpeningSearchTest.scala b/modules/opening/src/test/OpeningSearchTest.scala index f364314e4c756..56dc68e931ab7 100644 --- a/modules/opening/src/test/OpeningSearchTest.scala +++ b/modules/opening/src/test/OpeningSearchTest.scala @@ -2,7 +2,7 @@ package lila.opening import chess.opening.OpeningName -class OpeningSearchTest extends munit.FunSuite { +class OpeningSearchTest extends munit.FunSuite: def search(q: String) = OpeningSearch(q, 10) @@ -25,4 +25,3 @@ class OpeningSearchTest extends munit.FunSuite { test("progressive") { assertEquals(search("Sicil").headOption.map(_.name), OpeningName("Sicilian Defense").some) } -} diff --git a/modules/opening/src/test/OpeningTest.scala b/modules/opening/src/test/OpeningTest.scala index e6a466194b852..6142f8206e5f3 100644 --- a/modules/opening/src/test/OpeningTest.scala +++ b/modules/opening/src/test/OpeningTest.scala @@ -2,7 +2,7 @@ package lila.opening import chess.opening.OpeningName -class OpeningTest extends munit.FunSuite { +class OpeningTest extends munit.FunSuite: import NameSection.variationName def vn(prev: String, next: String, expected: String) = @@ -59,4 +59,3 @@ class OpeningTest extends munit.FunSuite { "Semi-Slav Defense" ) } -} diff --git a/modules/perfStat/src/main/PerfStat.scala b/modules/perfStat/src/main/PerfStat.scala index fc5ddc74ce565..28f15c363a0ed 100644 --- a/modules/perfStat/src/main/PerfStat.scala +++ b/modules/perfStat/src/main/PerfStat.scala @@ -21,14 +21,14 @@ case class PerfStat( inline def id = _id def agg(pov: Pov) = - if (!pov.game.finished) this + if !pov.game.finished then this else val thisYear = pov.game.createdAt isAfter nowInstant.minusYears(1) copy( highest = RatingAt.agg(highest, pov, 1), - 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, + lowest = if thisYear then RatingAt.agg(lowest, pov, -1) else lowest, + bestWins = if ~pov.win then bestWins.agg(pov, 1) else bestWins, + worstLosses = if thisYear && ~pov.loss then worstLosses.agg(pov, -1) else worstLosses, count = count(pov), resultStreak = resultStreak agg pov, playStreak = playStreak agg pov @@ -74,7 +74,7 @@ case class PlayStreak(nb: Streaks, time: Streaks, lastDate: Option[Instant]): ) } def checkCurrent = - if (isContinued(nowInstant)) this + if isContinued(nowInstant) then this else copy(nb = nb.reset, time = time.reset) private def isContinued(at: Instant) = lastDate.fold(true) { ld => @@ -89,14 +89,14 @@ case class Streaks(cur: Streak, max: Streak): def continueOrStart(cont: Boolean, pov: Pov)(v: Int) = copy(cur = cur.continueOrStart(cont, pov)(v)).setMax def reset = copy(cur = Streak.init) - private def setMax = copy(max = if (cur.v >= max.v) cur else max) + private def setMax = copy(max = if cur.v >= max.v then cur else max) object Streaks: val init = Streaks(Streak.init, Streak.init) case class Streak(v: Int, from: Option[GameAt], to: Option[GameAt]): def continueOrReset(cont: Boolean, pov: Pov)(v: Int) = - if (cont) inc(pov, v) else Streak.init + if cont then inc(pov, v) else Streak.init def continueOrStart(cont: Boolean, pov: Pov)(v: Int) = - if (cont) inc(pov, v) + if cont then inc(pov, v) else val at = GameAt(pov.game.createdAt, pov.gameId).some val end = GameAt(pov.game.movedAt, pov.gameId).some @@ -124,19 +124,19 @@ case class Count( def apply(pov: Pov) = copy( all = all + 1, - 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), + rated = rated + (if pov.game.rated then 1 else 0), + win = win + (if pov.win.contains(true) then 1 else 0), + loss = loss + (if pov.win.contains(false) then 1 else 0), + draw = draw + (if pov.win.isEmpty then 1 else 0), + tour = tour + (if pov.game.isTournament then 1 else 0), + berserk = berserk + (if pov.player.berserk then 1 else 0), opAvg = pov.opponent.stableRating.fold(opAvg)(r => opAvg agg r.value), - seconds = seconds + (pov.game.durationSeconds match { + seconds = seconds + (pov.game.durationSeconds match case Some(s) if s <= 3 * 60 * 60 => s case _ => 0 - }), + ), disconnects = disconnects + { - if (~pov.loss && pov.game.status == chess.Status.Timeout) 1 else 0 + if ~pov.loss && pov.game.status == chess.Status.Timeout then 1 else 0 } ) def duration = Duration.ofSeconds(seconds) diff --git a/modules/plan/src/main/Charge.scala b/modules/plan/src/main/Charge.scala index d638f00157ac4..ee568423c0e19 100644 --- a/modules/plan/src/main/Charge.scala +++ b/modules/plan/src/main/Charge.scala @@ -22,9 +22,9 @@ case class Charge( def isStripe = stripe.nonEmpty def serviceName = - if (isStripe) "stripe" - else if (isPayPalLegacy) "paypal legacy" - else if (isPayPalCheckout) "paypal checkout" + if isStripe then "stripe" + else if isPayPalLegacy then "paypal legacy" + else if isPayPalCheckout then "paypal checkout" else "???" def toGift = (userId, giftTo) mapN { Charge.Gift(_, _, date) } diff --git a/modules/plan/src/main/Currency.scala b/modules/plan/src/main/Currency.scala index 363f5414d8e65..5106e7a3ce1c3 100644 --- a/modules/plan/src/main/Currency.scala +++ b/modules/plan/src/main/Currency.scala @@ -26,7 +26,7 @@ final class CurrencyApi( private val ratesCache = mongoCache.unit[Map[String, Double]]( "currency:rates", - if (mode == Mode.Prod) 120 minutes // i.e. 377/month, under the 1000/month limit of free OER plan + if mode == Mode.Prod then 120 minutes // i.e. 377/month, under the 1000/month limit of free OER plan else 1 day ) { loader => _.refreshAfterWrite(121 minutes) @@ -48,10 +48,10 @@ final class CurrencyApi( def convert(money: Money, currency: Currency): Fu[Option[Money]] = ratesCache.get {} map { rates => - for { + for fromRate <- rates get money.currencyCode toRate <- rates get currency.getCurrencyCode - } yield Money(money.amount / fromRate * toRate, currency) + yield Money(money.amount / fromRate * toRate, currency) } def toUsd(money: Money): Fu[Option[Usd]] = diff --git a/modules/plan/src/main/Patron.scala b/modules/plan/src/main/Patron.scala index b9275cc4c91ec..ced620d204832 100644 --- a/modules/plan/src/main/Patron.scala +++ b/modules/plan/src/main/Patron.scala @@ -27,7 +27,7 @@ case class Patron( ) def expireInOneMonth(cond: Boolean): Patron = - if (cond) expireInOneMonth + if cond then expireInOneMonth else copy(expiresAt = none) def removeStripe = diff --git a/modules/plan/src/main/PayPalClient.scala b/modules/plan/src/main/PayPalClient.scala index daad142b232c7..b5c385996cda7 100644 --- a/modules/plan/src/main/PayPalClient.scala +++ b/modules/plan/src/main/PayPalClient.scala @@ -134,7 +134,7 @@ final private class PayPalClient( )(using (__ \ "plans").read[List[PayPalPlan]]) current .flatMap { (plans: List[PayPalPlan]) => - if (plans.size == plansPerPage) getPlans(page + 1).map(plans ::: _) + if plans.size == plansPerPage then getPlans(page + 1).map(plans ::: _) else fuccess(plans) } .map(_.filter(_.active)) diff --git a/modules/plan/src/main/PlanApi.scala b/modules/plan/src/main/PlanApi.scala index b955a59189ba3..5776d807a1b39 100644 --- a/modules/plan/src/main/PlanApi.scala +++ b/modules/plan/src/main/PlanApi.scala @@ -66,7 +66,7 @@ final class PlanApi( def getEvent = stripeClient.getEvent - def onCharge(stripeCharge: StripeCharge): Funit = for { + def onCharge(stripeCharge: StripeCharge): Funit = for patronOption <- customerIdPatron(stripeCharge.customer) giftTo <- stripeCharge.giftTo so userRepo.byId money = stripeCharge.amount toMoney stripeCharge.currency @@ -93,7 +93,7 @@ final class PlanApi( case Some(to) => gift(user, to, money) case None => stripeClient.getCustomer(stripeCharge.customer) flatMap { customer => - val freq = if (customer.exists(_.renew)) Freq.Monthly else Freq.Onetime + val freq = if customer.exists(_.renew) then Freq.Monthly else Freq.Onetime val patron = prevPatron .copy(lastLevelUp = prevPatron.lastLevelUp orElse nowInstant.some) .levelUpIfPossible @@ -104,11 +104,11 @@ final class PlanApi( } } } - } yield () + yield () def onSubscriptionDeleted(sub: StripeSubscription): Funit = customerIdPatron(sub.customer) flatMapz { patron => - if (patron.isLifetime) funit + if patron.isLifetime then funit else userRepo byId patron.userId orFail s"Missing user for $patron" flatMap { user => setDbUserPlan(user.mapPlan(_.disable)) >> @@ -175,7 +175,7 @@ final class PlanApi( } def canUse(ip: IpAddress, freq: Freq)(using me: Me): Fu[StripeCanUse] = ip2proxy(ip) flatMap { proxy => - if (!proxy.is) fuccess(StripeCanUse.Yes) + if !proxy.is then fuccess(StripeCanUse.Yes) else val maxPerWeek = { val verifiedBonus = me.isVerified so 50 @@ -209,17 +209,17 @@ final class PlanApi( def getEvent = payPalClient.getEvent - def onLegacyCharge(ipn: PlanForm.Ipn, ip: IpAddress, key: String): Funit = for { + def onLegacyCharge(ipn: PlanForm.Ipn, ip: IpAddress, key: String): Funit = for money <- ipn.money.fold[Fu[Money]](fufail(s"Invalid paypal charge ${ipn.txnId}"))(fuccess) pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" usd <- currencyApi toUsd money orFail s"Invalid paypal currency $money" isLifetime <- pricingApi isLifetime money giftTo <- ipn.giftTo so userRepo.byId _ <- - if (key != payPalIpnKey.value) + if key != payPalIpnKey.value then logger.error(s"Invalid PayPal IPN key $key from $ip ${ipn.userId} $money") funit - else if (!pricing.valid(money)) + else if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${ipn.userId} $money ${ipn.txnId}") funit else @@ -273,7 +273,7 @@ final class PlanApi( isLifetime so setLifetime(user) } >>- logger.info(s"Charged ${user.username} with paypal: $money") } - } yield () + yield () def userSubscriptionId(user: User): Fu[Option[PayPalSubscriptionId]] = userPatron(user) map { @@ -284,15 +284,15 @@ final class PlanApi( userSubscriptionId(user) flatMapz payPalClient.getSubscription def createOrder(checkout: PlanCheckout, user: User, giftTo: Option[lila.user.User]) = - for { + for isLifetime <- pricingApi.isLifetime(checkout.money) order <- payPalClient.createOrder(CreatePayPalOrder(checkout, user, giftTo, isLifetime)) - } yield order + yield order def createSubscription(checkout: PlanCheckout, user: User) = payPalClient.createSubscription(checkout, user) - def captureOrder(orderId: PayPalOrderId, ip: IpAddress) = for { + def captureOrder(orderId: PayPalOrderId, ip: IpAddress) = for order <- payPalClient.captureOrder(orderId) money <- order.capturedMoney.fold[Fu[Money]](fufail(s"Invalid paypal capture $order"))(fuccess) pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" @@ -300,7 +300,7 @@ final class PlanApi( isLifetime <- pricingApi isLifetime money giftTo <- order.giftTo so userRepo.byId _ <- - if (!pricing.valid(money)) + if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${order.userId} $money ${orderId}") funit else @@ -341,7 +341,7 @@ final class PlanApi( isLifetime so setLifetime(user) } >>- logger.info(s"Charged ${user.username} with paypal: $money") } - } yield () + yield () def captureSubscription( orderId: PayPalOrderId, @@ -355,7 +355,7 @@ final class PlanApi( pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" usd <- currencyApi toUsd money orFail s"Invalid paypal currency $money" _ <- - if (!pricing.valid(money)) + if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${order.userId} $money $orderId") funit else @@ -425,7 +425,7 @@ final class PlanApi( end payPal private def setDbUserPlanOnCharge(from: User, levelUp: Boolean): Funit = - val user = from.mapPlan(p => if (levelUp) p.incMonths else p.enable) + val user = from.mapPlan(p => if levelUp then p.incMonths else p.enable) notifier.onCharge(user) setDbUserPlan(user) @@ -466,7 +466,7 @@ final class PlanApi( } case (_, _, Some(_)) => - if (!user.plan.active) + if !user.plan.active then logger.warn(s"${user.username} sync: enable plan of customer with paypal") setDbUserPlan(user.mapPlan(_.enable)) inject ReloadUser else fuccess(Synced(patron.some, none, none)) @@ -486,7 +486,7 @@ final class PlanApi( } def setLifetime(user: User): Funit = - if (user.plan.isEmpty) Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, 0), "plan") + if user.plan.isEmpty then Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, 0), "plan") userRepo.setPlan( user, user.plan.enable @@ -517,7 +517,7 @@ final class PlanApi( .void >> setDbUserPlanOnCharge(user, levelUp = false) def gift(from: User, to: User, money: Money): Funit = - for { + for toPatronOpt <- userPatron(to) isLifetime <- fuccess(toPatronOpt.exists(_.isLifetime)) >>| (pricingApi isLifetime money) _ <- mongo.patron.update @@ -531,9 +531,9 @@ final class PlanApi( ), upsert = true ) - newTo = to.mapPlan(p => if (toPatronOpt.exists(_.canLevelUp)) p.incMonths else p.enable) + newTo = to.mapPlan(p => if toPatronOpt.exists(_.canLevelUp) then p.incMonths else p.enable) _ <- setDbUserPlan(newTo) - } yield notifier.onGift(from, newTo, isLifetime) + yield notifier.onGift(from, newTo, isLifetime) def recentGiftFrom(from: User): Fu[Option[Patron]] = mongo.patron @@ -655,9 +655,9 @@ final class PlanApi( lila.mon.plan.goal.update(m.goal.cents) lila.mon.plan.current.update(m.current.cents) lila.mon.plan.percent.update(m.percent) - if (charge.isPayPalLegacy) lila.mon.plan.paypalLegacy.amount.record(charge.usd.cents) - else if (charge.isPayPalCheckout) lila.mon.plan.paypalCheckout.amount.record(charge.usd.cents) - else if (charge.isStripe) lila.mon.plan.stripe.record(charge.usd.cents) + if charge.isPayPalLegacy then lila.mon.plan.paypalLegacy.amount.record(charge.usd.cents) + else if charge.isPayPalCheckout then lila.mon.plan.paypalCheckout.amount.record(charge.usd.cents) + else if charge.isStripe then lila.mon.plan.stripe.record(charge.usd.cents) }.void private def setDbUserPlan(user: User): Funit = diff --git a/modules/plan/src/main/PlanCheckout.scala b/modules/plan/src/main/PlanCheckout.scala index 3f6a6cf4facd5..e4453a39814bd 100644 --- a/modules/plan/src/main/PlanCheckout.scala +++ b/modules/plan/src/main/PlanCheckout.scala @@ -12,7 +12,7 @@ case class PlanCheckout( giftTo: Option[UserStr] ): def fixFreq = copy( - freq = if (giftTo.isDefined) Freq.Onetime else freq + freq = if giftTo.isDefined then Freq.Onetime else freq ) private object PlanCheckout: @@ -29,7 +29,7 @@ final class PlanCheckoutForm(lightUserApi: lila.user.LightUserApi): PlanCheckout( email, Money(amount, currency), - if (freq == "monthly") Freq.Monthly else Freq.Onetime, + if freq == "monthly" then Freq.Monthly else Freq.Onetime, giftTo = giftTo ) diff --git a/modules/plan/src/main/PlanNotifier.scala b/modules/plan/src/main/PlanNotifier.scala index 5ebc0845a2bb8..a25a55a9b01df 100644 --- a/modules/plan/src/main/PlanNotifier.scala +++ b/modules/plan/src/main/PlanNotifier.scala @@ -16,7 +16,7 @@ final private[plan] class PlanNotifier( def onCharge(user: User) = Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, user.plan.months), "plan") - if (user.plan.months > 1) onRenew(user) else onStart(user) + if user.plan.months > 1 then onRenew(user) else onStart(user) private def onStart(user: User): Unit = system.scheduler.scheduleOnce(5 seconds) { diff --git a/modules/plan/src/main/PlanPricingApi.scala b/modules/plan/src/main/PlanPricingApi.scala index e2ea2568de564..370747fce57c0 100644 --- a/modules/plan/src/main/PlanPricingApi.scala +++ b/modules/plan/src/main/PlanPricingApi.scala @@ -32,16 +32,16 @@ final class PlanPricingApi(currencyApi: CurrencyApi)(using Executor): ) def pricingFor(currency: Currency): Fu[Option[PlanPricing]] = - if (currency == USD) fuccess(usdPricing.some) - else if (currency == EUR) fuccess(eurPricing.some) + if currency == USD then fuccess(usdPricing.some) + else if currency == EUR then fuccess(eurPricing.some) else - for { + for allSuggestions <- usdPricing.suggestions.map(convertAndRound(_, currency)).parallel.map(_.sequence) suggestions = allSuggestions.map(_.distinct) min <- convertAndRound(usdPricing.min, currency) max <- convertAndRound(usdPricing.max, currency) lifetime <- convertAndRound(usdPricing.lifetime, currency) - } yield (suggestions, min, max, lifetime).mapN(PlanPricing.apply) + yield (suggestions, min, max, lifetime).mapN(PlanPricing.apply) def pricingOrDefault(currency: Currency): Fu[PlanPricing] = pricingFor(currency).dmap(_ | usdPricing) @@ -60,7 +60,7 @@ object PlanPricingApi: def nicelyRound(amount: BigDecimal): BigDecimal = { val double = amount.toDouble val scale = math.floor(math.log10(double)); - val fraction = if (scale > 1) 2d else 1d + val fraction = if scale > 1 then 2d else 1d math.round(double * fraction * math.pow(10, -scale)) / fraction / math.pow(10, -scale) } atLeast 1 diff --git a/modules/plan/src/main/PlanWebhook.scala b/modules/plan/src/main/PlanWebhook.scala index 02cd54685f5c5..36b8d0447cd8f 100644 --- a/modules/plan/src/main/PlanWebhook.scala +++ b/modules/plan/src/main/PlanWebhook.scala @@ -51,10 +51,10 @@ final class PlanWebhook(api: PlanApi)(using Executor): Json .fromJson[PayPalCapture](event.resource) .fold( - _ => { + _ => log.error(s"Unreadable PayPalCapture ${Json stringify event.resource take 2000}") funit - }, + , capture => fuccess { api.payPal.onCaptureCompleted(capture) @@ -64,10 +64,10 @@ final class PlanWebhook(api: PlanApi)(using Executor): Json .fromJson[PayPalSale](event.resource) .fold( - _ => { + _ => log.error(s"Unreadable PayPalSale ${Json stringify event.resource take 2000}") funit - }, + , sale => fuccess { api.payPal.onCaptureCompleted(sale.toCapture) diff --git a/modules/plan/src/main/StripeClient.scala b/modules/plan/src/main/StripeClient.scala index 48f9d017225eb..3852b414fb557 100644 --- a/modules/plan/src/main/StripeClient.scala +++ b/modules/plan/src/main/StripeClient.scala @@ -35,7 +35,7 @@ final private class StripeClient(ws: StandaloneWSClient, config: StripeClient.Co val args = sessionArgs(StripeMode.payment, data, data.urls) ::: List( "line_items[0][price_data][product]" -> { - if (data.giftTo.isDefined) config.products.gift + if data.giftTo.isDefined then config.products.gift else config.products.onetime }, "line_items[0][price_data][currency]" -> data.checkout.money.currency, @@ -172,7 +172,7 @@ final private class StripeClient(ws: StandaloneWSClient, config: StripeClient.Co (summon[Reads[A]] reads res.body[JsValue]).fold( errs => fufail { - if (isDeleted(res.body[JsValue])) + if isDeleted(res.body[JsValue]) then new DeletedException(s"[stripe] Upstream resource was deleted: ${res.body}") else new Exception(s"[stripe] Can't parse ${res.body} --- $errs") }, diff --git a/modules/plan/src/main/model.scala b/modules/plan/src/main/model.scala index be8136967db7e..117d66d3856ec 100644 --- a/modules/plan/src/main/model.scala +++ b/modules/plan/src/main/model.scala @@ -53,12 +53,13 @@ object StripeAmount extends OpaqueInt[lila.plan.StripeAmount]: extension (e: StripeAmount) def toMoney(currency: Currency) = Money( - if (CurrencyApi zeroDecimalCurrencies currency) e + if CurrencyApi zeroDecimalCurrencies currency then e else BigDecimal(e) / 100, currency ) def apply(money: Money): StripeAmount = StripeAmount { - if (CurrencyApi.zeroDecimalCurrencies(money.currency)) money.amount.toInt else (money.amount * 100).toInt + if CurrencyApi.zeroDecimalCurrencies(money.currency) then money.amount.toInt + else (money.amount * 100).toInt } case class StripeSubscriptions(data: List[StripeSubscription]) @@ -148,7 +149,7 @@ case class StripeCompletedSession( amount_total: StripeAmount, currency: Currency ): - def freq = if (mode == "subscription") Freq.Monthly else Freq.Onetime + def freq = if mode == "subscription" then Freq.Monthly else Freq.Onetime def money = amount_total toMoney currency def giftTo: Option[UserId] = UserId.from(metadata get "giftTo") @@ -220,11 +221,11 @@ case class PayPalPlanId(value: String) extends AnyVal with StringValue case class PayPalPlan(id: PayPalPlanId, name: String, status: String, billing_cycles: JsArray): import JsonHandlers.payPal.given def active = status == "ACTIVE" - val currency = for { + val currency = for cycle <- billing_cycles.value.headOption pricing <- cycle obj "pricing_scheme" price <- pricing.get[PayPalAmount]("fixed_price") - } yield price.money.currency + yield price.money.currency case class PayPalTransactionId(value: String) extends AnyVal with StringValue case class PayPalCapture( id: PayPalTransactionId, diff --git a/modules/plan/src/test/PlanPricingTest.scala b/modules/plan/src/test/PlanPricingTest.scala index f040ce30fbc26..25d598ed17912 100644 --- a/modules/plan/src/test/PlanPricingTest.scala +++ b/modules/plan/src/test/PlanPricingTest.scala @@ -1,6 +1,6 @@ package lila.plan -class PlanPricingTest extends munit.FunSuite { +class PlanPricingTest extends munit.FunSuite: import PlanPricingApi.nicelyRound @@ -31,5 +31,3 @@ class PlanPricingTest extends munit.FunSuite { assertEquals(nicelyRound(77), BigDecimal(80)) assertEquals(nicelyRound(1009), BigDecimal(1000)) } - -} diff --git a/modules/playban/src/main/PlaybanApi.scala b/modules/playban/src/main/PlaybanApi.scala index 55377332696af..8086b472af63e 100644 --- a/modules/playban/src/main/PlaybanApi.scala +++ b/modules/playban/src/main/PlaybanApi.scala @@ -31,7 +31,7 @@ final class PlaybanApi( private def blameable(game: Game): Fu[Boolean] = (game.source.exists(blameableSources.contains) && game.hasClock) so { - if (game.rated) fuTrue + if game.rated then fuTrue else !userRepo.containsEngine(game.userIds) } @@ -71,11 +71,11 @@ final class PlaybanApi( // flagged after waiting a long time def sitting: Option[Funit] = - for { + for userId <- game.player(flaggerColor).userId seconds = nowSeconds - game.movedAt.toSeconds if unreasonableTime.exists(seconds >= _) - } yield save(Outcome.Sitting, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- + yield save(Outcome.Sitting, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- feedback.sitting(Pov(game, flaggerColor)) >> propagateSitting(game, userId) @@ -84,11 +84,11 @@ final class PlaybanApi( // assumes game was already checked for sitting def sitMoving: Option[Funit] = game.player(flaggerColor).userId.ifTrue { - ~(for { + ~(for movetimes <- game moveTimes flaggerColor lastMovetime <- movetimes.lastOption limit <- unreasonableTime - } yield lastMovetime.toSeconds >= limit) + yield lastMovetime.toSeconds >= limit) } map { userId => save(Outcome.SitMoving, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- feedback.sitting(Pov(game, flaggerColor)) >> @@ -103,17 +103,17 @@ final class PlaybanApi( private def propagateSitting(game: Game, userId: UserId): Funit = rageSitCache get userId map { rageSit => - if (rageSit.isBad) Bus.publish(SittingDetected(game, userId), "playban") + if rageSit.isBad then Bus.publish(SittingDetected(game, userId), "playban") } def other(game: Game, status: Status.type => Status, winner: Option[Color]): Funit = IfBlameable(game) { - ~(for { + ~(for w <- winner loser = game.player(!w) loserId <- loser.userId - } yield { - if (Status.NoStart is status) + yield + if Status.NoStart is status then save(Outcome.NoPlay, loserId, RageSit.Update.Reset, game.source) >>- feedback.noStart(Pov(game, !w)) else game.clock @@ -134,7 +134,7 @@ final class PlaybanApi( .getOrElse { good(game, !w) } - }) + ) } private def good(game: Game, loserColor: Color): Funit = @@ -198,31 +198,30 @@ final class PlaybanApi( source: Option[Source] ): Funit = { lila.mon.playban.outcome(outcome.key).increment() - for { + for withOutcome <- coll .findAndUpdateSimplified[UserRecord]( selector = $id(userId), update = $doc( $push("o" -> $doc("$each" -> List(outcome), "$slice" -> -30)) ++ { - rsUpdate match { + rsUpdate match case RageSit.Update.Reset => $min("c" -> 0) case RageSit.Update.Inc(v) if v != 0 => $inc("c" -> v) case _ => $empty - } } ), fetchNewObject = true, upsert = true ) orFail s"can't find newly created record for user $userId" withBan <- - if (outcome == Outcome.Good) fuccess(withOutcome) + if outcome == Outcome.Good then fuccess(withOutcome) else - for { + for createdAt <- userRepo.createdAtById(userId) orFail s"Missing user creation date $userId" withBan <- legiferate(withOutcome, createdAt, source) - } yield withBan + yield withBan _ <- registerRageSit(withBan, rsUpdate) - } yield () + yield () }.void logFailure lila.log("playban") private def legiferate(record: UserRecord, accCreatedAt: Instant, source: Option[Source]): Fu[UserRecord] = @@ -261,7 +260,7 @@ final class PlaybanApi( lila.hub.actorApi.mod.AutoWarning(record.userId, MsgPreset.sittingAuto.name), "autoWarning" ) - if (record.rageSit.isLethal && record.banMinutes.exists(_ > 12 * 60)) + if record.rageSit.isLethal && record.banMinutes.exists(_ > 12 * 60) then userRepo .byId(record.userId) .flatMapz { user => diff --git a/modules/playban/src/main/RageSit.scala b/modules/playban/src/main/RageSit.scala index a20d191db44e8..116c41b566b3e 100644 --- a/modules/playban/src/main/RageSit.scala +++ b/modules/playban/src/main/RageSit.scala @@ -17,7 +17,7 @@ object RageSit extends OpaqueInt[RageSit]: def isLethal = a.value <= -200 def goneWeight: Float = - if (!isBad) 1f + if !isBad then 1f else (1 - 0.7 * sqrt(log10(-(a.counter / 10) - 3))).toFloat max 0.1f def counterView = a.counter / 10 @@ -38,10 +38,10 @@ object RageSit extends OpaqueInt[RageSit]: case (a, _) if a <= -4 => -1 case _ => 0 } * { - if (loser.white) 1 else -1 + if loser.white then 1 else -1 } * { - if (game.speed <= Speed.Bullet) 5 - else if (game.speed == Speed.Blitz) 10 + if game.speed <= Speed.Bullet then 5 + else if game.speed == Speed.Blitz then 10 else 15 } } diff --git a/modules/playban/src/main/model.scala b/modules/playban/src/main/model.scala index 2d213b54e779a..079e65a30a37c 100644 --- a/modules/playban/src/main/model.scala +++ b/modules/playban/src/main/model.scala @@ -27,7 +27,7 @@ case class UserRecord( case o if o != Outcome.Good => 1 } sum - def badOutcomeRatio: Float = if (bans.sizeIs < 3) 0.4f else 0.3f + def badOutcomeRatio: Float = if bans.sizeIs < 3 then 0.4f else 0.3f def minBadOutcomes: Int = bans.size match @@ -93,11 +93,10 @@ object TempBan: def make(bans: Vector[TempBan], accountCreationDate: Instant): TempBan = make { (bans.lastOption so { prev => - prev.endsAt.toNow.toHours.toSaturatedInt match { + prev.endsAt.toNow.toHours.toSaturatedInt match case h if h < 72 => prev.mins * (132 - h) / 60 case h => (55.6 * prev.mins / (Math.pow(5.56 * prev.mins - 54.6, h / 720) + 54.6)).toInt - } - } atLeast baseMinutes) * (if (accountCreationDate.plusDays(3).isAfterNow) 2 else 1) + } atLeast baseMinutes) * (if accountCreationDate.plusDays(3).isAfterNow then 2 else 1) } enum Outcome(val id: Int, val name: String): diff --git a/modules/pool/src/main/GameStarter.scala b/modules/pool/src/main/GameStarter.scala index 983dda627af35..828d090f9abd6 100644 --- a/modules/pool/src/main/GameStarter.scala +++ b/modules/pool/src/main/GameStarter.scala @@ -38,10 +38,10 @@ final private class GameStarter( import couple.* import cats.syntax.all.* (perfs.get(p1.userId), perfs.get(p2.userId)).mapN((_, _)) so { (perf1, perf2) => - for { + for p1White <- userRepo.firstGetsWhite(p1.userId, p2.userId) - (whitePerf, blackPerf) = if (p1White) perf1 -> perf2 else perf2 -> perf1 - (whiteMember, blackMember) = if (p1White) p1 -> p2 else p2 -> p1 + (whitePerf, blackPerf) = if p1White then perf1 -> perf2 else perf2 -> perf1 + (whiteMember, blackMember) = if p1White then p1 -> p2 else p2 -> p1 game = makeGame( id, pool, @@ -49,7 +49,7 @@ final private class GameStarter( blackMember.userId -> blackPerf ).start _ <- gameRepo insertDenormalized game - } yield + yield onStart(game.id) Pairing( game, diff --git a/modules/pool/src/main/HookThieve.scala b/modules/pool/src/main/HookThieve.scala index 2811f001dcfc4..c4023db7e2c37 100644 --- a/modules/pool/src/main/HookThieve.scala +++ b/modules/pool/src/main/HookThieve.scala @@ -14,7 +14,7 @@ final private class HookThieve()(using Executor, Scheduler): def stolen(poolHooks: Vector[PoolHook], monId: String) = lila.mon.lobby.pool.thieve.stolen(monId).record(poolHooks.size) - if (poolHooks.nonEmpty) Bus.publish(StolenHookIds(poolHooks.map(_.hookId)), "lobbyActor") + if poolHooks.nonEmpty then Bus.publish(StolenHookIds(poolHooks.map(_.hookId)), "lobbyActor") object HookThieve: diff --git a/modules/pool/src/main/MatchMaking.scala b/modules/pool/src/main/MatchMaking.scala index d0f4579f9e13d..292fb8ea3a1b6 100644 --- a/modules/pool/src/main/MatchMaking.scala +++ b/modules/pool/src/main/MatchMaking.scala @@ -30,8 +30,8 @@ object MatchMaking: // 2500 ~> 166 // 3000 ~> 200 private def ratingToMaxScore(rating: IntRating) = - if (rating < 1000) 130 - else if (rating < 1500) 100 + if rating < 1000 then 130 + else if rating < 1500 then 100 else rating.value / 15 // quality of a potential pairing. Lower is better. @@ -61,7 +61,7 @@ object MatchMaking: // bonus if both players have rating ranges, and they're compatible private def rangeBonus(a: PoolMember, b: PoolMember) = - if (a.ratingRange.exists(_ contains b.rating) && b.ratingRange.exists(_ contains a.rating)) 200 + if a.ratingRange.exists(_ contains b.rating) && b.ratingRange.exists(_ contains a.rating) then 200 else 0 // if players block each other @@ -72,17 +72,17 @@ object MatchMaking: // bonus if the two players both have a bad sit counter // malus (so negative number as bonus) if neither of those are true, meaning that their sit counters are far away (e.g. 0 and -5) private def ragesitBonus(a: PoolMember, b: PoolMember) = - if (a.rageSitCounter >= -2 && b.rageSitCounter >= -2) 30 // good players - else if (a.rageSitCounter <= -12 && b.rageSitCounter <= -12) 60 // very bad players - else if (a.rageSitCounter <= -5 && b.rageSitCounter <= -5) 30 // bad players - else (abs(a.rageSitCounter - b.rageSitCounter) atMost 10) * -20 // match of good and bad player + if a.rageSitCounter >= -2 && b.rageSitCounter >= -2 then 30 // good players + else if a.rageSitCounter <= -12 && b.rageSitCounter <= -12 then 60 // very bad players + else if a.rageSitCounter <= -5 && b.rageSitCounter <= -5 then 30 // bad players + else (abs(a.rageSitCounter - b.rageSitCounter) atMost 10) * -20 // match of good and bad player def apply(members: Vector[PoolMember]): Option[Vector[Couple]] = WMMatching(members.toArray, pairScore).fold( - err => { + err => logger.error("WMMatching", err) none - }, + , pairs => Some { pairs.view.map { case (a, b) => Couple(a, b) } to Vector diff --git a/modules/pool/src/main/PoolActor.scala b/modules/pool/src/main/PoolActor.scala index 632fb35e35951..5529e272c0b85 100644 --- a/modules/pool/src/main/PoolActor.scala +++ b/modules/pool/src/main/PoolActor.scala @@ -41,7 +41,7 @@ final private class PoolActor( members.find(joiner.is) match case None => members = members :+ PoolMember(joiner, rageSit) - if (members.sizeIs >= config.wave.players.value) self ! FullWave + if members.sizeIs >= config.wave.players.value then self ! FullWave case Some(member) if member.ratingRange != joiner.ratingRange => members = members.map { case m if m == member => m withRange joiner.ratingRange @@ -84,7 +84,7 @@ final private class PoolActor( members = members.diff(pairedMembers).map(_.incMisses) - if (pairings.nonEmpty) gameStarter(config, pairings) + if pairings.nonEmpty then gameStarter(config, pairings) monitor.candidates(monId).record(candidates.size) monitor.paired(monId).record(pairedMembers.size) diff --git a/modules/pool/src/main/PoolMember.scala b/modules/pool/src/main/PoolMember.scala index ba46b5ad696c4..2e6a9430949d6 100644 --- a/modules/pool/src/main/PoolMember.scala +++ b/modules/pool/src/main/PoolMember.scala @@ -19,7 +19,7 @@ case class PoolMember( def ratingDiff(other: PoolMember) = IntRatingDiff(Math.abs(rating.value - other.rating.value)) def withRange(r: Option[RatingRange]) = - if (r == ratingRange) this + if r == ratingRange then this else copy(ratingRange = r, misses = 0) def hasRange = ratingRange.isDefined diff --git a/modules/practice/src/main/PracticeApi.scala b/modules/practice/src/main/PracticeApi.scala index 4ef67f82e55d6..549447fc9de8f 100644 --- a/modules/practice/src/main/PracticeApi.scala +++ b/modules/practice/src/main/PracticeApi.scala @@ -79,7 +79,7 @@ final class PracticeApi( def clear() = cache.invalidateUnit() def onSave(study: Study) = get foreach { structure => - if (structure.hasStudy(study.id)) clear() + if structure.hasStudy(study.id) then clear() } object progress: diff --git a/modules/practice/src/main/PracticeGoal.scala b/modules/practice/src/main/PracticeGoal.scala index bfd4bc53f4178..e745fd9bce7c4 100644 --- a/modules/practice/src/main/PracticeGoal.scala +++ b/modules/practice/src/main/PracticeGoal.scala @@ -27,10 +27,10 @@ object PracticeGoal: case DrawInR(movesStr) => movesStr.toIntOption map DrawIn.apply case EqualInR(movesStr) => movesStr.toIntOption map EqualIn.apply case EvalInR(cpStr, movesStr) => - for { + for cp <- cpStr.toIntOption moves <- movesStr.toIntOption - } yield EvalIn(cp, moves) + yield EvalIn(cp, moves) case PromotionR(cpStr) => cpStr.toIntOption map Promotion.apply case _ => none } | Mate // default to mate diff --git a/modules/practice/src/main/UserPractice.scala b/modules/practice/src/main/UserPractice.scala index 7c34c3f902302..7c314e0c599b2 100644 --- a/modules/practice/src/main/UserPractice.scala +++ b/modules/practice/src/main/UserPractice.scala @@ -30,6 +30,6 @@ case class UserStudy( case class Completion(done: Int, total: Int): - def percent = if (total == 0) 0 else done * 100 / total + def percent = if total == 0 then 0 else done * 100 / total def complete = done >= total diff --git a/modules/pref/src/main/Pref.scala b/modules/pref/src/main/Pref.scala index ced4706349cf7..93f6685300b0f 100644 --- a/modules/pref/src/main/Pref.scala +++ b/modules/pref/src/main/Pref.scala @@ -57,7 +57,7 @@ case class Pref( val themeColorLight = "#dbd7d1" val themeColorDark = "#2e2a24" - def themeColor = if (bg == Bg.LIGHT) themeColorLight else themeColorDark + def themeColor = if bg == Bg.LIGHT then themeColorLight else themeColorDark def realSoundSet = SoundSet(soundSet) @@ -90,9 +90,9 @@ case class Pref( SoundSet.allByKey get value map { s => copy(soundSet = s.key) } - case "zen" => copy(zen = if (value == "1") 1 else 0).some - case "voice" => copy(voice = if (value == "1") 1.some else 0.some).some - case "keyboardMove" => copy(keyboardMove = if (value == "1") 1 else 0).some + case "zen" => copy(zen = if value == "1" then 1 else 0).some + case "voice" => copy(voice = if value == "1" then 1.some else 0.some).some + case "keyboardMove" => copy(keyboardMove = if value == "1" then 1 else 0).some case _ => none def animationMillis: Int = @@ -450,7 +450,7 @@ object Pref: if user.createdAt.isAfter(systemByDefaultSince) then Bg.SYSTEM else if user.createdAt.isAfter(darkByDefaultSince) then Bg.DARK else Bg.LIGHT, - agreement = if (user.createdAt isAfter Agreement.changedAt) Agreement.current else 0 + agreement = if user.createdAt isAfter Agreement.changedAt then Agreement.current else 0 ) lazy val default = Pref( diff --git a/modules/pref/src/main/PrefForm.scala b/modules/pref/src/main/PrefForm.scala index ae9b21ff98b80..f9d2f529957f6 100644 --- a/modules/pref/src/main/PrefForm.scala +++ b/modules/pref/src/main/PrefForm.scala @@ -154,12 +154,12 @@ object PrefForm: def apply(pref: Pref): PrefData = PrefData( display = DisplayData( - highlight = if (pref.highlight) 1 else 0, - destination = if (pref.destination) 1 else 0, + highlight = if pref.highlight then 1 else 0, + destination = if pref.destination then 1 else 0, animation = pref.animation, coords = pref.coords, replay = pref.replay, - captured = if (pref.captured) 1 else 0, + captured = if pref.captured then 1 else 0, blindfold = pref.blindfold, zen = pref.zen.some, resizeHandle = pref.resizeHandle.some, @@ -167,7 +167,7 @@ object PrefForm: ), behavior = BehaviorData( moveEvent = pref.moveEvent.some, - premove = if (pref.premove) 1 else 0, + premove = if pref.premove then 1 else 0, takeback = pref.takeback, autoQueen = pref.autoQueen, autoThreefold = pref.autoThreefold, @@ -179,11 +179,11 @@ object PrefForm: ), clock = ClockData( tenths = pref.clockTenths, - bar = if (pref.clockBar) 1 else 0, - sound = if (pref.clockSound) 1 else 0, + bar = if pref.clockBar then 1 else 0, + sound = if pref.clockSound then 1 else 0, moretime = pref.moretime ), - follow = if (pref.follow) 1 else 0, + follow = if pref.follow then 1 else 0, challenge = pref.challenge, message = pref.message, studyInvite = pref.studyInvite.some, diff --git a/modules/push/src/main/Env.scala b/modules/push/src/main/Env.scala index 5aacfb7f7621f..4dd4f2aac057d 100644 --- a/modules/push/src/main/Env.scala +++ b/modules/push/src/main/Env.scala @@ -52,7 +52,7 @@ final class Env( case e: Exception => logger.warn("Failed to create google credentials", e) none - if (googleCredentials.isDefined) logger.info("Firebase push notifications are enabled.") + if googleCredentials.isDefined then logger.info("Firebase push notifications are enabled.") private lazy val firebasePush = wire[FirebasePush] diff --git a/modules/push/src/main/FirebasePush.scala b/modules/push/src/main/FirebasePush.scala index 41642f6d7772b..dc9cdf7dc2a9a 100644 --- a/modules/push/src/main/FirebasePush.scala +++ b/modules/push/src/main/FirebasePush.scala @@ -84,12 +84,12 @@ final private class FirebasePush( ) ) flatMap { res => lila.mon.push.firebaseStatus(res.status).increment() - if (res.status == 200) funit - else if (res.status == 404) + if res.status == 200 then funit + else if res.status == 404 then logger.info(s"Delete missing firebase device $device") deviceApi delete device else - if (errorCounter(res.status)) logger.warn(s"[push] firebase: ${res.status}") + if errorCounter(res.status) then logger.warn(s"[push] firebase: ${res.status}") funit } diff --git a/modules/push/src/main/PushApi.scala b/modules/push/src/main/PushApi.scala index d5d0b22067907..7423e36409e48 100644 --- a/modules/push/src/main/PushApi.scala +++ b/modules/push/src/main/PushApi.scala @@ -37,7 +37,7 @@ final private class PushApi( case _ => funit def finish(game: Game): Funit = - if (!game.isCorrespondence || game.hasAi) funit + if !game.isCorrespondence || game.hasAi then funit else game.userIds .map { userId => @@ -50,11 +50,11 @@ final private class PushApi( _.finish, NotificationPref.GameEvent, PushApi.Data( - title = pov.win match { + title = pov.win match case Some(true) => "You won!" case Some(false) => "You lost." case _ => "It's a draw." - }, + , body = s"Your game with $opponent is over.", stacking = Stacking.GameFinish, urgency = Urgency.VeryLow, @@ -317,7 +317,7 @@ final private class PushApi( "type" -> "tourSoon", "tourId" -> tour.tourId, "tourName" -> tour.tourName, - "path" -> s"/${if (tour.swiss) "swiss" else "tournament"}/${tour.tourId}" + "path" -> s"/${if tour.swiss then "swiss" else "tournament"}/${tour.tourId}" ) ) ) @@ -397,11 +397,11 @@ final private class PushApi( import lila.challenge.Challenge.TimeControl.* List( if c.mode.rated then "Rated" else "Casual", - c.timeControl match { + c.timeControl match case Unlimited => "Unlimited" case Correspondence(d) => s"$d days" case c: Clock => c.show - }, + , c.variant.name ) mkString " • " diff --git a/modules/push/src/main/WebSubscriptionApi.scala b/modules/push/src/main/WebSubscriptionApi.scala index 4d26bb0e5466c..1c38c5064c1a9 100644 --- a/modules/push/src/main/WebSubscriptionApi.scala +++ b/modules/push/src/main/WebSubscriptionApi.scala @@ -40,7 +40,7 @@ final class WebSubscriptionApi(coll: Coll)(using Executor): private[push] def getSubscriptions(userIds: Iterable[UserId], maxPerUser: Int): Fu[List[WebSubscription]] = coll .aggregateList(100_000, _.sec): framework => - import framework._ + import framework.* Match($doc("userId" $in userIds)) -> List( Sort(Descending("seenAt")), GroupField("userId")("subs" -> Push(BSONString("$$ROOT"))), diff --git a/modules/puzzle/src/main/BsonHandlers.scala b/modules/puzzle/src/main/BsonHandlers.scala index f85e9a6c49b92..d34fee30e3d0f 100644 --- a/modules/puzzle/src/main/BsonHandlers.scala +++ b/modules/puzzle/src/main/BsonHandlers.scala @@ -13,7 +13,7 @@ object BsonHandlers: import Puzzle.BSONFields.* private[puzzle] given puzzleReader: BSONDocumentReader[Puzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId](id) gameId <- r.getAsTry[GameId](gameId) fen <- r.getAsTry[Fen.Epd](fen) @@ -23,7 +23,7 @@ object BsonHandlers: plays <- r.getAsTry[Int](plays) vote <- r.getAsTry[Float](vote) themes <- r.getAsTry[Set[PuzzleTheme.Key]](themes) - } yield Puzzle( + yield Puzzle( id = id, gameId = gameId, fen = fen, @@ -36,10 +36,9 @@ object BsonHandlers: private[puzzle] given roundIdHandler: BSONHandler[PuzzleRound.Id] = tryHandler[PuzzleRound.Id]( { case BSONString(v) => - v split PuzzleRound.idSep match { + v split PuzzleRound.idSep match case Array(userId, puzzleId) => Success(PuzzleRound.Id(UserId(userId), PuzzleId(puzzleId))) case _ => handlerBadValue(s"Invalid puzzle round id $v") - } }, id => BSONString(id.toString) ) @@ -52,7 +51,7 @@ object BsonHandlers: Success(PuzzleRound.Theme(theme.key, v.head == '+')) } }, - rt => BSONString(s"${if (rt.vote) "+" else "-"}${rt.theme}") + rt => BSONString(s"${if rt.vote then "+" else "-"}${rt.theme}") ) private[puzzle] given roundHandler: BSON[PuzzleRound] with diff --git a/modules/puzzle/src/main/Env.scala b/modules/puzzle/src/main/Env.scala index ebfe67c0032f3..ee92514a6495d 100644 --- a/modules/puzzle/src/main/Env.scala +++ b/modules/puzzle/src/main/Env.scala @@ -88,10 +88,10 @@ final class Env( scheduler.scheduleAtFixedRate(10 minutes, 1 day): () => tagger.addAllMissing unit - if (mode == play.api.Mode.Prod) + if mode == play.api.Mode.Prod then scheduler.scheduleAtFixedRate(1 hour, 1 hour): () => pathApi.isStale.foreach: stale => - if (stale) logger.error("Puzzle paths appear to be stale! check that the regen cron is up") + if stale then logger.error("Puzzle paths appear to be stale! check that the regen cron is up") final class PuzzleColls( val puzzle: AsyncColl, diff --git a/modules/puzzle/src/main/GameJson.scala b/modules/puzzle/src/main/GameJson.scala index 2633d597d700c..cfac44ea51695 100644 --- a/modules/puzzle/src/main/GameJson.scala +++ b/modules/puzzle/src/main/GameJson.scala @@ -16,7 +16,7 @@ final private class GameJson( )(using Executor): def apply(gameId: GameId, plies: Ply, bc: Boolean): Fu[JsObject] = - (if (bc) bcCache else cache) get writeKey(gameId, plies) + (if bc then bcCache else cache) get writeKey(gameId, plies) def noCache(game: Game, plies: Ply): Fu[JsObject] = lightUserApi preloadMany game.userIds inject generate(game, plies) @@ -47,7 +47,7 @@ final private class GameJson( private def generate(gameId: GameId, plies: Ply, bc: Boolean): Fu[JsObject] = gameRepo gameFromSecondary gameId orFail s"Missing puzzle game $gameId!" flatMap { game => lightUserApi preloadMany game.userIds map { _ => - if (bc) generateBc(game, plies) + if bc then generateBc(game, plies) else generate(game, plies) } } diff --git a/modules/puzzle/src/main/Puzzle.scala b/modules/puzzle/src/main/Puzzle.scala index 0707f458e9fde..ebb6e36303b79 100644 --- a/modules/puzzle/src/main/Puzzle.scala +++ b/modules/puzzle/src/main/Puzzle.scala @@ -63,13 +63,13 @@ object Puzzle: private def charToInt(c: Char) = val i = c.toInt - if (i > 96) i - 71 - else if (i > 64) i - 65 + if i > 96 then i - 71 + else if i > 64 then i - 65 else i + 4 private def intToChar(i: Int): Char = { - if (i < 26) i + 65 - else if (i < 52) i + 71 + if i < 26 then i + 65 + else if i < 52 then i + 71 else i - 4 }.toChar diff --git a/modules/puzzle/src/main/PuzzleAnon.scala b/modules/puzzle/src/main/PuzzleAnon.scala index 581b26054abf7..45f701bdbb055 100644 --- a/modules/puzzle/src/main/PuzzleAnon.scala +++ b/modules/puzzle/src/main/PuzzleAnon.scala @@ -26,7 +26,7 @@ final class PuzzleAnon( private def selectWithColor(color: Color)(puzzles: Vector[Puzzle]): Option[Puzzle] = def nextTry(attempts: Int): Option[Puzzle] = - if (attempts < 10) + if attempts < 10 then ThreadLocalRandom oneOf puzzles filter (_.color == color) orElse nextTry(attempts + 1) else ThreadLocalRandom oneOf puzzles.filter(_.color == color) nextTry(1) diff --git a/modules/puzzle/src/main/PuzzleApi.scala b/modules/puzzle/src/main/PuzzleApi.scala index ea00bcfa2b608..d6ffb7ed1de96 100644 --- a/modules/puzzle/src/main/PuzzleApi.scala +++ b/modules/puzzle/src/main/PuzzleApi.scala @@ -68,7 +68,7 @@ final class PuzzleApi( .find(user, id) .flatMapz { prevRound => trustApi.vote(user, prevRound, vote) flatMapz { weight => - val voteValue = (if (vote) 1 else -1) * weight + val voteValue = (if vote then 1 else -1) * weight lila.mon.puzzle.vote.count(vote, prevRound.win.yes).increment() updatePuzzle(id, voteValue, prevRound.vote) zip colls.round { @@ -107,10 +107,10 @@ final class PuzzleApi( } } - def angles: Fu[PuzzleAngle.All] = for { + def angles: Fu[PuzzleAngle.All] = for themes <- theme.categorizedWithCount openings <- openingApi.collection - } yield PuzzleAngle.All(themes, openings) + yield PuzzleAngle.All(themes, openings) object theme: @@ -128,7 +128,7 @@ final class PuzzleApi( round.themeVote(theme, vote) so { newThemes => import PuzzleRound.{ BSONFields as F } val update = - if (newThemes.isEmpty || !PuzzleRound.themesLookSane(newThemes)) + if newThemes.isEmpty || !PuzzleRound.themesLookSane(newThemes) then fuccess($unset(F.themes, F.puzzle).some) else vote match diff --git a/modules/puzzle/src/main/PuzzleCount.scala b/modules/puzzle/src/main/PuzzleCount.scala index 95f2606767c5d..8f725c43efc4f 100644 --- a/modules/puzzle/src/main/PuzzleCount.scala +++ b/modules/puzzle/src/main/PuzzleCount.scala @@ -33,10 +33,10 @@ final private class PuzzleCountApi( ) }.map { _.flatMap { obj => - for { + for key <- obj string "_id" count <- obj int "nb" - } yield PuzzleTheme.Key(key) -> count + yield PuzzleTheme.Key(key) -> count }.toMap }.flatMap { themed => colls.puzzle(_.countAll) map { all => diff --git a/modules/puzzle/src/main/PuzzleFinisher.scala b/modules/puzzle/src/main/PuzzleFinisher.scala index 57ac9c0900210..a05226689506a 100644 --- a/modules/puzzle/src/main/PuzzleFinisher.scala +++ b/modules/puzzle/src/main/PuzzleFinisher.scala @@ -181,23 +181,21 @@ final private[puzzle] class PuzzleFinisher( private def weightOf(angle: PuzzleAngle, win: PuzzleWin) = angle.asTheme.fold(1f) { theme => - if (theme == PuzzleTheme.mix.key) 1 - else if (isObvious(theme)) - if (win.yes) 0.2f else 0.6f - else if (isHinting(theme)) - if (win.yes) 0.3f else 0.7f - else if (win.yes) 0.7f + if theme == PuzzleTheme.mix.key then 1 + else if isObvious(theme) then if win.yes then 0.2f else 0.6f + else if isHinting(theme) then if win.yes then 0.3f else 0.7f + else if win.yes then 0.7f else 0.8f } def player(angle: PuzzleAngle, win: PuzzleWin, glicko: (Glicko, Glicko), puzzle: Glicko) = val provisionalPuzzle = puzzle.provisional.yes so { - if (win.yes) -0.2f else -0.7f + if win.yes then -0.2f else -0.7f } glicko._1.average(glicko._2, (weightOf(angle, win) + provisionalPuzzle) atLeast 0.1f) def puzzle(angle: PuzzleAngle, win: PuzzleWin, glicko: (Glicko, Glicko), player: Glicko) = - if (player.clueless) glicko._1 + if player.clueless then glicko._1 else glicko._1.average(glicko._2, weightOf(angle, win)) private val VOLATILITY = Glicko.default.volatility diff --git a/modules/puzzle/src/main/PuzzleOpening.scala b/modules/puzzle/src/main/PuzzleOpening.scala index 3780149a4a9e9..ace25e157f0fd 100644 --- a/modules/puzzle/src/main/PuzzleOpening.scala +++ b/modules/puzzle/src/main/PuzzleOpening.scala @@ -28,7 +28,7 @@ case class PuzzleOpeningCollection( op.opening.ref.variation.isDefined so Set(op) ).some case Some((famCount, ops)) => - (famCount, if (op.opening.ref.variation.isDefined) ops incl op else ops).some + (famCount, if op.opening.ref.variation.isDefined then ops incl op else ops).some } } val treePopular: TreeList = treeMap.toList diff --git a/modules/puzzle/src/main/PuzzleReplay.scala b/modules/puzzle/src/main/PuzzleReplay.scala index b65b37f29ac55..154ba8489ccfd 100644 --- a/modules/puzzle/src/main/PuzzleReplay.scala +++ b/modules/puzzle/src/main/PuzzleReplay.scala @@ -38,7 +38,7 @@ final class PuzzleReplayApi( ): Fu[Option[(Puzzle, PuzzleReplay)]] = maybeDays map { days => replays.getFuture(user.id, _ => createReplayFor(user, days, theme)) flatMap { current => - if (current.days == days && current.theme == theme && current.remaining.nonEmpty) fuccess(current) + if current.days == days && current.theme == theme && current.remaining.nonEmpty then fuccess(current) else createReplayFor(user, days, theme) tap { replays.put(user.id, _) } } flatMap { replay => replay.remaining.headOption so { id => @@ -51,8 +51,7 @@ final class PuzzleReplayApi( angle.asTheme so { theme => replays.getIfPresent(round.userId) so { _ map { replay => - if (replay.days == days && replay.theme == theme) - replays.put(round.userId, fuccess(replay.step)) + if replay.days == days && replay.theme == theme then replays.put(round.userId, fuccess(replay.step)) } } } @@ -83,7 +82,7 @@ final class PuzzleReplayApi( $doc( "$match" -> $doc( $expr { - if (theme == PuzzleTheme.mix.key) $doc("$eq" -> $arr("$_id", "$$pid")) + if theme == PuzzleTheme.mix.key then $doc("$eq" -> $arr("$_id", "$$pid")) else $doc( $and( diff --git a/modules/puzzle/src/main/PuzzleSelector.scala b/modules/puzzle/src/main/PuzzleSelector.scala index 57931d48b71cc..c8fa839f974dc 100644 --- a/modules/puzzle/src/main/PuzzleSelector.scala +++ b/modules/puzzle/src/main/PuzzleSelector.scala @@ -122,8 +122,9 @@ final class PuzzleSelector( .getAsOpt[List[Puzzle]]("puzzle") .flatMap(_.headOption) .fold[NextPuzzleResult](PuzzleMissing(puzzleId)): puzzle => - if (session.settings.color.exists(puzzle.color !=)) WrongColor(puzzle) - else if (doc.getAsOpt[List[Bdoc]]("round").exists(_.nonEmpty)) PuzzleAlreadyPlayed(puzzle) + if session.settings.color.exists(puzzle.color !=) then WrongColor(puzzle) + else if doc.getAsOpt[List[Bdoc]]("round").exists(_.nonEmpty) then + PuzzleAlreadyPlayed(puzzle) else PuzzleFound(puzzle) .monValue: result => _.puzzle.selector.nextPuzzleResult( diff --git a/modules/puzzle/src/main/PuzzleSession.scala b/modules/puzzle/src/main/PuzzleSession.scala index aa55553f50003..5b31535c4b6fc 100644 --- a/modules/puzzle/src/main/PuzzleSession.scala +++ b/modules/puzzle/src/main/PuzzleSession.scala @@ -46,8 +46,7 @@ final class PuzzleSessionApi(pathApi: PuzzlePathApi, cacheApi: CacheApi)(using E _ map { session => // yes, even if the completed puzzle was not the current session puzzle // in that case we just skip a puzzle on the path, which doesn't matter - if (session.path.angle == angle) - sessions.put(round.userId, fuccess(session.next)) + if session.path.angle == angle then sessions.put(round.userId, fuccess(session.next)) } } diff --git a/modules/puzzle/src/main/PuzzleStreak.scala b/modules/puzzle/src/main/PuzzleStreak.scala index 8c92c2b5b2c01..d6b992d6473f8 100644 --- a/modules/puzzle/src/main/PuzzleStreak.scala +++ b/modules/puzzle/src/main/PuzzleStreak.scala @@ -44,7 +44,7 @@ final class PuzzleStreakApi(colls: PuzzleColls, cacheApi: CacheApi)(using Execut Facet( buckets.map { case (rating, nbPuzzles) => val (tier, samples, deviation) = - if (rating > 2300) (PuzzleTier.good, 5, 110) else (PuzzleTier.top, 1, 85) + if rating > 2300 then (PuzzleTier.good, 5, 110) else (PuzzleTier.top, 1, 85) rating.toString -> List( Match( $doc( @@ -95,9 +95,8 @@ final class PuzzleStreakApi(colls: PuzzleColls, cacheApi: CacheApi)(using Execut private def monitor(puzzles: List[Puzzle]): Unit = val nb = puzzles.size lila.mon.streak.selector.count.record(nb) - if (nb < poolSize * 0.9) - logger.warn(s"Streak selector wanted $poolSize puzzles, only got $nb") - if (nb > 1) + if nb < poolSize * 0.9 then logger.warn(s"Streak selector wanted $poolSize puzzles, only got $nb") + if nb > 1 then val rest = puzzles.toVector drop 1 lila.common.Maths.mean(rest.map(_.glicko.intRating.value)) foreach { r => lila.mon.streak.selector.rating.record(r.toInt).unit diff --git a/modules/puzzle/src/main/PuzzleTier.scala b/modules/puzzle/src/main/PuzzleTier.scala index 1b498cfd5daec..690436decc9d2 100644 --- a/modules/puzzle/src/main/PuzzleTier.scala +++ b/modules/puzzle/src/main/PuzzleTier.scala @@ -8,11 +8,11 @@ enum PuzzleTier: object PuzzleTier: def stepDown(tier: PuzzleTier): Option[PuzzleTier] = - if (tier == top) good.some - else if (tier == good) all.some + if tier == top then good.some + else if tier == good then all.some else none def from(tier: String) = - if (tier == top.toString) top - else if (tier == good.toString) good + if tier == top.toString then top + else if tier == good.toString then good else all diff --git a/modules/puzzle/src/main/PuzzleTrust.scala b/modules/puzzle/src/main/PuzzleTrust.scala index b6734eb2c8ddb..05f02eb357077 100644 --- a/modules/puzzle/src/main/PuzzleTrust.scala +++ b/modules/puzzle/src/main/PuzzleTrust.scala @@ -11,7 +11,7 @@ final private class PuzzleTrustApi(colls: PuzzleColls, perfsRepo: UserPerfsRepo) .flatMap: user => val w = base(user) + { // more trust when vote != win - if (vote == round.win.value) -2 else 2 + if vote == round.win.value then -2 else 2 } // distrust provisional ratings and distant ratings (w > 0) @@ -63,10 +63,10 @@ final private class PuzzleTrustApi(colls: PuzzleColls, perfsRepo: UserPerfsRepo) private def patronBonus(user: User) = (~user.planMonths * 5) atMost 15 private def modBonus(user: User) = - if (user.roles.exists(_ contains "ROLE_PUZZLE_CURATOR")) 100 - else if (user.isAdmin) 50 - else if (user.isVerified) 30 + if user.roles.exists(_ contains "ROLE_PUZZLE_CURATOR") then 100 + else if user.isAdmin then 50 + else if user.isVerified then 30 else 0 private def lameBonus(user: User) = - if (user.lameOrTroll) -30 else 0 + if user.lameOrTroll then -30 else 0 diff --git a/modules/racer/src/main/RacerApi.scala b/modules/racer/src/main/RacerApi.scala index c1373e58ff3c9..ab1f55019c782 100644 --- a/modules/racer/src/main/RacerApi.scala +++ b/modules/racer/src/main/RacerApi.scala @@ -72,14 +72,13 @@ final class RacerApi( def makePlayer(id: RacerPlayer.Id) = RacerPlayer.make(id, RacerPlayer.Id.userIdOf(id).map(lightUser)) - def join(id: RacerRace.Id, playerId: RacerPlayer.Id): Option[RacerRace] = { + def join(id: RacerRace.Id, playerId: RacerPlayer.Id): Option[RacerRace] = val player = makePlayer(playerId) get(id).flatMap(_ join player) map { r => val race = (r.isLobby so doStart(r)) | r saveAndPublish(race) race } - } private[racer] def manualStart(race: RacerRace): Unit = !race.isLobby so { doStart(race) foreach saveAndPublish @@ -107,7 +106,7 @@ final class RacerApi( } def registerPlayerScore(id: RacerRace.Id, player: RacerPlayer.Id, score: Int): Unit = - if (score > 160) logger.warn(s"$id $player score: $score") + if score > 160 then logger.warn(s"$id $player score: $score") else get(id).flatMap(_.registerScore(player, score)) foreach saveAndPublish private def save(race: RacerRace): Unit = @@ -121,4 +120,4 @@ final class RacerApi( // work around circular dependency private var socket: Option[RacerSocket] = None - private[racer] def registerSocket(s: RacerSocket) = { socket = s.some } + private[racer] def registerSocket(s: RacerSocket) = socket = s.some diff --git a/modules/racer/src/main/RacerBsonHandlers.scala b/modules/racer/src/main/RacerBsonHandlers.scala index 298a895a8657d..859056aea6b41 100644 --- a/modules/racer/src/main/RacerBsonHandlers.scala +++ b/modules/racer/src/main/RacerBsonHandlers.scala @@ -10,11 +10,11 @@ import lila.storm.StormPuzzle private object RacerBsonHandlers: given BSONDocumentReader[StormPuzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId]("_id") fen <- r.getAsTry[Fen.Epd]("fen") lineStr <- r.getAsTry[String]("line") line <- lineStr.split(' ').toList.flatMap(Uci.Move.apply).toNel.toTry("Empty move list?!") glicko <- r.getAsTry[Bdoc]("glicko") rating <- glicko.getAsTry[Double]("r") - } yield StormPuzzle(id, fen, line, IntRating(rating.toInt)) + yield StormPuzzle(id, fen, line, IntRating(rating.toInt)) diff --git a/modules/racer/src/main/RacerPlayer.scala b/modules/racer/src/main/RacerPlayer.scala index e8f2e841552f3..105f105abb86f 100644 --- a/modules/racer/src/main/RacerPlayer.scala +++ b/modules/racer/src/main/RacerPlayer.scala @@ -18,7 +18,7 @@ object RacerPlayer: case Anon(sessionId: String) object Id: def apply(str: String) = - if (str startsWith "@") Anon(str drop 1) + if str startsWith "@" then Anon(str drop 1) else User(UserId(str)) def userIdOf(id: Id) = id match case User(uid) => uid.some diff --git a/modules/racer/src/main/RacerRace.scala b/modules/racer/src/main/RacerRace.scala index b3ee851db442c..6fa1682ac504d 100644 --- a/modules/racer/src/main/RacerRace.scala +++ b/modules/racer/src/main/RacerRace.scala @@ -33,7 +33,7 @@ case class RacerRace( ) def startCountdown: Option[RacerRace] = - startsAt.isEmpty && players.size > (if (isLobby) 2 else 1) option + startsAt.isEmpty && players.size > (if isLobby then 2 else 1) option copy(startsAt = nowInstant.plusSeconds(countdownSeconds).some) def startsInMillis = startsAt.map(d => d.toMillis - nowMillis) diff --git a/modules/rating/src/main/Glicko.scala b/modules/rating/src/main/Glicko.scala index 1e7f090486de0..3064c670d8183 100644 --- a/modules/rating/src/main/Glicko.scala +++ b/modules/rating/src/main/Glicko.scala @@ -19,7 +19,7 @@ case class Glicko( def rankable(variant: chess.variant.Variant) = deviation <= { - if (variant.standard) Glicko.standardRankableDeviation + if variant.standard then Glicko.standardRankableDeviation else Glicko.variantRankableDeviation } def provisional = RatingProvisional(deviation >= Glicko.provisionalDeviation) @@ -46,8 +46,8 @@ case class Glicko( ) def average(other: Glicko, weight: Float = 0.5f) = - if (weight >= 1) other - else if (weight <= 0) this + if weight >= 1 then other + else if weight <= 0 then this else Glicko( rating = rating * (1 - weight) + other.rating * weight, diff --git a/modules/rating/src/main/Perf.scala b/modules/rating/src/main/Perf.scala index 7752b41e61c0f..f658e2f1e1a63 100644 --- a/modules/rating/src/main/Perf.scala +++ b/modules/rating/src/main/Perf.scala @@ -59,7 +59,7 @@ case class Perf( ) private def updateRecentWith(glicko: Glicko) = - if (nb < 10) recent + if nb < 10 then recent else (glicko.intRating :: recent) take Perf.recentMaxSize def clearRecent = copy(recent = Nil) diff --git a/modules/rating/src/main/RatingFactor.scala b/modules/rating/src/main/RatingFactor.scala index cddedf37dfeeb..087cc700703e9 100644 --- a/modules/rating/src/main/RatingFactor.scala +++ b/modules/rating/src/main/RatingFactor.scala @@ -20,10 +20,10 @@ object RatingFactor extends OpaqueDouble[RatingFactor]: private def read(s: String): RatingFactors = s.split(separator).toList.map(_.trim.split('=')) flatMap { case Array(ptk, fs) => - for { + for pt <- PerfType(Perf.Key(ptk)) f <- fs.toDoubleOption - } yield pt -> RatingFactor(f) + yield pt -> RatingFactor(f) case _ => None } toMap diff --git a/modules/rating/src/main/RatingRange.scala b/modules/rating/src/main/RatingRange.scala index 44ad596c17fc1..71793c07997de 100644 --- a/modules/rating/src/main/RatingRange.scala +++ b/modules/rating/src/main/RatingRange.scala @@ -29,16 +29,16 @@ object RatingRange: def readRating(str: String) = IntRating from str.toIntOption // ^\d{3,4}\-\d{3,4}$ - def apply(from: String): Option[RatingRange] = for { + def apply(from: String): Option[RatingRange] = for min <- readRating(from.takeWhile('-' !=)) if acceptable(min) max <- readRating(from.dropWhile('-' !=).tail) if acceptable(max) if min < max - } yield RatingRange(min, max) + yield RatingRange(min, max) def apply(rating: IntRating, deltaMin: Option[String], deltaMax: Option[String]): Option[RatingRange] = - for { + for dmin <- deltaMin.flatMap(_.toIntOption) min = rating + dmin if acceptable(min) @@ -46,14 +46,14 @@ object RatingRange: max = rating + dmax if acceptable(max) if min < max - } yield RatingRange(min, max) + yield RatingRange(min, max) def orDefault(from: String) = apply(from) | default def orDefault(rating: Option[IntRating], deltaMin: Option[String], deltaMax: Option[String]) = rating.flatMap(r => apply(r, deltaMin, deltaMax)) | default def noneIfDefault(from: String) = - if (from == default.toString) none + if from == default.toString then none else apply(from).filter(_ != default) def valid(from: String) = apply(from).isDefined diff --git a/modules/rating/src/main/RatingRegulator.scala b/modules/rating/src/main/RatingRegulator.scala index 58cdf7e324ffa..d1f53c97c550c 100644 --- a/modules/rating/src/main/RatingRegulator.scala +++ b/modules/rating/src/main/RatingRegulator.scala @@ -8,10 +8,10 @@ object RatingRegulator: } private def apply(factor: RatingFactor, perfType: PerfType, before: Perf, after: Perf): Perf = - if ({ + if { (after.nb == before.nb + 1) && // after playing one game (after.glicko.rating > before.glicko.rating) // and gaining rating - }) + } then val diff = after.glicko.rating - before.glicko.rating val extra = diff * (factor.value - 1) lila.mon.rating.regulator.micropoints(perfType.key.value).record((extra * 1000 * 1000).toLong) diff --git a/modules/rating/src/main/glicko2/RatingCalculator.scala b/modules/rating/src/main/glicko2/RatingCalculator.scala index e816d70b731b4..b6062ebc7587b 100644 --- a/modules/rating/src/main/glicko2/RatingCalculator.scala +++ b/modules/rating/src/main/glicko2/RatingCalculator.scala @@ -44,9 +44,9 @@ final class RatingCalculator( val players = results.getParticipants players foreach { player => val elapsedRatingPeriods = if skipDeviationIncrease then 0 else 1 - if (results.getResults(player).sizeIs > 0) { + if results.getResults(player).sizeIs > 0 then calculateNewRating(player, results.getResults(player), elapsedRatingPeriods) - } else { + else { // if a player does not compete during the rating period, then only Step 6 applies. // the player's rating and volatility parameters remain the same but deviation increases player.workingRating = player.getGlicko2Rating @@ -74,9 +74,7 @@ final class RatingCalculator( val interval = java.time.Duration.between(periodEnd, ratingPeriodEndDate) elapsedRatingPeriods = interval.toMillis * ratingPeriodsPerMilli } - if (reverse) { - elapsedRatingPeriods = -elapsedRatingPeriods - } + if reverse then elapsedRatingPeriods = -elapsedRatingPeriods val newRD = calculateNewRD(player.getGlicko2RatingDeviation, player.volatility, elapsedRatingPeriods) convertRatingDeviationToOriginalGlickoScale(newRD) @@ -96,16 +94,14 @@ final class RatingCalculator( // step 5.2 - set the initial values of the iterative algorithm to come in step 5.4 var A: Double = a var B: Double = 0 - if (Math.pow(delta, 2) > Math.pow(phi, 2) + v) { - B = Math.log(Math.pow(delta, 2) - Math.pow(phi, 2) - v) - } else { + if Math.pow(delta, 2) > Math.pow(phi, 2) + v then B = Math.log(Math.pow(delta, 2) - Math.pow(phi, 2) - v) + else { var k = 1d B = a - (k * Math.abs(tau)) - while (f(B, delta, phi, v, a, tau) < 0) { + while f(B, delta, phi, v, a, tau) < 0 do k = k + 1 B = a - (k * Math.abs(tau)) - } } // step 5.3 @@ -114,28 +110,24 @@ final class RatingCalculator( // step 5.4 var iterations = 0 - while (Math.abs(B - A) > CONVERGENCE_TOLERANCE && iterations < ITERATION_MAX) { + while Math.abs(B - A) > CONVERGENCE_TOLERANCE && iterations < ITERATION_MAX do iterations = iterations + 1 // println(String.format("%f - %f (%f) > %f", B, A, Math.abs(B - A), CONVERGENCE_TOLERANCE)) val C = A + (((A - B) * fA) / (fB - fA)) val fC = f(C, delta, phi, v, a, tau) - if (fC * fB <= 0) { + if fC * fB <= 0 then A = B fA = fB - } else { - fA = fA / 2.0 - } + else fA = fA / 2.0 B = C fB = fC - } - if (iterations == ITERATION_MAX) { + if iterations == ITERATION_MAX then println(String.format("Convergence fail at %d iterations", iterations)) println(player.toString()) results foreach println throw new RuntimeException("Convergence fail") - } val newSigma = Math.exp(A / 2.0) diff --git a/modules/rating/src/main/glicko2/Result.scala b/modules/rating/src/main/glicko2/Result.scala index 87cd674e3f0f4..d9c046187cd13 100644 --- a/modules/rating/src/main/glicko2/Result.scala +++ b/modules/rating/src/main/glicko2/Result.scala @@ -15,9 +15,9 @@ trait Result: // score from 0 (opponent wins) to 1 (player wins) class FloatingResult(player: Rating, opponent: Rating, score: Float) extends Result: - def getScore(p: Rating) = if (p == player) score else 1 - score + def getScore(p: Rating) = if p == player then score else 1 - score - def getOpponent(p: Rating) = if (p == player) opponent else player + def getOpponent(p: Rating) = if p == player then opponent else player def participated(p: Rating) = p == player || p == opponent diff --git a/modules/rating/src/main/package.scala b/modules/rating/src/main/package.scala index 83fd2c56429b6..d82793522c1b9 100644 --- a/modules/rating/src/main/package.scala +++ b/modules/rating/src/main/package.scala @@ -9,8 +9,7 @@ type RatingFactors = Map[lila.rating.PerfType, RatingFactor] given intZero: Zero[IntRating] = Zero(IntRating(0)) -val formMapping: play.api.data.Mapping[IntRating] = { +val formMapping: play.api.data.Mapping[IntRating] = import play.api.data.Forms.number import lila.common.Form.into number(min = Glicko.minRating.value, max = Glicko.maxRating.value).into[IntRating] -} diff --git a/modules/rating/src/test/RatingCalculatorTest.scala b/modules/rating/src/test/RatingCalculatorTest.scala index dfdcb1d3fee2e..3637b15664cda 100644 --- a/modules/rating/src/test/RatingCalculatorTest.scala +++ b/modules/rating/src/test/RatingCalculatorTest.scala @@ -3,7 +3,7 @@ package lila.rating import glicko2.* import chess.{ Color, White, Black } -class RatingCalculatorTest extends lila.common.LilaTest { +class RatingCalculatorTest extends lila.common.LilaTest: def updateRatings(wRating: Rating, bRating: Rating, winner: Option[Color]) = val result = winner match @@ -190,4 +190,3 @@ class RatingCalculatorTest extends lila.common.LilaTest { assertCloseTo(br.volatility, 0.062006, 0.000001d) } } -} diff --git a/modules/relation/src/main/SubscriptionRepo.scala b/modules/relation/src/main/SubscriptionRepo.scala index f72bbbacdcdc2..86259ada0d582 100644 --- a/modules/relation/src/main/SubscriptionRepo.scala +++ b/modules/relation/src/main/SubscriptionRepo.scala @@ -7,14 +7,14 @@ import lila.relation.RelationRepo.makeId final class SubscriptionRepo(colls: Colls, userRepo: lila.user.UserRepo)(using Executor -) { +): val coll = colls.subscription // for streaming, streamerId is the user UserId of the streamer being subscribed to def subscribersOnlineSince(streamerId: UserId, daysAgo: Int): Fu[List[UserId]] = coll .aggregateOne(_.sec): framework => - import framework._ + import framework.* Match($doc("s" -> streamerId)) -> List( PipelineOperator( $lookup.pipeline( @@ -55,4 +55,3 @@ final class SubscriptionRepo(colls: Colls, userRepo: lila.user.UserRepo)(using coll.distinctEasy[String, Set]("_id", $inIds(streamerIds.map(makeId(subscriber, _)))) map { ids => UserId from ids.flatMap(_.split('/').lift(1)) } -} diff --git a/modules/relay/src/main/BSONHandlers.scala b/modules/relay/src/main/BSONHandlers.scala index 2172bf214475e..9104f907f3747 100644 --- a/modules/relay/src/main/BSONHandlers.scala +++ b/modules/relay/src/main/BSONHandlers.scala @@ -35,7 +35,7 @@ object BSONHandlers: given BSONDocumentHandler[RelayTour] = Macros.handler - def readRoundWithTour(doc: Bdoc): Option[RelayRound.WithTour] = for { + def readRoundWithTour(doc: Bdoc): Option[RelayRound.WithTour] = for round <- doc.asOpt[RelayRound] tour <- doc.getAsOpt[RelayTour]("tour") - } yield RelayRound.WithTour(round, tour) + yield RelayRound.WithTour(round, tour) diff --git a/modules/relay/src/main/JsonView.scala b/modules/relay/src/main/JsonView.scala index c4d4074f87be6..0bde7b6c5c106 100644 --- a/modules/relay/src/main/JsonView.scala +++ b/modules/relay/src/main/JsonView.scala @@ -26,7 +26,7 @@ final class JsonView(baseUrl: BaseUrl, markup: RelayMarkup, leaderboardApi: Rela .add("markup" -> trs.tour.markup.map(markup(trs.tour))) .add("url" -> withUrls.option(s"$baseUrl/broadcast/${trs.tour.slug}/${trs.tour.id}")), "rounds" -> trs.rounds.map { round => - if (withUrls) withUrl(round withTour trs.tour) else apply(round) + if withUrls then withUrl(round withTour trs.tour) else apply(round) } ) diff --git a/modules/relay/src/main/RelayApi.scala b/modules/relay/src/main/RelayApi.scala index 0bee871f44375..c7ec4798ed4c2 100644 --- a/modules/relay/src/main/RelayApi.scala +++ b/modules/relay/src/main/RelayApi.scala @@ -160,7 +160,7 @@ final class RelayApi( def isOfficial(id: StudyId): Fu[Boolean] = roundRepo.coll .aggregateOne(): framework => - import framework._ + import framework.* Match($id(id)) -> List( PipelineOperator(tourRepo lookup "tourId"), UnwindField("tour"), diff --git a/modules/relay/src/main/RelayFetch.scala b/modules/relay/src/main/RelayFetch.scala index 93f99af75ac7c..e2ebb40e1bd08 100644 --- a/modules/relay/src/main/RelayFetch.scala +++ b/modules/relay/src/main/RelayFetch.scala @@ -80,10 +80,10 @@ final private class RelayFetch( case e: Exception => e.match { case SyncResult.Timeout => - if (rt.tour.official) logger.info(s"Sync timeout ${rt.round}") + if rt.tour.official then logger.info(s"Sync timeout ${rt.round}") SyncResult.Timeout case _ => - if (rt.tour.official) logger.info(s"Sync error ${rt.round} ${e.getMessage take 80}") + if rt.tour.official then logger.info(s"Sync error ${rt.round} ${e.getMessage take 80}") SyncResult.Error(e.getMessage) } -> rt.round.withSync(_ addLog SyncLog.event(0, e.some)) .map: (result, newRelay) => @@ -173,13 +173,12 @@ final private class RelayFetch( val number = i + 1 val gameDoc = makeGameDoc(number) gameDoc.format - .match { + .match case RelayFormat.DocFormat.Pgn => httpGetPgn(gameDoc.url) case RelayFormat.DocFormat.Json => httpGetJson[GameJson](gameDoc.url).recover { case _: Exception => GameJson(moves = Nil, result = none) } map { _.toPgn(pairing.tags) } - } .map(number -> _) .parallel .map { results => @@ -212,7 +211,7 @@ final private class RelayFetch( private[relay] object RelayFetch: def maxChapters(tour: RelayTour) = - lila.study.Study.maxChapters * (if (tour.official) 2 else 1) + lila.study.Study.maxChapters * (if tour.official then 2 else 1) private[relay] object DgtJson: case class PairingPlayer( @@ -267,7 +266,7 @@ private[relay] object RelayFetch: case (Success((acc, index)), pgn) => pgnCache.get(pgn) flatMap { f => val game = f(index) - if (game.isEmpty) Failure(LilaInvalid(s"Found an empty PGN at index $index")) + if game.isEmpty then Failure(LilaInvalid(s"Found an empty PGN at index $index")) else Success((acc :+ game, index + 1)) } case (acc, _) => acc diff --git a/modules/relay/src/main/RelayInputSanity.scala b/modules/relay/src/main/RelayInputSanity.scala index 04f1af1d32212..5258bc6d30d57 100644 --- a/modules/relay/src/main/RelayInputSanity.scala +++ b/modules/relay/src/main/RelayInputSanity.scala @@ -12,8 +12,8 @@ private object RelayInputSanity: extends Fail(s"Game ${gamePos + 1} matches with Chapter ${chapterPos + 1}") def apply(chapters: List[Chapter], games: RelayGames): Either[Fail, RelayGames] = { - if (chapters.isEmpty) Right(games) - else if (isValidTCEC(chapters, games)) Right(games) + if chapters.isEmpty then Right(games) + else if isValidTCEC(chapters, games) then Right(games) else val relayChapters: List[RelayChapter] = chapters.flatMap { chapter => chapter.relay map chapter.-> diff --git a/modules/relay/src/main/RelayPgnStream.scala b/modules/relay/src/main/RelayPgnStream.scala index 19854af7ea17f..5cab5b7f89dc4 100644 --- a/modules/relay/src/main/RelayPgnStream.scala +++ b/modules/relay/src/main/RelayPgnStream.scala @@ -38,7 +38,7 @@ final class RelayPgnStream( fileR.replaceAllIn(s"lichess_broadcast_${tour.slug}_${tour.id}_$date", "") def streamRoundGames(rt: RelayRound.WithTourAndStudy): Source[PgnStr, ?] = { - if (rt.relay.hasStarted) studyPgnDump.chaptersOf(rt.study, flags).throttle(16, 1 second) + if rt.relay.hasStarted then studyPgnDump.chaptersOf(rt.study, flags).throttle(16, 1 second) else Source.empty[PgnStr] } concat Source .queue[Set[StudyChapterId]](8, akka.stream.OverflowStrategy.dropHead) diff --git a/modules/relay/src/main/RelayPush.scala b/modules/relay/src/main/RelayPush.scala index 1d3b5d225e74e..897c993c39e06 100644 --- a/modules/relay/src/main/RelayPush.scala +++ b/modules/relay/src/main/RelayPush.scala @@ -13,11 +13,10 @@ final class RelayPush(sync: RelaySync, api: RelayApi)(using private val throttler = new lila.hub.EarlyMultiThrottler[RelayRoundId](logger) def apply(rt: RelayRound.WithTour, pgn: PgnStr): Fu[Option[String]] = - if (rt.round.sync.hasUpstream) - fuccess("The relay has an upstream URL, and cannot be pushed to.".some) + if rt.round.sync.hasUpstream then fuccess("The relay has an upstream URL, and cannot be pushed to.".some) else fuccess { - throttler(rt.round.id, if (rt.tour.official) 3.seconds else 7.seconds) { + throttler(rt.round.id, if rt.tour.official then 3.seconds else 7.seconds) { pushNow(rt, pgn) } none diff --git a/modules/relay/src/main/RelayRound.scala b/modules/relay/src/main/RelayRound.scala index 0b47948d1dc5f..2bb52fa2a6f4b 100644 --- a/modules/relay/src/main/RelayRound.scala +++ b/modules/relay/src/main/RelayRound.scala @@ -27,7 +27,7 @@ case class RelayRound( lazy val slug = val s = lila.common.String slugify name.value - if (s.isEmpty) "-" else s + if s.isEmpty then "-" else s def finish = copy( @@ -76,13 +76,13 @@ object RelayRound: def hasUpstream = upstream.isDefined def renew = - if (hasUpstream) copy(until = nowInstant.plusHours(1).some) + if hasUpstream then copy(until = nowInstant.plusHours(1).some) else pause def ongoing = until so nowInstant.isBefore def play = - if (hasUpstream) renew.copy(nextAt = nextAt orElse nowInstant.plusSeconds(3).some) + if hasUpstream then renew.copy(nextAt = nextAt orElse nowInstant.plusSeconds(3).some) else pause def pause = @@ -129,7 +129,7 @@ object RelayRound: def link: RelayRound def fullName = s"${tour.name} • ${display.name}" def path: String = - s"/broadcast/${tour.slug}/${if (link.slug == tour.slug) "-" else link.slug}/${link.id}" + s"/broadcast/${tour.slug}/${if link.slug == tour.slug then "-" else link.slug}/${link.id}" def path(chapterId: StudyChapterId): String = s"$path/$chapterId" case class WithTour(round: RelayRound, tour: RelayTour) extends AndTour: diff --git a/modules/relay/src/main/RelayRoundForm.scala b/modules/relay/src/main/RelayRoundForm.scala index dc0d472ea2298..9b3e036fc91be 100644 --- a/modules/relay/src/main/RelayRoundForm.scala +++ b/modules/relay/src/main/RelayRoundForm.scala @@ -114,7 +114,7 @@ object RelayRoundForm: name = name, caption = caption, sync = makeSync(me).pipe: sync => - if (relay.sync.playing) sync.play else sync, + if relay.sync.playing then sync.play else sync, startsAt = startsAt, finished = relay.finished && startsAt.fold(true)(_.isBeforeNow) ) diff --git a/modules/relay/src/main/RelaySync.scala b/modules/relay/src/main/RelaySync.scala index b6ce6402f73b2..c69f023cae1e8 100644 --- a/modules/relay/src/main/RelaySync.scala +++ b/modules/relay/src/main/RelaySync.scala @@ -62,7 +62,7 @@ final private class RelaySync( chapters: List[Chapter], nbGames: Int ): Option[Chapter] = - if (nbGames == 1 || game.looksLikeLichess) chapters find game.staticTagsMatch + if nbGames == 1 || game.looksLikeLichess then chapters find game.staticTagsMatch else chapters.find(_.relay.exists(_.index == game.index)) private def updateChapter( @@ -119,7 +119,7 @@ final private class RelaySync( .some )(who) inject position + n } inject { - if (chapter.root.children.nodes.isEmpty && node.mainline.nonEmpty) + if chapter.root.children.nodes.isEmpty && node.mainline.nonEmpty then studyApi.reloadChapters(study) node.mainline.size } @@ -132,7 +132,7 @@ final private class RelaySync( game: RelayGame ): Fu[Boolean] = val gameTags = game.tags.value.foldLeft(Tags(Nil)): (newTags, tag) => - if (!chapter.tags.value.has(tag)) newTags + tag + if !chapter.tags.value.has(tag) then newTags + tag else newTags val newEndTag = game.end .ifFalse(gameTags(_.Result).isDefined) @@ -142,7 +142,7 @@ final private class RelaySync( val chapterNewTags = tags.value.foldLeft(chapter.tags): (chapterTags, tag) => PgnTags(chapterTags + tag) (chapterNewTags != chapter.tags) so { - if (vs(chapterNewTags) != vs(chapter.tags)) + if vs(chapterNewTags) != vs(chapter.tags) then logger.info(s"Update ${showSC(study, chapter)} tags '${vs(chapter.tags)}' -> '${vs(chapterNewTags)}'") studyApi.setTags( studyId = study.id, diff --git a/modules/relay/src/main/RelayTour.scala b/modules/relay/src/main/RelayTour.scala index 91726667c11c8..1c896350eca97 100644 --- a/modules/relay/src/main/RelayTour.scala +++ b/modules/relay/src/main/RelayTour.scala @@ -21,13 +21,13 @@ case class RelayTour( lazy val slug = val s = lila.common.String slugify name - if (s.isEmpty) "-" else s + if s.isEmpty then "-" else s def withRounds(rounds: List[RelayRound]) = RelayTour.WithRounds(this, rounds) def official = tier.isDefined - def reAssignIfOfficial = if (official) copy(ownerId = User.broadcasterId) else this + def reAssignIfOfficial = if official then copy(ownerId = User.broadcasterId) else this object RelayTour: diff --git a/modules/relay/src/main/SyncLog.scala b/modules/relay/src/main/SyncLog.scala index 88016caa43d4e..9c7a472d42af0 100644 --- a/modules/relay/src/main/SyncLog.scala +++ b/modules/relay/src/main/SyncLog.scala @@ -13,7 +13,7 @@ case class SyncLog(events: Vector[SyncLog.Event]) extends AnyVal: def add(event: SyncLog.Event) = copy( events = { - if (events.sizeIs > SyncLog.historySize) events drop 1 + if events.sizeIs > SyncLog.historySize then events drop 1 else events } :+ event ) diff --git a/modules/report/src/main/AutoAnalysis.scala b/modules/report/src/main/AutoAnalysis.scala index eed8ca4293534..240fff332f79c 100644 --- a/modules/report/src/main/AutoAnalysis.scala +++ b/modules/report/src/main/AutoAnalysis.scala @@ -11,17 +11,18 @@ final class AutoAnalysis( ): def apply(candidate: Report.Candidate): Funit = - if (candidate.isCheat) doItNow(candidate) - else if (candidate.isPrint) fuccess { - List(30, 90) foreach { minutes => - scheduler.scheduleOnce(minutes minutes) { doItNow(candidate).unit } + if candidate.isCheat then doItNow(candidate) + else if candidate.isPrint then + fuccess { + List(30, 90) foreach { minutes => + scheduler.scheduleOnce(minutes minutes) { doItNow(candidate).unit } + } } - } else funit private def doItNow(candidate: Report.Candidate) = gamesToAnalyse(candidate) map { games => - if (games.nonEmpty) + if games.nonEmpty then logger.info(s"Auto-analyse ${games.size} games after report by ${candidate.reporter.user.id}") games foreach { game => lila.mon.cheat.autoAnalysis("Report").increment() diff --git a/modules/report/src/main/Report.scala b/modules/report/src/main/Report.scala index 5e1f5c2c139a2..8bb0b97d976e8 100644 --- a/modules/report/src/main/Report.scala +++ b/modules/report/src/main/Report.scala @@ -30,7 +30,7 @@ case class Report( def add(atom: Atom) = atomBy(atom.by) .fold(copy(atoms = atom :: atoms)): existing => - if (existing.text contains atom.text) this + if existing.text contains atom.text then this else copy( atoms = { @@ -89,9 +89,9 @@ object Report: extension (a: Score) def +(s: Score): Score = a + s def color = - if (a >= 150) "red" - else if (a >= 100) "orange" - else if (a >= 50) "yellow" + if a >= 150 then "red" + else if a >= 100 then "orange" + else if a >= 50 then "yellow" else "green" def atLeast(s: Score): Score = math.max(a, s) def withinBounds: Score = a atLeast 5 atMost 100 diff --git a/modules/report/src/main/ReportApi.scala b/modules/report/src/main/ReportApi.scala index 43cedafefbc9e..809ef9106d835 100644 --- a/modules/report/src/main/ReportApi.scala +++ b/modules/report/src/main/ReportApi.scala @@ -59,14 +59,13 @@ final class ReportApi( .flatMap { prev => val report = Report.make(scored, prev) lila.mon.mod.report.create(report.reason.key, scored.score.value.toInt).increment() - if ( - report.isRecentComm && + if report.isRecentComm && report.score.value >= thresholds.discord() && prev.exists(_.score.value < thresholds.discord()) - ) ircApi.commReportBurst(c.suspect.user) + then ircApi.commReportBurst(c.suspect.user) coll.update.one($id(report.id), report, upsert = true).void >> autoAnalysis(candidate) >>- { - if (report.isCheat) + if report.isCheat then Bus.publish(lila.hub.actorApi.report.CheatReportCreated(report.user), "cheatReport") } } >>- @@ -223,7 +222,7 @@ final class ReportApi( yield open def reopenReports(suspect: Suspect): Funit = - for { + for all <- recent(suspect, 10) closed = all .filter(_.done.map(_.by) has User.lichessId.into(ModId)) @@ -236,7 +235,7 @@ final class ReportApi( multi = true ) .void - } yield () + yield () // `seriousness` depends on the number of previous warnings, and number of games throwed away def autoBoostReport(winnerId: UserId, loserId: UserId, seriousness: Int): Funit = @@ -244,7 +243,7 @@ final class ReportApi( userRepo.pair(winnerId, loserId) zip getLichessReporter flatMap { case ((isSame, Some((winner, loser))), reporter) if !winner.lame && !loser.lame => val loginsText = - if (isSame) "Found matching IP/print" + if isSame then "Found matching IP/print" else "No IP/print match found" create( Candidate( @@ -281,7 +280,7 @@ final class ReportApi( maxScoreCache.invalidateUnit() >>- lila.mon.mod.report.close.increment().unit - def autoProcess(sus: Suspect, rooms: Set[Room])(using Me.Id): Funit = { + def autoProcess(sus: Suspect, rooms: Set[Room])(using Me.Id): Funit = val selector = $doc( "user" -> sus.user.id, "room" $in rooms, @@ -290,7 +289,6 @@ final class ReportApi( doProcessReport(selector, unsetInquiry = true).void >>- maxScoreCache.invalidateUnit() >>- lila.mon.mod.report.close.increment().unit - } private def doProcessReport(selector: Bdoc, unsetInquiry: Boolean)(using me: Me.Id): Funit = coll.update @@ -435,7 +433,7 @@ final class ReportApi( opens <- findBest(nb, selectOpenInRoom(room, snoozedIds)) nbClosed = nb - opens.size closed <- - if (room.has(Room.Xfiles) || nbClosed < 1) fuccess(Nil) + if room.has(Room.Xfiles) || nbClosed < 1 then fuccess(Nil) else findRecent(nbClosed, closedSelect ++ roomSelect(room)) withNotes <- addSuspectsAndNotes(opens ++ closed) yield withNotes @@ -477,7 +475,7 @@ final class ReportApi( .sort(sortLastAtomAt) .cursor[Report](ReadPref.sec) .list(20) flatMap { reports => - if (reports.sizeIs < 4) fuccess(none) // not enough data to know + if reports.sizeIs < 4 then fuccess(none) // not enough data to know else val userIds = reports.map(_.user).distinct userRepo countEngines userIds map { nbEngines => @@ -563,7 +561,7 @@ final class ReportApi( id: String | Either[Report.Id, UserId] )(using mod: Me): Fu[(Option[Report], Option[Report])] = def findByUser(userId: UserId) = coll.one[Report]($doc("user" -> userId, "inquiry.mod" $exists true)) - for { + for report <- id match case Left(reportId) => coll.byId[Report](reportId) case Right(userId) => findByUser(userId) @@ -579,7 +577,7 @@ final class ReportApi( Report.Inquiry(mod.userId, nowInstant) ) .void - } yield (current, report.filter(_.inquiry.isEmpty)) + yield (current, report.filter(_.inquiry.isEmpty)) def toggleNext(room: Room)(using Me): Fu[Option[Report]] = workQueue: diff --git a/modules/report/src/main/ReportScore.scala b/modules/report/src/main/ReportScore.scala index 80dc2bddaa3a6..d48dcbaa95795 100644 --- a/modules/report/src/main/ReportScore.scala +++ b/modules/report/src/main/ReportScore.scala @@ -48,7 +48,7 @@ final private class ReportScore( private val gameRegex = ReportForm gameLinkRegex domain def dropScoreIfCheatReportHasNoAnalyzedGames(c: Report.Candidate.Scored): Fu[Report.Candidate.Scored] = - if (c.candidate.isCheat & !c.candidate.isIrwinCheat & !c.candidate.isKaladinCheat) + if c.candidate.isCheat & !c.candidate.isIrwinCheat & !c.candidate.isKaladinCheat then val gameIds = gameRegex.findAllMatchIn(c.candidate.text).toList.take(20).map(m => GameId(m.group(1))) def isUsable(gameId: GameId) = gameRepo analysed gameId map { _.exists(_.ply > 30) } gameIds diff --git a/modules/round/src/main/CorresAlarm.scala b/modules/round/src/main/CorresAlarm.scala index b13e64f1bd4d0..64847747d568b 100644 --- a/modules/round/src/main/CorresAlarm.scala +++ b/modules/round/src/main/CorresAlarm.scala @@ -27,7 +27,7 @@ final private class CorresAlarm( private given BSONDocumentHandler[Alarm] = Macros.handler Bus.subscribeFun("finishGame") { case lila.game.actorApi.FinishGame(game, _, _) => - if (game.hasCorrespondenceClock && !game.hasAi) coll.delete.one($id(game.id)).unit + if game.hasCorrespondenceClock && !game.hasAi then coll.delete.one($id(game.id)).unit } Bus.subscribeFun("moveEventCorres") { case lila.hub.actorApi.round.CorresMoveEvent(move, _, _, true, _) => diff --git a/modules/round/src/main/CorrespondenceEmail.scala b/modules/round/src/main/CorrespondenceEmail.scala index 9a5d180ec9913..354ce53e1364d 100644 --- a/modules/round/src/main/CorrespondenceEmail.scala +++ b/modules/round/src/main/CorrespondenceEmail.scala @@ -22,7 +22,7 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, def tick(): Unit = { val now = LocalTime.now - if (now.isAfter(runAfter) && now.isBefore(runBefore)) run() + if now.isAfter(runAfter) && now.isBefore(runBefore) then run() }.unit private def run() = @@ -67,7 +67,7 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, .documentSource() .mapConcat { doc => import lila.game.BSONHandlers.given - (for { + (for userId <- doc.getAsOpt[UserId]("_id") games <- doc.getAsOpt[List[Game]]("games") povs = games @@ -82,5 +82,5 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, pov.game.id ) } - } yield CorrespondenceOpponents(userId, opponents)).toList + yield CorrespondenceOpponents(userId, opponents)).toList } diff --git a/modules/round/src/main/Drawer.scala b/modules/round/src/main/Drawer.scala index 8bf19819e7a66..c4efe06ecfeb8 100644 --- a/modules/round/src/main/Drawer.scala +++ b/modules/round/src/main/Drawer.scala @@ -20,7 +20,7 @@ final private[round] class Drawer( def autoThreefold(game: Game): Fu[Option[Pov]] = game.drawable.so: Pov(game) .map: pov => - if (game.playerHasOfferedDrawRecently(pov.color)) fuccess(pov.some) + if game.playerHasOfferedDrawRecently(pov.color) then fuccess(pov.some) else pov.player.userId so { uid => prefApi.get(uid, _.autoThreefold) } map { autoThreefold => autoThreefold == Pref.AutoThreefold.ALWAYS || { @@ -51,7 +51,7 @@ final private[round] class Drawer( case _ => fuccess(List(Event.ReloadOwner)) def no(pov: Pov)(using proxy: GameProxy): Fu[Events] = pov.game.drawable.so: - pov match { + pov match case Pov(g, color) if pov.player.isOfferingDraw => proxy.save { messenger.system(g, trans.drawOfferCanceled.txt()) @@ -67,7 +67,7 @@ final private[round] class Drawer( } } inject List(Event.DrawOffer(by = none)) case _ => fuccess(List(Event.ReloadOwner)) - }: Fu[Events] + : Fu[Events] def claim(pov: Pov)(using GameProxy): Fu[Events] = (pov.game.drawable && pov.game.history.threefoldRepetition) so @@ -75,13 +75,13 @@ final private[round] class Drawer( def force(game: Game)(using GameProxy): Fu[Events] = finisher.other(game, _.Draw, None, None) - private def publishDrawOffer(game: Game): Unit = if (game.nonAi) - if (game.isCorrespondence) + private def publishDrawOffer(game: Game): Unit = if game.nonAi then + if game.isCorrespondence then Bus.publish( lila.hub.actorApi.round.CorresDrawOfferEvent(game.id), "offerEventCorres" ) - if (lila.game.Game.isBoardOrBotCompatible(game)) + if lila.game.Game.isBoardOrBotCompatible(game) then Bus.publish( lila.game.actorApi.BoardDrawOffer(game), lila.game.actorApi.BoardDrawOffer makeChan game.id diff --git a/modules/round/src/main/Env.scala b/modules/round/src/main/Env.scala index dac5a21d51d57..57192a652db45 100644 --- a/modules/round/src/main/Env.scala +++ b/modules/round/src/main/Env.scala @@ -66,8 +66,7 @@ final class Env( private val defaultGoneWeight = fuccess(1f) private def goneWeight(userId: UserId): Fu[Float] = playban.getRageSit(userId).dmap(_.goneWeight) private val goneWeightsFor: Game => Fu[(Float, Float)] = (game: Game) => - if (!game.playable || !game.hasClock || game.hasAi || !Uptime.startedSinceMinutes(1)) - fuccess(1f -> 1f) + if !game.playable || !game.hasClock || game.hasAi || !Uptime.startedSinceMinutes(1) then fuccess(1f -> 1f) else game.whitePlayer.userId.fold(defaultGoneWeight)(goneWeight) zip game.blackPlayer.userId.fold(defaultGoneWeight)(goneWeight) @@ -198,8 +197,8 @@ final class Env( val apiMoveStream = wire[ApiMoveStream] def resign(pov: Pov): Unit = - if (pov.game.abortableByUser) tellRound(pov.gameId, Abort(pov.playerId)) - else if (pov.game.resignable) tellRound(pov.gameId, Resign(pov.playerId)) + if pov.game.abortableByUser then tellRound(pov.gameId, Abort(pov.playerId)) + else if pov.game.resignable then tellRound(pov.gameId, Resign(pov.playerId)) trait SelfReportEndGame trait SelfReportMarkUser diff --git a/modules/round/src/main/Finisher.scala b/modules/round/src/main/Finisher.scala index 6be2e0040210d..76c8a4d184606 100644 --- a/modules/round/src/main/Finisher.scala +++ b/modules/round/src/main/Finisher.scala @@ -42,10 +42,11 @@ final private class Finisher( } def outOfTime(game: Game)(using GameProxy): Fu[Events] = - if (!game.isCorrespondence && !Uptime.startedSinceSeconds(120) && game.movedAt.isBefore(Uptime.startedAt)) + if !game.isCorrespondence && !Uptime.startedSinceSeconds(120) && game.movedAt.isBefore(Uptime.startedAt) + then logger.info(s"Aborting game last played before JVM boot: ${game.id}") other(game, _.Aborted, none) - else if (game.player(!game.player.color).isOfferingDraw) + else if game.player(!game.player.color).isOfferingDraw then apply(game, _.Draw, None, Messenger.SystemMessage.Persistent(trans.drawOfferAccepted.txt()).some) else val winner = Some(!game.player.color) ifFalse game.situation.opponentHasInsufficientMaterial @@ -58,7 +59,8 @@ final private class Finisher( game.playerWhoDidNotMove.so: culprit => lila.mon.round.expiration.count.increment() playban.noStart(Pov(game, culprit)) - if (game.isMandatory || game.metadata.hasRule(_.NoAbort)) apply(game, _.NoStart, Some(!culprit.color)) + if game.isMandatory || game.metadata.hasRule(_.NoAbort) then + apply(game, _.NoStart, Some(!culprit.color)) else apply(game, _.Aborted, None, Messenger.SystemMessage.Persistent("Game aborted by server").some) def other( @@ -69,7 +71,7 @@ final private class Finisher( )(using GameProxy): Fu[Events] = apply(game, status, winner, message) >>- playban.other(game, status, winner).unit - private def recordLagStats(game: Game) = for { + private def recordLagStats(game: Game) = for clock <- game.clock player <- clock.players.all lt = player.lag @@ -82,7 +84,7 @@ final private class Finisher( compEstStdErr <- lt.compEstStdErr quotaStr = f"${lt.quotaGain.centis / 10}%02d" compEstOvers = lt.compEstOvers.centis - } { + do import lila.mon.round.move.{ lag as lRec } lRec.mean.record(Math.round(10 * mean)) lRec.stdDev.record(Math.round(10 * sd)) @@ -96,7 +98,6 @@ final private class Finisher( case h: DecayingStats => lRec.compDeviation.record(h.deviation.toInt) lRec.compEstStdErr.record(Math.round(1000 * compEstStdErr)) lRec.compEstOverErr.record(Math.round(10f * compEstOvers / moves)) - } private def apply( prev: Game, @@ -107,7 +108,7 @@ final private class Finisher( val status = makeStatus(Status) val prog = lila.game.Progress(prev, prev.finish(status, winnerC)) val game = prog.game - if (game.nonAi && game.isCorrespondence) Color.all foreach notifier.gameEnd(prog.game) + if game.nonAi && game.isCorrespondence then Color.all foreach notifier.gameEnd(prog.game) lila.mon.game .finish( variant = game.variant.key.value, @@ -154,8 +155,8 @@ final private class Finisher( val totalTime = (game.hasClock && user.playTime.isDefined) so game.durationSeconds val tvTime = totalTime ifTrue recentTvGames.get(game.id) val result = - if (game.winnerUserId has user.id) 1 - else if (game.loserUserId has user.id) -1 + if game.winnerUserId has user.id then 1 + else if game.loserUserId has user.id then -1 else 0 userRepo .incNbGames(user.id, game.rated, game.hasAi, result = result, totalTime = totalTime, tvTime = tvTime) diff --git a/modules/round/src/main/ForecastApi.scala b/modules/round/src/main/ForecastApi.scala index 39ccdce864f76..78b53dbe833cd 100644 --- a/modules/round/src/main/ForecastApi.scala +++ b/modules/round/src/main/ForecastApi.scala @@ -38,7 +38,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): uciMove: String, steps: Forecast.Steps ): Funit = - if (!pov.isMyTurn) funit + if !pov.isMyTurn then funit else Uci.Move(uciMove).fold[Funit](fufail(lila.round.ClientError(s"Invalid move $uciMove on $pov"))) { uci => val promise = Promise[Unit]() @@ -58,7 +58,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): pov.forecastable so coll.byId[Forecast](pov.fullId) flatMap { case None => fuccess(none) case Some(fc) => - if (firstStep(fc.steps).exists(_.ply != pov.game.ply + 1)) clearPov(pov) inject none + if firstStep(fc.steps).exists(_.ply != pov.game.ply + 1) then clearPov(pov) inject none else fuccess(fc.some) } @@ -66,7 +66,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): pov.game.forecastable so coll.byId[Forecast](pov.fullId) flatMap { case None => fuccess(none) case Some(fc) => - if (firstStep(fc.steps).exists(_.ply != pov.game.ply)) clearPov(pov) inject none + if firstStep(fc.steps).exists(_.ply != pov.game.ply) then clearPov(pov) inject none else fuccess(fc.some) } diff --git a/modules/round/src/main/GameProxy.scala b/modules/round/src/main/GameProxy.scala index d4de4a8b6eb7a..dd8d944333bbc 100644 --- a/modules/round/src/main/GameProxy.scala +++ b/modules/round/src/main/GameProxy.scala @@ -21,7 +21,7 @@ final private class GameProxy( def save(progress: Progress): Funit = set(progress.game) dirtyProgress = dirtyProgress.fold(progress.dropEvents)(_ withGame progress.game).some - if (shouldFlushProgress(progress)) flushProgress() + if shouldFlushProgress(progress) then flushProgress() else fuccess(scheduleFlushProgress()) def update(f: Game => Game): Funit = diff --git a/modules/round/src/main/GameProxyRepo.scala b/modules/round/src/main/GameProxyRepo.scala index 79988d0c4ebaf..e5b85597f6982 100644 --- a/modules/round/src/main/GameProxyRepo.scala +++ b/modules/round/src/main/GameProxyRepo.scala @@ -24,7 +24,7 @@ final class GameProxyRepo( // get the proxied version of the game def upgradeIfPresent(game: Game): Fu[Game] = - if (game.finishedOrAborted) fuccess(game) + if game.finishedOrAborted then fuccess(game) else roundSocket upgradeIfPresent game def upgradeIfPresent(pov: Pov): Fu[Pov] = diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index 2908682f84929..5024dbb65f744 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -97,7 +97,7 @@ final class JsonView( "coords" -> pref.coords, "resizeHandle" -> pref.resizeHandle, "replay" -> pref.replay, - "autoQueen" -> (if (pov.game.variant == chess.variant.Antichess) Pref.AutoQueen.NEVER + "autoQueen" -> (if pov.game.variant == chess.variant.Antichess then Pref.AutoQueen.NEVER else pref.autoQueen), "clockTenths" -> pref.clockTenths, "moveEvent" -> pref.moveEvent @@ -321,7 +321,7 @@ final class JsonView( private def animationMillis(pov: Pov, pref: Pref) = pref.animationMillis * { - if (pov.game.finished) 1 + if pov.game.finished then 1 else math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2)) } diff --git a/modules/round/src/main/Messenger.scala b/modules/round/src/main/Messenger.scala index d10cb168aa2b1..e4aeb938fa0b9 100644 --- a/modules/round/src/main/Messenger.scala +++ b/modules/round/src/main/Messenger.scala @@ -17,11 +17,12 @@ final class Messenger(api: ChatApi): case Messenger.SystemMessage.Persistent(msg) => system(persistent = true)(game, msg) case Messenger.SystemMessage.Volatile(msg) => system(persistent = false)(game, msg) - def system(persistent: Boolean)(game: Game, message: String): Unit = if (game.nonAi) { - api.userChat.volatile(chatWatcherId(game.id into ChatId), message, _.Round) - if (persistent) api.userChat.system(game.id into ChatId, message, _.Round) - else api.userChat.volatile(game.id into ChatId, message, _.Round) - }.unit + def system(persistent: Boolean)(game: Game, message: String): Unit = if game.nonAi then + { + api.userChat.volatile(chatWatcherId(game.id into ChatId), message, _.Round) + if persistent then api.userChat.system(game.id into ChatId, message, _.Round) + else api.userChat.volatile(game.id into ChatId, message, _.Round) + }.unit def watcher(gameId: GameId, userId: UserId, text: String) = api.userChat.write(gameWatcherId(gameId), userId, text, PublicSource.Watcher(gameId).some, _.Round) diff --git a/modules/round/src/main/Moretimer.scala b/modules/round/src/main/Moretimer.scala index 0fef17df54480..ae37d73c4b18e 100644 --- a/modules/round/src/main/Moretimer.scala +++ b/modules/round/src/main/Moretimer.scala @@ -52,8 +52,8 @@ final class Moretimer( p == Pref.Moretime.ALWAYS || (p == Pref.Moretime.CASUAL && game.casual) private def IfAllowed[A](game: Game)(f: => A): Fu[A] = - if (!game.playable) fufail(ClientError("[moretimer] game is over " + game.id)) - else if (!game.canTakebackOrAddTime || game.metadata.hasRule(_.NoGiveTime)) + if !game.playable then fufail(ClientError("[moretimer] game is over " + game.id)) + else if !game.canTakebackOrAddTime || game.metadata.hasRule(_.NoGiveTime) then fufail(ClientError("[moretimer] game disallows it " + game.id)) else isAllowedByPrefs(game) flatMap { diff --git a/modules/round/src/main/NoteApi.scala b/modules/round/src/main/NoteApi.scala index 079e36df471e5..7e0b247e01375 100644 --- a/modules/round/src/main/NoteApi.scala +++ b/modules/round/src/main/NoteApi.scala @@ -14,7 +14,7 @@ final class NoteApi(coll: Coll)(using Executor): coll.primitiveOne[String]($id(makeId(gameId, userId)), noteField) dmap (~_) def set(gameId: GameId, userId: UserId, text: String) = { - if (text.isEmpty) coll.delete.one($id(makeId(gameId, userId))) + if text.isEmpty then coll.delete.one($id(makeId(gameId, userId))) else coll.update.one( $id(makeId(gameId, userId)), diff --git a/modules/round/src/main/PerfsUpdater.scala b/modules/round/src/main/PerfsUpdater.scala index a2f03b0715401..34fba5ed555dc 100644 --- a/modules/round/src/main/PerfsUpdater.scala +++ b/modules/round/src/main/PerfsUpdater.scala @@ -171,4 +171,4 @@ final class PerfsUpdater( classical = r(PT.Classical, perfs.classical, perfs1.classical), correspondence = r(PT.Correspondence, perfs.correspondence, perfs1.correspondence) ) - if (isStd) perfs2.updateStandard else perfs2 + if isStd then perfs2.updateStandard else perfs2 diff --git a/modules/round/src/main/Player.scala b/modules/round/src/main/Player.scala index 7746207807f0d..a5d3078e6a2fc 100644 --- a/modules/round/src/main/Player.scala +++ b/modules/round/src/main/Player.scala @@ -74,24 +74,25 @@ final private class Player( progress: Progress, moveOrDrop: MoveOrDrop )(using GameProxy): Fu[Events] = - if (pov.game.hasAi) uciMemo.add(pov.game, moveOrDrop) + if pov.game.hasAi then uciMemo.add(pov.game, moveOrDrop) notifyMove(moveOrDrop, progress.game) - if (progress.game.finished) moveFinish(progress.game) dmap { progress.events ::: _ } + if progress.game.finished then moveFinish(progress.game) 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 (progress.game.forecastable) moveOrDrop.move.foreach { move => - round ! ForecastPlay(move) - } + if progress.game.playableByAi then requestFishnet(progress.game, round) + if pov.opponent.isOfferingDraw then round ! DrawNo(pov.player.id) + if pov.player.isProposingTakeback then round ! TakebackNo(pov.player.id) + if progress.game.forecastable then + moveOrDrop.move.foreach { move => + round ! ForecastPlay(move) + } scheduleExpiration(progress.game) fuccess(progress.events) } private[round] def fishnet(game: Game, sign: String, uci: Uci)(using proxy: GameProxy): Fu[Events] = - if (game.playable && game.player.isAi) + if game.playable && game.player.isAi then uciMemo sign game flatMap { expectedSign => - if (expectedSign == sign) + if expectedSign == sign then applyUci(game, uci, blur = false, metrics = fishnetLag) .fold(errs => fufail(ClientError(ErrorStr raw errs)), fuccess) .flatMap { @@ -101,9 +102,8 @@ final private class Player( uciMemo.add(progress.game, moveOrDrop) >>- lila.mon.fishnet.move(~game.aiLevel).increment().unit >>- notifyMove(moveOrDrop, progress.game) >> { - if (progress.game.finished) moveFinish(progress.game) dmap { progress.events ::: _ } - else - fuccess(progress.events) + if progress.game.finished then moveFinish(progress.game) dmap { progress.events ::: _ } + else fuccess(progress.events) } } else @@ -122,7 +122,7 @@ final private class Player( private[round] def requestFishnet(game: Game, round: RoundAsyncActor): Funit = game.playableByAi.so: - if (game.ply <= fishnetPlayer.maxPlies) fishnetPlayer(game) + if game.ply <= fishnetPlayer.maxPlies then fishnetPlayer(game) else fuccess(round ! actorApi.round.ResignAi) private val fishnetLag = MoveMetrics(clientLag = Centis(5).some) @@ -168,7 +168,7 @@ final private class Player( Bus.publish(MoveGameEvent(game, moveEvent.fen, moveEvent.move), MoveGameEvent makeChan game.id) // publish correspondence moves - if (game.isCorrespondence && game.nonAi) + if game.isCorrespondence && game.nonAi then Bus.publish( CorresMoveEvent( move = moveEvent, diff --git a/modules/round/src/main/RecentTvGames.scala b/modules/round/src/main/RecentTvGames.scala index a50ba5f7929ac..6902cd39058dc 100644 --- a/modules/round/src/main/RecentTvGames.scala +++ b/modules/round/src/main/RecentTvGames.scala @@ -11,4 +11,4 @@ final class RecentTvGames(gameRepo: GameRepo): def put(game: Game) = gameRepo.setTv(game.id) - (if (game.speed <= chess.Speed.Bullet) fast else slow) put game.id + (if game.speed <= chess.Speed.Bullet then fast else slow) put game.id diff --git a/modules/round/src/main/Rematcher.scala b/modules/round/src/main/Rematcher.scala index b42a6c64dc3dc..92d2ed774f460 100644 --- a/modules/round/src/main/Rematcher.scala +++ b/modules/round/src/main/Rematcher.scala @@ -37,10 +37,9 @@ final private class Rematcher( def yes(pov: Pov): Fu[Events] = pov match case Pov(game, color) if game.playerCouldRematch => - if (isOffering(!pov) || game.opponent(color).isAi) + if isOffering(!pov) || game.opponent(color).isAi then rematches.getAcceptedId(game.id).fold(rematchJoin(pov))(rematchExists(pov)) - else if (!declined.get(pov.flip.fullId) && rateLimit.zero(pov.fullId)(true)) - rematchCreate(pov) + else if !declined.get(pov.flip.fullId) && rateLimit.zero(pov.fullId)(true) then rematchCreate(pov) else fuccess(List(Event.RematchOffer(by = none))) case _ => fuccess(List(Event.ReloadOwner)) @@ -72,12 +71,12 @@ final private class Rematcher( private def rematchJoin(pov: Pov): Fu[Events] = - def createGame(withId: Option[GameId]) = for { + def createGame(withId: Option[GameId]) = for nextGame <- returnGame(pov, withId).map(_.start) _ = rematches.accept(pov.gameId, nextGame.id) - _ = if (pov.game.variant == Chess960 && !chess960.get(pov.gameId)) chess960.put(nextGame.id) + _ = if pov.game.variant == Chess960 && !chess960.get(pov.gameId) then chess960.put(nextGame.id) _ <- gameRepo insertDenormalized nextGame - } yield + yield messenger.volatile(pov.game, trans.rematchOfferAccepted.txt()) onStart(nextGame.id) redirectEvents(nextGame) @@ -88,12 +87,12 @@ final private class Rematcher( case Some(Rematches.NextGame.Offered(_, id)) => createGame(id.some) private def returnGame(pov: Pov, withId: Option[GameId]): Fu[Game] = - for { + for initialFen <- gameRepo initialFen pov.game situation = initialFen.flatMap(Fen.readWithMoveNumber(pov.game.variant, _)) pieces = pov.game.variant match case Chess960 => - if (chess960 get pov.gameId) Chess960.pieces + if chess960 get pov.gameId then Chess960.pieces else situation.fold(Chess960.pieces)(_.situation.board.pieces) case FromPosition => situation.fold(Standard.pieces)(_.situation.board.pieces) case variant => variant.pieces @@ -126,7 +125,7 @@ final private class Rematcher( pgnImport = None ) game <- withId.fold(sloppy.withUniqueId) { id => fuccess(sloppy withId id) } - } yield game + yield game private def returnPlayer(game: Game, color: ChessColor, users: List[User.WithPerf]): lila.game.Player = game.opponent(color).aiLevel match diff --git a/modules/round/src/main/RoundAsyncActor.scala b/modules/round/src/main/RoundAsyncActor.scala index 1054351a93194..93b972777d8cb 100644 --- a/modules/round/src/main/RoundAsyncActor.scala +++ b/modules/round/src/main/RoundAsyncActor.scala @@ -53,7 +53,7 @@ final private[round] class RoundAsyncActor( def setOnline(on: Boolean): Unit = isLongGone foreach { _ so notifyGone(color, gone = false) } - offlineSince = if (on) None else offlineSince orElse nowMillis.some + offlineSince = if on then None else offlineSince orElse nowMillis.some bye = bye && !on def setBye(): Unit = bye = true @@ -62,7 +62,7 @@ final private[round] class RoundAsyncActor( private def timeoutMillis: Long = { val base = { - if (bye) RoundSocket.ragequitTimeout + if bye then RoundSocket.ragequitTimeout else proxy.withGameOptionSync { g => RoundSocket.povDisconnectTimeout(g pov color) @@ -76,7 +76,7 @@ final private[round] class RoundAsyncActor( } so !isHostingSimul def showMillisToGone: Fu[Option[Long]] = - if (botConnected) fuccess(none) + if botConnected then fuccess(none) else val now = nowMillis offlineSince @@ -87,13 +87,13 @@ final private[round] class RoundAsyncActor( !_ option (timeoutMillis + since - now) def setBotConnected(v: Boolean) = - botConnections = Math.max(0, botConnections + (if (v) 1 else -1)) + botConnections = Math.max(0, botConnections + (if v then 1 else -1)) end Player private val whitePlayer = Player(White) private val blackPlayer = Player(Black) - export proxy.{ game => getGame, update => updateGame } + export proxy.{ game as getGame, update as updateGame } val process: AsyncActor.ReceiveAsync = @@ -104,7 +104,7 @@ final private[round] class RoundAsyncActor( mightBeSimul = game.isSimul whitePlayer.goneWeight = whiteGoneWeight blackPlayer.goneWeight = blackGoneWeight - if (game.playableByAi) player.requestFishnet(game, this) + if game.playableByAi then player.requestFishnet(game, this) // socket stuff @@ -185,8 +185,8 @@ final private[round] class RoundAsyncActor( case p: HumanPlay => handle(p.playerId): pov => - if (pov.player.isAi) fufail(s"player $pov can't play AI") - else if (pov.game.outoftime(withGrace = true)) finisher.outOfTime(pov.game) + if pov.player.isAi then fufail(s"player $pov can't play AI") + else if pov.game.outoftime(withGrace = true) then finisher.outOfTime(pov.game) else recordLag(pov) player.human(p, this)(pov) @@ -204,7 +204,7 @@ final private[round] class RoundAsyncActor( case p: BotPlay => val res = proxy.withPov(p.playerId) { _.so: pov => - if (pov.game.outoftime(withGrace = true)) finisher.outOfTime(pov.game) + if pov.game.outoftime(withGrace = true) then finisher.outOfTime(pov.game) else player.bot(p.uci, this)(pov) } dmap publish p.promise.foreach(_ completeWith res) @@ -275,7 +275,7 @@ final private[round] class RoundAsyncActor( case Abandon => proxy.withGame: game => game.abandoned.so: - if (game.abortable) finisher.other(game, _.Aborted, None) + if game.abortable then finisher.other(game, _.Aborted, None) else finisher.other(game, _.Resign, Some(!game.player.color)) case DrawYes(playerId) => handle(playerId)(drawer.yes) @@ -350,8 +350,9 @@ final private[round] class RoundAsyncActor( case NoStart => handle: game => game.timeBeforeExpiration.exists(_.centis == 0) so { - if (game.isSwiss) game.startClock.so: g => - proxy save g inject List(Event.Reload) + if game.isSwiss then + game.startClock.so: g => + proxy save g inject List(Event.Reload) else finisher.noStart(game) } @@ -368,10 +369,10 @@ final private[round] class RoundAsyncActor( proxy.withGameOptionSync { g => (g.forceResignable && g.bothPlayersHaveMoved) so fuccess: Color.all.foreach: c => - if (!getPlayer(c).isOnline && getPlayer(!c).isOnline) + if !getPlayer(c).isOnline && getPlayer(!c).isOnline then getPlayer(c).showMillisToGone foreach { _.so: millis => - if (millis <= 0) notifyGone(c, gone = true) + if millis <= 0 then notifyGone(c, gone = true) else g.clock.exists(_.remainingTime(c).millis > millis + 3000) so notifyGoneIn(c, millis) } } | funit @@ -392,7 +393,7 @@ final private[round] class RoundAsyncActor( } private def recordLag(pov: Pov): Unit = - if ((pov.game.playedTurns.value & 30) == 10) + if (pov.game.playedTurns.value & 30) == 10 then // Triggers every 32 moves starting on ply 10. // i.e. 10, 11, 42, 43, 74, 75, ... for @@ -414,7 +415,7 @@ final private[round] class RoundAsyncActor( publishBoardBotGone(pov, millis.some) private def publishBoardBotGone(pov: Pov, millis: Option[Long]) = - if (lila.game.Game.isBoardOrBotCompatible(pov.game)) + if lila.game.Game.isBoardOrBotCompatible(pov.game) then lila.common.Bus.publish( lila.game.actorApi.BoardGone(pov, millis.map(m => (m.atLeast(0) / 1000).toInt)), lila.game.actorApi.BoardGone makeChan gameId diff --git a/modules/round/src/main/RoundSocket.scala b/modules/round/src/main/RoundSocket.scala index ea8f63e132048..3c99a30e6850e 100644 --- a/modules/round/src/main/RoundSocket.scala +++ b/modules/round/src/main/RoundSocket.scala @@ -245,7 +245,7 @@ final class RoundSocket( .andThen: case scala.util.Success(loadedIds) => val missingIds = gamePromises.keySet -- loadedIds - if (missingIds.nonEmpty) + if missingIds.nonEmpty then bootLog.warn: s"RoundSocket ${missingIds.size} round games could not be loaded: ${missingIds.take(20) mkString " "}" missingIds.foreach: id => @@ -367,12 +367,12 @@ object RoundSocket: case _ => RP.In.reader(raw) private def centis(s: String): Option[Centis] = - if (s == "-") none + if s == "-" then none else Centis from s.toIntOption private def readColor(s: String) = - if (s == "w") Some(White) - else if (s == "b") Some(Black) + if s == "w" then Some(White) + else if s == "b" then Some(Black) else None object Out: @@ -385,14 +385,14 @@ object RoundSocket: def tellVersion(roomId: RoomId, version: SocketVersion, e: Event) = val flags = StringBuilder(2) - if (e.watcher) flags += 's' - else if (e.owner) flags += 'p' + if e.watcher then flags += 's' + else if e.owner then flags += 'p' else e.only.map(_.fold('w', 'b')).orElse { e.moveBy.map(_.fold('W', 'B')) } foreach flags.+= - if (e.troll) flags += 't' - if (flags.isEmpty) flags += '-' + if e.troll then flags += 't' + if flags.isEmpty then flags += '-' s"r/ver $roomId $version $flags ${e.typ} ${e.data}" def tvSelect(gameId: GameId, speed: chess.Speed, data: JsObject) = diff --git a/modules/round/src/main/SelfReport.scala b/modules/round/src/main/SelfReport.scala index 7bff797cc6754..9b1758dce5ece 100644 --- a/modules/round/src/main/SelfReport.scala +++ b/modules/round/src/main/SelfReport.scala @@ -31,28 +31,27 @@ final class SelfReport( // Env.report.api.autoBotReport(u.id, referer, name) // } def doLog(): Unit = - if (name != "ceval") + if name != "ceval" then if logOnceEvery(ip.str) then lila.log("cheat").branch("jslog").info { s"$ip https://lichess.org/$fullId ${user.fold("anon")(_.id)} $name" } lila.mon.cheat.selfReport(name, userId.isDefined).increment() - if (fullId.value == "____________") doLog() + if fullId.value == "____________" then doLog() else proxyRepo .pov(fullId) .foreach: _.so: pov => - if (!known) doLog() + if !known then doLog() user.foreach: u => - if ( - endGameSetting.get().matches(name) || + if endGameSetting.get().matches(name) || (name.startsWith("soc") && ( name.contains("stockfish") || name.contains("userscript") || name.contains("__puppeteer_evaluation_script__") )) - ) tellRound(pov.gameId, lila.round.actorApi.round.Cheat(pov.color)) - if (markUserSetting.get().matches(name)) + then tellRound(pov.gameId, lila.round.actorApi.round.Cheat(pov.color)) + if markUserSetting.get().matches(name) then val rating = u.perfs.bestRating val hours = if rating > 2500 then 0 diff --git a/modules/round/src/main/StepBuilder.scala b/modules/round/src/main/StepBuilder.scala index 665c772a2c321..01e4e7115b0c9 100644 --- a/modules/round/src/main/StepBuilder.scala +++ b/modules/round/src/main/StepBuilder.scala @@ -45,7 +45,6 @@ object StepBuilder: } private val logChessError = (id: String) => - (err: chess.ErrorStr) => { - val path = if (id == "synthetic") "analysis" else id + (err: chess.ErrorStr) => + val path = if id == "synthetic" then "analysis" else id logger.info(s"https://lichess.org/$path ${err.value.linesIterator.toList.headOption | "?"}") - } diff --git a/modules/round/src/main/Takebacker.scala b/modules/round/src/main/Takebacker.scala index fffbeeb07406c..c157f5da12ebd 100644 --- a/modules/round/src/main/Takebacker.scala +++ b/modules/round/src/main/Takebacker.scala @@ -23,10 +23,9 @@ final private class Takebacker( pov match case Pov(game, color) if pov.opponent.isProposingTakeback => { - if ( - pov.opponent.proposeTakebackAt == pov.game.ply && + if pov.opponent.proposeTakebackAt == pov.game.ply && color == pov.opponent.proposeTakebackAt.turn - ) single(game) + then single(game) else double(game) } >>- publishTakeback(pov) dmap (_ -> situation.reset) case Pov(game, _) if pov.game.playableByAi => @@ -70,7 +69,7 @@ final private class Takebacker( game.canTakebackOrAddTime so isAllowedByPrefs(game) private def isAllowedByPrefs(game: Game): Fu[Boolean] = - if (game.hasAi) fuTrue + if game.hasAi then fuTrue else game.userIds.map { prefApi.get(_, (p: Pref) => p.takeback) @@ -81,8 +80,8 @@ final private 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 if (!game.canTakebackOrAddTime) fufail(ClientError("[takebacker] game disallows it " + game.id)) + if !game.playable then fufail(ClientError("[takebacker] game is over " + game.id)) + else if !game.canTakebackOrAddTime then fufail(ClientError("[takebacker] game disallows it " + game.id)) else isAllowedByPrefs(game) flatMap { if _ then f @@ -90,15 +89,15 @@ final private class Takebacker( } private def single(game: Game)(using GameProxy): Fu[Events] = - for { + for fen <- gameRepo initialFen game progress <- Rewind(game, fen).toFuture _ <- fuccess { uciMemo.drop(game, 1) } events <- saveAndNotify(progress) - } yield events + yield events private def double(game: Game)(using GameProxy): Fu[Events] = - for { + for fen <- gameRepo initialFen game prog1 <- Rewind(game, fen).toFuture prog2 <- Rewind(prog1.game, fen).toFuture dmap { progress => @@ -106,7 +105,7 @@ final private class Takebacker( } _ <- fuccess { uciMemo.drop(game, 2) } events <- saveAndNotify(prog2) - } yield events + yield events private def saveAndNotify(p1: Progress)(using proxy: GameProxy): Fu[Events] = val p2 = p1 + Event.Reload @@ -114,14 +113,14 @@ final private class Takebacker( proxy.save(p2) inject p2.events private def publishTakebackOffer(game: Game): Unit = - if (lila.game.Game.isBoardOrBotCompatible(game)) + if lila.game.Game.isBoardOrBotCompatible(game) then Bus.publish( lila.game.actorApi.BoardTakebackOffer(game), lila.game.actorApi.BoardTakebackOffer makeChan game.id ) private def publishTakeback(prevPov: Pov)(using proxy: GameProxy): Unit = - if (lila.game.Game.isBoardOrBotCompatible(prevPov.game)) + if lila.game.Game.isBoardOrBotCompatible(prevPov.game) then proxy .withPov(prevPov.color) { p => fuccess( diff --git a/modules/round/src/main/TreeBuilder.scala b/modules/round/src/main/TreeBuilder.scala index 7f875c973eb3e..42ecd927b58dd 100644 --- a/modules/round/src/main/TreeBuilder.scala +++ b/modules/round/src/main/TreeBuilder.scala @@ -27,7 +27,8 @@ object TreeBuilder: case (init, games, error) => error foreach logChessError(game.id) val openingOf: OpeningOf = - if (withFlags.opening && Variant.list.openingSensibleVariants(game.variant)) OpeningDb.findByEpdFen + if withFlags.opening && Variant.list.openingSensibleVariants(game.variant) then + OpeningDb.findByEpdFen else _ => None val fen = Fen write init val infos: Vector[Info] = analysis.so(_.infos.toVector) diff --git a/modules/round/src/main/TvBroadcast.scala b/modules/round/src/main/TvBroadcast.scala index beab1d33fadf6..1af2477ca6988 100644 --- a/modules/round/src/main/TvBroadcast.scala +++ b/modules/round/src/main/TvBroadcast.scala @@ -69,7 +69,7 @@ final private class TvBroadcast( ) clients.foreach { client => client.queue offer { - if (client.fromLichess) msg + if client.fromLichess then msg else feat.socketMsg } } diff --git a/modules/round/src/main/actorApi.scala b/modules/round/src/main/actorApi.scala index 491ff1ddc022f..2f697c19e9309 100644 --- a/modules/round/src/main/actorApi.scala +++ b/modules/round/src/main/actorApi.scala @@ -46,7 +46,8 @@ package round: case class DrawNo(playerId: GamePlayerId) case class TakebackYes(playerId: GamePlayerId) case class TakebackNo(playerId: GamePlayerId) - object Moretime { val defaultDuration = 15.seconds } + object Moretime: + val defaultDuration = 15.seconds case class Moretime(playerId: GamePlayerId, seconds: FiniteDuration = Moretime.defaultDuration) case object QuietFlag case class ClientFlag(color: Color, fromPlayerId: Option[GamePlayerId]) diff --git a/modules/search/src/main/Env.scala b/modules/search/src/main/Env.scala index a1881f49a2138..68bbbf5a0302c 100644 --- a/modules/search/src/main/Env.scala +++ b/modules/search/src/main/Env.scala @@ -23,5 +23,5 @@ final class Env( private def makeHttp(index: Index): ESClientHttp = wire[ESClientHttp] val makeClient = (index: Index) => - if (config.enabled) makeHttp(index) + if config.enabled then makeHttp(index) else wire[ESClientStub] diff --git a/modules/search/src/main/Range.scala b/modules/search/src/main/Range.scala index d460ec91d813b..acb35e9ee4d39 100644 --- a/modules/search/src/main/Range.scala +++ b/modules/search/src/main/Range.scala @@ -17,7 +17,7 @@ object Range: def apply[A](a: Option[A], b: Option[A])(using o: Ordering[A]): Range[A] = (a, b) match case (Some(aa), Some(bb)) => - if (o.lt(aa, bb)) new Range(a, b) + if o.lt(aa, bb) then new Range(a, b) else new Range(b, a) case (x, y) => new Range(x, y) diff --git a/modules/security/src/main/DisposableEmailAttempt.scala b/modules/security/src/main/DisposableEmailAttempt.scala index fd7accd84cc17..fa6dc362dcd47 100644 --- a/modules/security/src/main/DisposableEmailAttempt.scala +++ b/modules/security/src/main/DisposableEmailAttempt.scala @@ -25,12 +25,12 @@ final class DisposableEmailAttempt( _.expireAfterWrite(1 day).build() } - def onFail(form: Form[?], ip: IpAddress): Unit = for { + def onFail(form: Form[?], ip: IpAddress): Unit = for email <- form("email").value flatMap EmailAddress.from if email.domain.exists(disposableApi.apply) str <- form("username").value u <- UserStr read str - } yield + yield val attempt = Attempt(u.id, email, ip) byIp.underlying.asMap.compute(ip, (_, attempts) => ~Option(attempts) + attempt).unit byId.underlying.asMap.compute(u.id, (_, attempts) => ~Option(attempts) + attempt).unit diff --git a/modules/security/src/main/DnsApi.scala b/modules/security/src/main/DnsApi.scala index d3d427bf9ccc2..82a330e245df5 100644 --- a/modules/security/src/main/DnsApi.scala +++ b/modules/security/src/main/DnsApi.scala @@ -32,7 +32,7 @@ final private class DnsApi( .map(_ split ' ') .collect { case Array(_, domain) => Domain.from { - if (domain endsWith ".") domain.init + if domain endsWith "." then domain.init else domain } } diff --git a/modules/security/src/main/EmailAddressValidator.scala b/modules/security/src/main/EmailAddressValidator.scala index 71f1cfb15e63d..bd7a4ef5faa35 100644 --- a/modules/security/src/main/EmailAddressValidator.scala +++ b/modules/security/src/main/EmailAddressValidator.scala @@ -17,7 +17,7 @@ final class EmailAddressValidator( import EmailAddressValidator.* val sendableConstraint = Constraint[EmailAddress]("constraint.email_acceptable") { email => - if (email.isSendable) Valid + if email.isSendable then Valid else Invalid(ValidationError("error.email_acceptable")) } @@ -25,13 +25,13 @@ final class EmailAddressValidator( Constraint[EmailAddress]("constraint.email_unique") { email => val (taken, reused) = (isTakenBySomeoneElse(email, forUser) zip wasUsedTwiceRecently(email)).await(2 seconds, "emailUnique") - if (taken || reused) Invalid(ValidationError("error.email_unique")) + if taken || reused then Invalid(ValidationError("error.email_unique")) else Valid } def differentConstraint(than: Option[EmailAddress]) = Constraint[EmailAddress]("constraint.email_different") { email => - if (than has email) Invalid(ValidationError("error.email_different")) + if than has email then Invalid(ValidationError("error.email_different")) else Valid } diff --git a/modules/security/src/main/EmailConfirm.scala b/modules/security/src/main/EmailConfirm.scala index e459549bec6df..12f042aaadda4 100644 --- a/modules/security/src/main/EmailConfirm.scala +++ b/modules/security/src/main/EmailConfirm.scala @@ -163,7 +163,7 @@ object EmailConfirm: userRepo withEmails u flatMap { case None => fuccess(NoSuchUser(u into UserName)) case Some(User.WithEmails(user, emails)) => - if (user.enabled.no) fuccess(Closed(user.username)) + if user.enabled.no then fuccess(Closed(user.username)) else userRepo mustConfirmEmail user.id dmap { if _ then diff --git a/modules/security/src/main/Env.scala b/modules/security/src/main/Env.scala index 88dc1d03a5e98..f6f80bd072f14 100644 --- a/modules/security/src/main/Env.scala +++ b/modules/security/src/main/Env.scala @@ -45,7 +45,7 @@ final class Env( lazy val flood = wire[Flood] lazy val hcaptcha: Hcaptcha = - if (config.hcaptcha.enabled) wire[HcaptchaReal] + if config.hcaptcha.enabled then wire[HcaptchaReal] else wire[HcaptchaSkip] lazy val forms = wire[SecurityForm] @@ -57,7 +57,7 @@ final class Env( lazy val store = Store(db(config.collection.security), cacheApi) lazy val ip2proxy: Ip2Proxy = - if (config.ip2Proxy.enabled && config.ip2Proxy.url.nonEmpty) + if config.ip2Proxy.enabled && config.ip2Proxy.url.nonEmpty then def mk = (url: String) => wire[Ip2ProxyServer] mk(config.ip2Proxy.url) else wire[Ip2ProxySkip] @@ -75,7 +75,7 @@ final class Env( mk((() => ugcArmedSetting.get())) lazy val emailConfirm: EmailConfirm = - if (config.emailConfirm.enabled) + if config.emailConfirm.enabled then EmailConfirmMailer( userRepo = userRepo, mailer = mailer, @@ -128,7 +128,7 @@ final class Env( lazy val promotion = wire[PromotionApi] - if (config.disposableEmail.enabled) + if config.disposableEmail.enabled then scheduler.scheduleOnce(33 seconds)(disposableEmailDomain.refresh()) scheduler.scheduleWithFixedDelay( config.disposableEmail.refreshDelay, @@ -139,7 +139,7 @@ final class Env( lazy val tor: Tor = wire[Tor] - if (config.tor.enabled) + if config.tor.enabled then scheduler.scheduleOnce(44 seconds)(tor.refresh.unit) scheduler.scheduleWithFixedDelay(config.tor.refreshDelay, config.tor.refreshDelay) { () => tor.refresh flatMap firewall.unblockIps diff --git a/modules/security/src/main/FingerPrint.scala b/modules/security/src/main/FingerPrint.scala index a99c720af6a12..9b34dba41d9ab 100644 --- a/modules/security/src/main/FingerPrint.scala +++ b/modules/security/src/main/FingerPrint.scala @@ -22,4 +22,4 @@ object FingerHash extends OpaqueString[FingerHash]: private def normalize(fp: FingerPrint): String = val str = fp.value.replace("-", "") - if (str.length % 2 != 0) s"${str}0" else str + if str.length % 2 != 0 then s"${str}0" else str diff --git a/modules/security/src/main/Firewall.scala b/modules/security/src/main/Firewall.scala index e2698e53e6cb7..4cb95574f08de 100644 --- a/modules/security/src/main/Firewall.scala +++ b/modules/security/src/main/Firewall.scala @@ -20,7 +20,7 @@ final class Firewall( val v = blocksIp { lila.common.HTTPRequest ipAddress req } - if (v) lila.mon.security.firewall.block.increment() + if v then lila.mon.security.firewall.block.increment() v def accepts(req: RequestHeader): Boolean = !blocks(req) diff --git a/modules/security/src/main/Hcaptcha.scala b/modules/security/src/main/Hcaptcha.scala index b58f8bd6b82b5..d5bbd78a24154 100644 --- a/modules/security/src/main/Hcaptcha.scala +++ b/modules/security/src/main/Hcaptcha.scala @@ -79,7 +79,7 @@ final class HcaptchaReal( def form[A](form: Form[A])(using req: RequestHeader): Fu[HcaptchaForm[A]] = skip.getFu map { skip => - lila.mon.security.hCaptcha.form(HTTPRequest clientName req, if (skip) "skip" else "show").increment() + lila.mon.security.hCaptcha.form(HTTPRequest clientName req, if skip then "skip" else "show").increment() HcaptchaForm(form, config.public, skip) } @@ -98,15 +98,15 @@ final class HcaptchaReal( res.body[JsValue].validate[GoodResponse] match case JsSuccess(res, _) => lila.mon.security.hCaptcha.hit(client, "success").increment() - if (res.success && res.hostname == netDomain.value) Result.Valid + if res.success && res.hostname == netDomain.value then Result.Valid else Result.Fail case JsError(err) => res.body[JsValue].validate[BadResponse].asOpt match case Some(err) if err.missingInput => - if (HTTPRequest.apiVersion(req).isDefined) + if HTTPRequest.apiVersion(req).isDefined then lila.mon.security.hCaptcha.hit(client, "api").increment() Result.Pass - else if (skip.get) + else if skip.get then lila.mon.security.hCaptcha.hit(client, "skip").increment() skip.record Result.Skip diff --git a/modules/security/src/main/Ip2Proxy.scala b/modules/security/src/main/Ip2Proxy.scala index f272033bec7b7..b6415967dcf16 100644 --- a/modules/security/src/main/Ip2Proxy.scala +++ b/modules/security/src/main/Ip2Proxy.scala @@ -56,7 +56,7 @@ final class Ip2ProxyServer( case Seq(ip) => apply(ip).dmap(Seq(_)) case ips => ips.flatMap(cache.getIfPresent).parallel flatMap { cached => - if (cached.sizeIs == ips.size) fuccess(cached) + if cached.sizeIs == ips.size then fuccess(cached) else ws.url(s"$checkUrl/batch") .addQueryStringParameters("ips" -> ips.mkString(",")) @@ -68,7 +68,7 @@ final class Ip2ProxyServer( } } .flatMap { res => - if (res.sizeIs == ips.size) fuccess(res) + if res.sizeIs == ips.size then fuccess(res) else fufail(s"Ip2Proxy missing results for $ips -> $res") } .addEffect { diff --git a/modules/security/src/main/IpTrust.scala b/modules/security/src/main/IpTrust.scala index 1b71e53be1c39..6d6dbaef3a347 100644 --- a/modules/security/src/main/IpTrust.scala +++ b/modules/security/src/main/IpTrust.scala @@ -5,18 +5,18 @@ import lila.common.IpAddress final class IpTrust(proxyApi: Ip2Proxy, geoApi: GeoIP, torApi: Tor, firewallApi: Firewall): def isSuspicious(ip: IpAddress): Fu[Boolean] = - if (firewallApi blocksIp ip) fuTrue - else if (torApi isExitNode ip) fuTrue + if firewallApi blocksIp ip then fuTrue + else if torApi isExitNode ip then fuTrue else val location = geoApi orUnknown ip - if (location == Location.unknown || location == Location.tor) fuTrue - else if (isUndetectedProxy(location)) fuTrue + if location == Location.unknown || location == Location.tor then fuTrue + else if isUndetectedProxy(location) then fuTrue else proxyApi(ip).dmap(_.is) def isSuspicious(ipData: UserLogins.IPData): Fu[Boolean] = isSuspicious(ipData.ip.value) - final class rateLimit(credits: Int, duration: FiniteDuration, key: String, factor: Int = 3) { + final class rateLimit(credits: Int, duration: FiniteDuration, key: String, factor: Int = 3): import lila.memo.{ RateLimit as RL } private val limiter = RL[IpAddress](credits, duration, key) def apply[A](ip: IpAddress, default: => Fu[A], cost: RL.Cost = 1, msg: => String = "")(op: => Fu[A])(using @@ -25,16 +25,15 @@ final class IpTrust(proxyApi: Ip2Proxy, geoApi: GeoIP, torApi: Tor, firewallApi: isSuspicious(ip).flatMap: susp => val realCost = cost * (if susp then factor else 1) limiter[Fu[A]](ip, default, realCost, msg)(op) - } /* lichess blacklist of proxies that ip2proxy doesn't know about */ private def isUndetectedProxy(location: Location): Boolean = location.shortCountry == "Iran" || - location.shortCountry == "United Arab Emirates" || (location match { + location.shortCountry == "United Arab Emirates" || (location match case Location("Poland", _, Some("Subcarpathian Voivodeship"), Some("Stalowa Wola")) => true case Location("Poland", _, Some("Lesser Poland Voivodeship"), Some("Krakow")) => true case Location("Russia", _, Some(region), Some("Ufa" | "Sterlitamak")) if region contains "Bashkortostan" => true case _ => false - }) + ) diff --git a/modules/security/src/main/Levenshtein.scala b/modules/security/src/main/Levenshtein.scala index 42cacf627e89e..9db55c9237a51 100644 --- a/modules/security/src/main/Levenshtein.scala +++ b/modules/security/src/main/Levenshtein.scala @@ -14,20 +14,20 @@ private object Levenshtein: ((i - (threshold - 1)) max 0) until (1 + ((i + t) min a.length)) @scala.annotation.tailrec def loop(j: Int, prev: Array[Int], prevr: Range, next: Array[Int]): Int = - if (j > b.length) prev.last + if j > b.length then prev.last else val c = b(j - 1) val q = rowRange(j) - for (i <- q) + for i <- q do next(i) = - if (i == 0) j + if i == 0 then j else - val t0 = if (i < prevr.end) prev(i) else inf - val t1 = 1 + (if (i > q.start) t0 min next(i - 1) else t0) - if (prevr.start < i) + val t0 = if i < prevr.end then prev(i) else inf + val t1 = 1 + (if i > q.start then t0 min next(i - 1) else t0) + if prevr.start < i then val t = prev(i - 1) - t1 min (if (c != a(i - 1)) 1 + t else t) + t1 min (if c != a(i - 1) then 1 + t else t) else t1 loop(j + 1, next, q, prev) loop(1, Array.range(0, a.length + 1), rowRange(0), Array.ofDim[Int](a.length + 1)) < threshold - if (a.lengthIs < b.length) f(b, a) else f(a, b) + if a.lengthIs < b.length then f(b, a) else f(a, b) diff --git a/modules/security/src/main/PrintBan.scala b/modules/security/src/main/PrintBan.scala index 637e046668b59..b740cc1015266 100644 --- a/modules/security/src/main/PrintBan.scala +++ b/modules/security/src/main/PrintBan.scala @@ -11,8 +11,8 @@ final class PrintBan(coll: Coll)(using Executor): def blocks(hash: FingerHash): Boolean = current contains hash.value def toggle(hash: FingerHash, block: Boolean): Funit = - current = if (block) current + hash.value else current - hash.value - if (block) + current = if block then current + hash.value else current - hash.value + if block then coll.update .one( $id(hash.value), diff --git a/modules/security/src/main/Promotion.scala b/modules/security/src/main/Promotion.scala index 93f9014d119f9..08b3465d8002c 100644 --- a/modules/security/src/main/Promotion.scala +++ b/modules/security/src/main/Promotion.scala @@ -13,7 +13,7 @@ final class PromotionApi(domain: NetDomain): val prevTextPromotion = prevText so extract val prev = ~cache.getIfPresent(me) -- prevTextPromotion val accept = prev.sizeIs < 3 && !prev.exists(promotions.contains) - if (!accept) logger.info(s"Promotion @${me.username} ${identify(text) mkString ", "}") + if !accept then logger.info(s"Promotion @${me.username} ${identify(text) mkString ", "}") accept } } diff --git a/modules/security/src/main/SecurityApi.scala b/modules/security/src/main/SecurityApi.scala index 2983867440af3..08a7784869844 100644 --- a/modules/security/src/main/SecurityApi.scala +++ b/modules/security/src/main/SecurityApi.scala @@ -97,7 +97,7 @@ final class SecurityApi( if _ then fufail(SecurityApi MustConfirmEmail userId) else val sessionId = SecureRandom nextString 22 - if (tor isExitNode HTTPRequest.ipAddress(req)) logger.info(s"Tor login $userId") + if tor isExitNode HTTPRequest.ipAddress(req) then logger.info(s"Tor login $userId") store.save(sessionId, userId, req, apiVersion, up = true, fp = none) inject sessionId } @@ -110,7 +110,7 @@ final class SecurityApi( private type AppealOrUser = Either[AppealUser, FingerPrintedUser] def restoreUser(req: RequestHeader): Fu[Option[AppealOrUser]] = firewall.accepts(req) so reqSessionId(req) so { sessionId => - appeal.authenticate(sessionId) match { + appeal.authenticate(sessionId) match case Some(userId) => userRepo byId userId map2 { u => Left(AppealUser(Me(u))) } case None => store.authInfo(sessionId) flatMapz { d => @@ -118,7 +118,7 @@ final class SecurityApi( _ map { me => Right(FingerPrintedUser(stripRolesOfCookieUser(me), d.hasFp)) } } } - }: Fu[Option[AppealOrUser]] + : Fu[Option[AppealOrUser]] } def oauthScoped( diff --git a/modules/security/src/main/Signup.scala b/modules/security/src/main/Signup.scala index 2e85954afab58..c0a678ca6d8b2 100644 --- a/modules/security/src/main/Signup.scala +++ b/modules/security/src/main/Signup.scala @@ -39,8 +39,8 @@ final class Signup( ): Fu[MustConfirmEmail] = val ip = HTTPRequest ipAddress req store.recentByIpExists(ip, 7.days) flatMap { ipExists => - if (ipExists) fuccess(YesBecauseIpExists) - else if (HTTPRequest weirdUA req) fuccess(YesBecauseUA) + if ipExists then fuccess(YesBecauseIpExists) + else if HTTPRequest weirdUA req then fuccess(YesBecauseUA) else print.fold[Fu[MustConfirmEmail]](fuccess(YesBecausePrintMissing)) { fp => store.recentByPrintExists(fp) map { printFound => @@ -109,9 +109,9 @@ final class Signup( apiVersion: Option[ApiVersion] )(user: User)(using RequestHeader, Lang): Fu[Signup.Result] = store.deletePreviousSessions(user) >> { - if (mustConfirm.value) + if mustConfirm.value then emailConfirm.send(user, email) >> { - if (emailConfirm.effective) + if emailConfirm.effective then api.saveSignup(user.id, apiVersion, fingerPrint) inject Signup.Result.ConfirmEmail(user, email) else fuccess(Signup.Result.AllSet(user, email)) diff --git a/modules/security/src/main/Store.scala b/modules/security/src/main/Store.scala index 4929720901a64..2187ecfeb832a 100644 --- a/modules/security/src/main/Store.scala +++ b/modules/security/src/main/Store.scala @@ -24,7 +24,7 @@ final class Store(val coll: Coll, cacheApi: lila.memo.CacheApi)(using .one[Bdoc] .map { _.flatMap { doc => - if (doc.getAsOpt[Instant]("date").fold(true)(_ isBefore nowInstant.minusHours(12))) + if doc.getAsOpt[Instant]("date").fold(true)(_ isBefore nowInstant.minusHours(12)) then coll.updateFieldUnchecked($id(id), "date", nowInstant) doc.getAsOpt[UserId]("user") map { AuthInfo(_, doc.contains("fp")) } } diff --git a/modules/security/src/main/UserLogins.scala b/modules/security/src/main/UserLogins.scala index 6c4485426615f..270fc33cb45e3 100644 --- a/modules/security/src/main/UserLogins.scala +++ b/modules/security/src/main/UserLogins.scala @@ -219,11 +219,10 @@ object UserLogins: case class WithMeSortedWithEmails[U: UserIdOf]( others: List[OtherUser[U]], emails: Map[UserId, EmailAddress] - ) { + ): def withUsers[V: UserIdOf](newUsers: List[V]) = copy(others = others.flatMap { o => newUsers.find(_ is o.user).map { u => o.copy(user = u) } }) - } def withMeSortedWithEmails( userRepo: UserRepo, @@ -243,8 +242,7 @@ object UserLogins: notes: List[lila.user.Note], bans: Map[UserId, Int], max: Int - ) { + ): def withUsers[V: UserIdOf](users: List[V]) = copy( othersWithEmail = othersWithEmail.withUsers(users) ) - } diff --git a/modules/security/src/main/model.scala b/modules/security/src/main/model.scala index 7575dc21e65d3..2b00da77593df 100644 --- a/modules/security/src/main/model.scala +++ b/modules/security/src/main/model.scala @@ -54,6 +54,6 @@ enum UserClient: case PC, Mob, App object UserClient: def apply(ua: UserAgent): UserClient = - if (ua.value contains "Lichobile") UserClient.App - else if (ua.value contains "Mobile") UserClient.Mob + if ua.value contains "Lichobile" then UserClient.App + else if ua.value contains "Mobile" then UserClient.Mob else UserClient.PC diff --git a/modules/security/src/test/Fixtures.scala b/modules/security/src/test/Fixtures.scala index 985999d99d23c..8755955092cf1 100644 --- a/modules/security/src/test/Fixtures.scala +++ b/modules/security/src/test/Fixtures.scala @@ -1,6 +1,6 @@ package lila.security -case object Fixtures { +case object Fixtures: def text = """ leeching.net @@ -1212,4 +1212,3 @@ zxcv.com zxcvbnm.com zzz.com """ -} diff --git a/modules/security/src/test/FloodTest.scala b/modules/security/src/test/FloodTest.scala index f74fa0e7bb85d..5aaf32ec91c80 100644 --- a/modules/security/src/test/FloodTest.scala +++ b/modules/security/src/test/FloodTest.scala @@ -2,9 +2,9 @@ package lila.security import java.time.Instant -class FloodTest extends munit.FunSuite { +class FloodTest extends munit.FunSuite: - import Flood._ + import Flood.* private def isDup = duplicateMessage _ @@ -33,4 +33,3 @@ class FloodTest extends munit.FunSuite { assert(isDup(m("hey"), List(m(s"hey!")))) assert(!isDup(m("hey"), List(m(s"hey!!")))) } -} diff --git a/modules/security/src/test/LevenshteinTest.scala b/modules/security/src/test/LevenshteinTest.scala index d8e3b9e4cdad4..8f8ce605c5a84 100644 --- a/modules/security/src/test/LevenshteinTest.scala +++ b/modules/security/src/test/LevenshteinTest.scala @@ -2,32 +2,25 @@ package lila.security import scala.util.Random import lila.common.base.StringUtils -object LevenshteinTest { - def check0(a: String, b: String): Boolean = { +object LevenshteinTest: + def check0(a: String, b: String): Boolean = val d = StringUtils.levenshtein(a, b) !Levenshtein.isDistanceLessThan(a, b, d) && Levenshtein.isDistanceLessThan(a, b, d + 1) - } def check(a: String, b: String) = check0(a, b) && check0(b, a) - def rndStr(r: Random, l: Int, sigma: Int): String = { + def rndStr(r: Random, l: Int, sigma: Int): String = val sb = new StringBuilder(l) - for (_ <- 0 until l) sb.append((48 + r.nextInt(sigma)).toChar) + for _ <- 0 until l do sb.append((48 + r.nextInt(sigma)).toChar) sb.result() - } - def rt(r: Random, l1: Int, l2: Int, sigma: Int) = { + def rt(r: Random, l1: Int, l2: Int, sigma: Int) = val s1 = rndStr(r, l1, sigma) val s2 = rndStr(r, l2, sigma) check(s1, s2) - } - def mt(seed: Int, nt: Int, l: Int, sigma: Int) = { + def mt(seed: Int, nt: Int, l: Int, sigma: Int) = val r = new Random(seed) - (0 until nt).forall(_ => { - rt(r, r.nextInt(l + 1), l, sigma) - }) - } -} + (0 until nt).forall(_ => rt(r, r.nextInt(l + 1), l, sigma)) -class LevenshteinTest extends munit.FunSuite { +class LevenshteinTest extends munit.FunSuite: import LevenshteinTest.{ check, mt } test("Levenshtein random") { assertEquals(mt(1, 1000, 10, 2), true) @@ -69,4 +62,3 @@ class LevenshteinTest extends munit.FunSuite { false ) } -} diff --git a/modules/security/src/test/SpamTest.scala b/modules/security/src/test/SpamTest.scala index 102ed8d3aea6a..9ccd3f88fc1c7 100644 --- a/modules/security/src/test/SpamTest.scala +++ b/modules/security/src/test/SpamTest.scala @@ -2,7 +2,7 @@ package lila.security import lila.common.Strings -class SpamTest extends munit.FunSuite { +class SpamTest extends munit.FunSuite: val spam = new Spam(() => Strings(Nil)) val foobar = """foo bar""" @@ -16,4 +16,3 @@ class SpamTest extends munit.FunSuite { assertEquals(spam.replace(foobar), foobar) assertEquals(spam.replace(_c2), """https://chess24.com""") } -} diff --git a/modules/setup/src/main/ApiAiConfig.scala b/modules/setup/src/main/ApiAiConfig.scala index 5717a076a6cfc..b78c73ea42c34 100644 --- a/modules/setup/src/main/ApiAiConfig.scala +++ b/modules/setup/src/main/ApiAiConfig.scala @@ -45,7 +45,7 @@ final case class ApiAiConfig( Player.make(chess.Black, user.map(_ only pt)) ), mode = chess.Mode.Casual, - source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Ai, + source = if chessGame.board.variant.fromPosition then Source.Position else Source.Ai, daysPerTurn = makeDaysPerTurn, pgnImport = None ) diff --git a/modules/setup/src/main/Config.scala b/modules/setup/src/main/Config.scala index 6c467726c9c9c..e23c30f636b17 100644 --- a/modules/setup/src/main/Config.scala +++ b/modules/setup/src/main/Config.scala @@ -51,12 +51,13 @@ private[setup] trait Config: protected def justMakeClock = Clock.Config( Clock.LimitSeconds((time * 60).toInt), - if (clockHasTime) increment else Clock.IncrementSeconds(1) + if clockHasTime then increment else Clock.IncrementSeconds(1) ) def makeDaysPerTurn: Option[Days] = (timeMode == TimeMode.Correspondence) option days -trait Positional { self: Config => +trait Positional: + self: Config => def fen: Option[Fen.Epd] @@ -80,8 +81,8 @@ trait Positional { self: Config => startedAtPly = sit.ply, clock = makeClock.map(_.toClock) ) - if (Fen.write(game).isInitial) makeGame(chess.variant.Standard) -> none - else game -> baseState + if Fen.write(game).isInitial then makeGame(chess.variant.Standard) -> none + else game -> baseState } builder(chessGame) dmap { game => state.fold(game) { case sit @ Situation.AndFullMoveNumber(Situation(board, _), _) => @@ -98,7 +99,6 @@ trait Positional { self: Config => ) } } -} object Config extends BaseConfig diff --git a/modules/setup/src/main/SetupBulk.scala b/modules/setup/src/main/SetupBulk.scala index 63547ab7dd3b2..5b1f606b79917 100644 --- a/modules/setup/src/main/SetupBulk.scala +++ b/modules/setup/src/main/SetupBulk.scala @@ -39,7 +39,7 @@ object SetupBulk: def validFen = ApiConfig.validFen(variant, fen) def autoVariant = - if (variant.standard && fen.exists(!_.isInitial)) copy(variant = FromPosition) + if variant.standard && fen.exists(!_.isInitial) then copy(variant = FromPosition) else this private def timestampInNearFuture = longNumber( diff --git a/modules/setup/src/main/TimeMode.scala b/modules/setup/src/main/TimeMode.scala index 85cd207332c2f..cbecb549da3d3 100644 --- a/modules/setup/src/main/TimeMode.scala +++ b/modules/setup/src/main/TimeMode.scala @@ -17,6 +17,6 @@ object TimeMode: def orDefault(id: Int) = apply(id) | default def ofGame(game: lila.game.Game) = - if (game.hasClock) RealTime - else if (game.hasCorrespondenceClock) Correspondence + if game.hasClock then RealTime + else if game.hasCorrespondenceClock then Correspondence else Unlimited diff --git a/modules/setup/src/main/ValidFen.scala b/modules/setup/src/main/ValidFen.scala index 659964a1517e3..534fb4bfe572e 100644 --- a/modules/setup/src/main/ValidFen.scala +++ b/modules/setup/src/main/ValidFen.scala @@ -8,8 +8,8 @@ case class ValidFen(fen: Fen.Epd, situation: chess.Situation): object ValidFen: def apply(strict: Boolean)(fen: Fen.Epd): Option[ValidFen] = - for { + for parsed <- chess.format.Fen readWithMoveNumber fen if parsed.situation playable strict validated = chess.format.Fen write parsed - } yield ValidFen(validated, parsed.situation) + yield ValidFen(validated, parsed.situation) diff --git a/modules/shutup/src/main/PublicLine.scala b/modules/shutup/src/main/PublicLine.scala index 9433022826379..b195fba110f31 100644 --- a/modules/shutup/src/main/PublicLine.scala +++ b/modules/shutup/src/main/PublicLine.scala @@ -20,7 +20,7 @@ object PublicLine: import lila.db.dsl.* private given BSONHandler[Source] = lila.db.dsl.tryHandler[Source]( { case BSONString(v) => - v split ':' match { + v split ':' match case Array("t", id) => Success(Source.Tournament(TourId(id))) case Array("s", id) => Success(Source.Simul(SimulId(id))) case Array("w", id) => Success(Source.Watcher(GameId(id))) @@ -28,17 +28,16 @@ object PublicLine: case Array("e", id) => Success(Source.Team(TeamId(id))) case Array("i", id) => Success(Source.Swiss(SwissId(id))) case _ => lila.db.BSON.handlerBadValue(s"Invalid PublicLine source $v") - } }, x => - BSONString(x match { + BSONString(x match case Source.Tournament(id) => s"t:$id" case Source.Simul(id) => s"s:$id" case Source.Study(id) => s"u:$id" case Source.Watcher(gameId) => s"w:$gameId" case Source.Team(id) => s"e:$id" case Source.Swiss(id) => s"i:$id" - }) + ) ) private val objectHandler = Macros.handler[PublicLine] @@ -49,5 +48,5 @@ object PublicLine: case BSONString(text) => Success(PublicLine(text, none, none)) case a => lila.db.BSON.handlerBadValue(s"Invalid PublicLine $a") }, - x => if (x.from.isDefined) objectHandler.writeTry(x).get else BSONString(x.text) + x => if x.from.isDefined then objectHandler.writeTry(x).get else BSONString(x.text) ) diff --git a/modules/shutup/src/main/model.scala b/modules/shutup/src/main/model.scala index ed99fcdadf85b..daefc2bb9dfb5 100644 --- a/modules/shutup/src/main/model.scala +++ b/modules/shutup/src/main/model.scala @@ -29,9 +29,9 @@ case class TextAnalysis( lazy val nbWords = text.split("""\s+""").length def ratio: Double = { - if (nbWords == 0) 0 else badWords.size.toDouble / nbWords + if nbWords == 0 then 0 else badWords.size.toDouble / nbWords } * { - if (critical) 3 else 1 + if critical then 3 else 1 } def dirty = ratio > 0 diff --git a/modules/shutup/src/test/AnalyserTest.scala b/modules/shutup/src/test/AnalyserTest.scala index 15665b6ad9762..472373798f0db 100644 --- a/modules/shutup/src/test/AnalyserTest.scala +++ b/modules/shutup/src/test/AnalyserTest.scala @@ -4,7 +4,7 @@ package lila.shutup * We reject and condemn them. They are here so we can verify * that Lichess detects them, to help moderators keeping the site nice. */ -class AnalyserTest extends munit.FunSuite { +class AnalyserTest extends munit.FunSuite: private def find(t: String) = Analyser(t).badWords private def dirty(t: String) = Analyser(t).dirty @@ -85,4 +85,3 @@ class AnalyserTest extends munit.FunSuite { ) ) } -} diff --git a/modules/simul/src/main/JsonView.scala b/modules/simul/src/main/JsonView.scala index 374fc76a4db2b..9b87f7a4fa149 100644 --- a/modules/simul/src/main/JsonView.scala +++ b/modules/simul/src/main/JsonView.scala @@ -17,7 +17,7 @@ final class JsonView( )(using Executor): private def fetchGames(simul: Simul): Fu[List[Game]] = - if (simul.isFinished) gameRepo gamesFromSecondary simul.gameIds + if simul.isFinished then gameRepo gamesFromSecondary simul.gameIds else simul.gameIds.map(proxyRepo.game).parallel.dmap(_.flatten) def apply(simul: Simul, verdicts: WithVerdicts): Fu[JsObject] = for @@ -59,12 +59,12 @@ final class JsonView( started: List[Simul], finished: List[Simul] ): Fu[JsObject] = - for { + for pendingJson <- api(pending) createdJson <- api(created) startedJson <- api(started) finishedJson <- api(finished) - } yield Json.obj( + yield Json.obj( "pending" -> pendingJson, "created" -> createdJson, "started" -> startedJson, diff --git a/modules/simul/src/main/Simul.scala b/modules/simul/src/main/Simul.scala index 69017ae0d7d5d..a8ce7d07a817a 100644 --- a/modules/simul/src/main/Simul.scala +++ b/modules/simul/src/main/Simul.scala @@ -97,7 +97,7 @@ case class Simul( hasUser(userId) option removeApplicant(userId).removePairing(userId) private def finishIfDone = - if (isStarted && pairings.forall(_.finished)) + if isStarted && pairings.forall(_.finished) then copy( status = SimulStatus.Finished, finishedAt = nowInstant.some, @@ -128,7 +128,7 @@ case class Simul( def setPairingHostColor(gameId: GameId, hostColor: chess.Color) = updatePairing(gameId, _.copy(hostColor = hostColor)) - private def Created(s: => Simul): Simul = if (isCreated) s else this + private def Created(s: => Simul): Simul = if isCreated then s else this def wins = pairings.count(p => p.finished && p.wins.has(false)) def draws = pairings.count(p => p.finished && p.wins.isEmpty) diff --git a/modules/simul/src/main/SimulApi.scala b/modules/simul/src/main/SimulApi.scala index a64e37bf85f8d..b57a665e007df 100644 --- a/modules/simul/src/main/SimulApi.scala +++ b/modules/simul/src/main/SimulApi.scala @@ -139,7 +139,7 @@ final class SimulApi( } def onPlayerConnection(game: Game, user: Option[User])(simul: Simul): Unit = - if (user.exists(simul.isHost) && simul.isRunning) + if user.exists(simul.isHost) && simul.isRunning then repo.setHostGameId(simul, game.id) socket.hostIsOn(simul.id, game.id) diff --git a/modules/simul/src/main/SimulPairing.scala b/modules/simul/src/main/SimulPairing.scala index 917d0808cde8b..8e81233797098 100644 --- a/modules/simul/src/main/SimulPairing.scala +++ b/modules/simul/src/main/SimulPairing.scala @@ -24,7 +24,7 @@ final case class SimulPairing( def winnerColor = wins.map { w => - if (w) !hostColor else hostColor + if w then !hostColor else hostColor } private[simul] object SimulPairing: diff --git a/modules/socket/src/main/AnaDests.scala b/modules/socket/src/main/AnaDests.scala index 667dbaf384bf9..c82fede20e0ea 100644 --- a/modules/socket/src/main/AnaDests.scala +++ b/modules/socket/src/main/AnaDests.scala @@ -18,7 +18,7 @@ case class AnaDests( def isInitial = variant.standard && fen.isInitial && path == "" val dests: String = - if (isInitial) AnaDests.initialDests + if isInitial then AnaDests.initialDests else val sit = chess.Game(variant.some, fen.some).situation sit.playable(false) so destString(sit.destinations) diff --git a/modules/socket/src/main/AnaDrop.scala b/modules/socket/src/main/AnaDrop.scala index 748ff43c4d1e5..00a963051be99 100644 --- a/modules/socket/src/main/AnaDrop.scala +++ b/modules/socket/src/main/AnaDrop.scala @@ -37,7 +37,7 @@ case class AnaDrop( check = game.situation.check, dests = Some(movable so game.situation.destinations), opening = OpeningDb findByEpdFen fen, - drops = if (movable) game.situation.drops else Some(Nil), + drops = if movable then game.situation.drops else Some(Nil), crazyData = game.situation.board.crazyData ) diff --git a/modules/socket/src/main/AnaMove.scala b/modules/socket/src/main/AnaMove.scala index a4b3be6a57ee4..b3f0a9bc53218 100644 --- a/modules/socket/src/main/AnaMove.scala +++ b/modules/socket/src/main/AnaMove.scala @@ -44,7 +44,7 @@ case class AnaMove( dests = Some(movable so game.situation.destinations), opening = (game.ply <= 30 && Variant.list.openingSensibleVariants(variant)) so OpeningDb.findByEpdFen(fen), - drops = if (movable) game.situation.drops else Some(Nil), + drops = if movable then game.situation.drops else Some(Nil), crazyData = game.situation.board.crazyData ) diff --git a/modules/socket/src/main/RemoteSocket.scala b/modules/socket/src/main/RemoteSocket.scala index c6c5da4bb86e8..7286ced3a0c6d 100644 --- a/modules/socket/src/main/RemoteSocket.scala +++ b/modules/socket/src/main/RemoteSocket.scala @@ -65,13 +65,14 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown ) { case SendTos(userIds, payload) => val connectedUsers = userIds intersect onlineUserIds.get - if (connectedUsers.nonEmpty) send(Out.tellUsers(connectedUsers, payload)) + if connectedUsers.nonEmpty then send(Out.tellUsers(connectedUsers, payload)) case SendTo(userId, payload) => - if (onlineUserIds.get.contains(userId)) send(Out.tellUser(userId, payload)) + if onlineUserIds.get.contains(userId) then send(Out.tellUser(userId, payload)) case SendToOnlineUser(userId, makePayload) => - if (onlineUserIds.get.contains(userId)) makePayload() foreach { payload => - send(Out.tellUser(userId, payload)) - } + if onlineUserIds.get.contains(userId) then + makePayload() foreach { payload => + send(Out.tellUser(userId, payload)) + } case Announce(_, _, json) => send(Out.tellAll(Json.obj("t" -> "announce", "d" -> json))) case Mlat(millis) => @@ -90,13 +91,13 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown send(Out.impersonate(userId, modId)) case ApiUserIsOnline(userId, value) => send(Out.apiUserOnline(userId, value)) - if (value) onlineUserIds.getAndUpdate(_ + userId).unit + if value then onlineUserIds.getAndUpdate(_ + userId).unit case Follow(u1, u2) => send(Out.follow(u1, u2)) case UnFollow(u1, u2) => send(Out.unfollow(u1, u2)) } final class StoppableSender(val conn: PubSub[String, String], channel: Channel) extends Sender: - def apply(msg: String) = if (!stopping) super.send(channel, msg).unit + def apply(msg: String) = if !stopping then super.send(channel, msg).unit def sticky(_id: String, msg: String) = apply(msg) final class RoundRobinSender(val conn: PubSub[String, String], channel: Channel, parallelism: Int) @@ -106,7 +107,7 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown def sticky(id: String, msg: String): Unit = publish(id.hashCode.abs % parallelism, msg) private def publish(subChannel: Int, msg: String) = - if (!stopping) conn.async.publish(s"$channel:$subChannel", msg).unit + if !stopping then conn.async.publish(s"$channel:$subChannel", msg).unit def makeSender(channel: Channel, parallelism: Int = 1): Sender = if parallelism > 1 then RoundRobinSender(redisClient.connectPubSub(), channel, parallelism) @@ -138,9 +139,10 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown private def connectAndSubscribe(channel: Channel)(f: String => Unit): Funit = val conn = redisClient.connectPubSub() - conn.addListener(new pubsub.RedisPubSubAdapter[String, String] { - override def message(_channel: String, message: String): Unit = f(message) - }) + conn.addListener( + new pubsub.RedisPubSubAdapter[String, String]: + override def message(_channel: String, message: String): Unit = f(message) + ) val subPromise = Promise[Unit]() conn.async .subscribe(channel) @@ -222,21 +224,20 @@ object RemoteSocket: } case "lags" => Lags(commas(raw.args).flatMap { - _ split ':' match { + _ split ':' match case Array(user, l) => l.toIntOption map { lag => UserId(user) -> Centis(lag) } case _ => None - } }.toMap).some case "tell/sri" => raw.get(3)(tellSriMapper) case "tell/user" => raw.get(2) { case Array(user, payload) => - for { + for obj <- Json.parse(payload).asOpt[JsObject] typ <- obj str "t" - } yield TellUser(UserId(user), typ, obj) + yield TellUser(UserId(user), typ, obj) } case "req/response" => raw.get(2) { case Array(reqId, response) => @@ -247,15 +248,15 @@ object RemoteSocket: case _ => none def tellSriMapper: PartialFunction[Array[String], Option[TellSri]] = { case Array(sri, user, payload) => - for { + for obj <- Json.parse(payload).asOpt[JsObject] typ <- obj str "t" - } yield TellSri(Sri(sri), UserId from optional(user), typ, obj) + yield TellSri(Sri(sri), UserId from optional(user), typ, obj) } - def commas(str: String): Array[String] = if (str == "-") Array.empty else str split ',' + def commas(str: String): Array[String] = if str == "-" then Array.empty else str split ',' def boolean(str: String): Boolean = str == "+" - def optional(str: String): Option[String] = if (str == "-") None else Some(str) + def optional(str: String): Option[String] = if str == "-" then None else Some(str) object Out: def tellUser(userId: UserId, payload: JsObject) = @@ -286,8 +287,8 @@ object RemoteSocket: def pong(id: String) = s"pong $id" def stop(reqId: Int) = s"lila/stop $reqId" - def commas(strs: Iterable[Any]): String = if (strs.isEmpty) "-" else strs mkString "," - def boolean(v: Boolean): String = if (v) "+" else "-" + def commas(strs: Iterable[Any]): String = if strs.isEmpty then "-" else strs mkString "," + def boolean(v: Boolean): String = if v then "+" else "-" def optional(str: Option[String]) = str getOrElse "-" def color(c: Color): String = c.fold("w", "b") def color(c: Option[Color]): String = optional(c.map(_.fold("w", "b"))) diff --git a/modules/storm/src/main/StormBsonHandlers.scala b/modules/storm/src/main/StormBsonHandlers.scala index 2d6711bf4cbce..b63b80f7c613a 100644 --- a/modules/storm/src/main/StormBsonHandlers.scala +++ b/modules/storm/src/main/StormBsonHandlers.scala @@ -10,23 +10,22 @@ import lila.common.LichessDay object StormBsonHandlers: given puzzleReader: BSONDocumentReader[StormPuzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId]("_id") fen <- r.getAsTry[Fen.Epd]("fen") lineStr <- r.getAsTry[String]("line") line <- lineStr.split(' ').toList.flatMap(Uci.Move.apply).toNel.toTry("Empty move list?!") rating <- r.getAsTry[IntRating]("rating") - } yield StormPuzzle(id, fen, line, rating) + yield StormPuzzle(id, fen, line, rating) given BSONHandler[StormDay.Id] = val sep = ':' tryHandler[StormDay.Id]( { case BSONString(v) => - v split sep match { + v split sep match case Array(userId, dayStr) => Success(StormDay.Id(UserId(userId), LichessDay(Integer.parseInt(dayStr)))) case _ => handlerBadValue(s"Invalid storm day id $v") - } }, id => BSONString(s"${id.userId}$sep${id.day.value}") ) diff --git a/modules/storm/src/main/StormDay.scala b/modules/storm/src/main/StormDay.scala index df6571c7fb0f7..e9d4308054b40 100644 --- a/modules/storm/src/main/StormDay.scala +++ b/modules/storm/src/main/StormDay.scala @@ -21,7 +21,7 @@ case class StormDay( ): def add(run: StormForm.RunData) = { - if (run.score > score) + if run.score > score then copy( score = run.score, moves = run.moves, @@ -60,7 +60,7 @@ final class StormDayApi(coll: Coll, highApi: StormHighApi, perfsRepo: UserPerfsR ): Fu[Option[StormHigh.NewHigh]] = lila.mon.storm.run.score(user.isDefined).record(data.score).unit user so { u => - if (mobile || sign.check(u, ~data.signed)) + if mobile || sign.check(u, ~data.signed) then Bus.publish(lila.hub.actorApi.puzzle.StormRun(u.id, data.score), "stormRun") highApi get u.id flatMap { prevHigh => val todayId = Id today u.id @@ -78,15 +78,15 @@ final class StormDayApi(coll: Coll, highApi: StormHighApi, perfsRepo: UserPerfsR } } else - if (data.time > 40) - if (data.score > 99) logger.warn(s"badly signed run from ${u.username} $data") + if data.time > 40 then + if data.score > 99 then logger.warn(s"badly signed run from ${u.username} $data") lila.mon.storm.run - .sign(data.signed match { + .sign(data.signed match case None => "missing" case Some("") => "empty" case Some("undefined") => "undefined" case _ => "wrong" - }) + ) .increment() fuccess(none) } diff --git a/modules/storm/src/main/StormSelector.scala b/modules/storm/src/main/StormSelector.scala index 85cc836f2c683..8d0b162db3660 100644 --- a/modules/storm/src/main/StormSelector.scala +++ b/modules/storm/src/main/StormSelector.scala @@ -51,7 +51,7 @@ final class StormSelector(colls: PuzzleColls, cacheApi: CacheApi)(using Executor val fenColorRegex = $doc( "$regexMatch" -> $doc( "input" -> "$fen", - "regex" -> { if (scala.util.Random.nextBoolean()) " w " else " b " } + "regex" -> { if scala.util.Random.nextBoolean() then " w " else " b " } ) ) Facet( @@ -119,9 +119,8 @@ final class StormSelector(colls: PuzzleColls, cacheApi: CacheApi)(using Executor private def monitor(puzzles: Vector[StormPuzzle], poolSize: Int): Unit = val nb = puzzles.size lila.mon.storm.selector.count.record(nb) - if (nb < poolSize * 0.9) - logger.warn(s"Selector wanted $poolSize puzzles, only got $nb") - if (nb > 1) + if nb < poolSize * 0.9 then logger.warn(s"Selector wanted $poolSize puzzles, only got $nb") + if nb > 1 then val rest = puzzles.toVector drop 1 lila.common.Maths.mean(IntRating raw rest.map(_.rating)) foreach { r => lila.mon.storm.selector.rating.record(r.toInt).unit diff --git a/modules/storm/src/main/StormSign.scala b/modules/storm/src/main/StormSign.scala index 5bab9ecac9829..8aadc639d3d95 100644 --- a/modules/storm/src/main/StormSign.scala +++ b/modules/storm/src/main/StormSign.scala @@ -25,6 +25,6 @@ final class StormSign(secret: Secret, cacheApi: CacheApi): !Uptime.startedSinceMinutes(5) || { signer.sha1(store.get(user.id)) hash_= signed } - if (correct) store.put(user.id, signed) + if correct then store.put(user.id, signed) correct } diff --git a/modules/streamer/src/main/StreamerApi.scala b/modules/streamer/src/main/StreamerApi.scala index 69fa61c44490b..ab1622eb09efb 100644 --- a/modules/streamer/src/main/StreamerApi.scala +++ b/modules/streamer/src/main/StreamerApi.scala @@ -73,7 +73,7 @@ final class StreamerApi( }.parallel _ <- elements.nonEmpty so update.many(elements).void candidateIds <- cache.candidateIds.getUnit - yield if (streams.map(_.streamer.id).exists(candidateIds.contains)) cache.candidateIds.invalidateUnit() + yield if streams.map(_.streamer.id).exists(candidateIds.contains) then cache.candidateIds.invalidateUnit() def update(prev: Streamer, data: StreamerForm.UserData, asMod: Boolean): Fu[Streamer.ModChange] = val streamer = data(prev, asMod) diff --git a/modules/streamer/src/main/StreamerForm.scala b/modules/streamer/src/main/StreamerForm.scala index 82aa0f2e179c4..4723f83d3a2eb 100644 --- a/modules/streamer/src/main/StreamerForm.scala +++ b/modules/streamer/src/main/StreamerForm.scala @@ -86,13 +86,13 @@ object StreamerForm: updatedAt = nowInstant ) newStreamer.copy( - approval = approval.map(_.resolve) match { + approval = approval.map(_.resolve) match case Some(m) if asMod => streamer.approval.copy( granted = m.granted, tier = m.tier | streamer.approval.tier, requested = !m.granted && { - if (streamer.approval.requested != m.requested) m.requested + if streamer.approval.requested != m.requested then m.requested else streamer.approval.requested || m.requested }, ignored = m.ignored && !m.granted, @@ -105,7 +105,6 @@ object StreamerForm: newStreamer.twitch.fold(true)(streamer.twitch.has) && newStreamer.youTube.fold(true)(streamer.youTube.has) ) - } ) case class ApprovalData( diff --git a/modules/streamer/src/main/StreamerPager.scala b/modules/streamer/src/main/StreamerPager.scala index beca9e33a8c03..756ce3acac6fb 100644 --- a/modules/streamer/src/main/StreamerPager.scala +++ b/modules/streamer/src/main/StreamerPager.scala @@ -39,7 +39,7 @@ final class StreamerPager( def slice(offset: Int, length: Int): Fu[Seq[Streamer.WithContext]] = coll .aggregateList(length, _.sec): framework => - import framework._ + import framework.* Match( $doc( "approval.granted" -> true, @@ -74,7 +74,7 @@ final class StreamerPager( def slice(offset: Int, length: Int): Fu[Seq[Streamer.WithContext]] = coll .aggregateList(length, _.sec): framework => - import framework._ + import framework.* Match(selector) -> List( Sort(Ascending("updatedAt")), Skip(offset), diff --git a/modules/streamer/src/main/Streaming.scala b/modules/streamer/src/main/Streaming.scala index 049ac80d93e2f..9e9a52066c2e5 100644 --- a/modules/streamer/src/main/Streaming.scala +++ b/modules/streamer/src/main/Streaming.scala @@ -21,7 +21,7 @@ final private class Streaming( def getLiveStreams: LiveStreams = liveStreams LilaScheduler("Streaming", _.Every(15 seconds), _.AtMost(10 seconds), _.Delay(20 seconds)) { - for { + for streamerIds <- api.allListedIds activeIds = streamerIds.filter { id => liveStreams.has(id) || isOnline(id.userId) @@ -44,18 +44,18 @@ final private class Streaming( } } _ <- api.setLangLiveNow(streams.streams) - } yield publishStreams(streamers, streams) + yield publishStreams(streamers, streams) } private val streamStartOnceEvery = lila.memo.OnceEvery[UserId](2 hour) private def publishStreams(streamers: List[Streamer], newStreams: LiveStreams) = - if (newStreams != liveStreams) + if newStreams != liveStreams then newStreams.streams filterNot { s => liveStreams has s.streamer } foreach { s => import s.streamer.userId - if (streamStartOnceEvery(userId)) + if streamStartOnceEvery(userId) then Bus.publish( lila.hub.actorApi.streamer.StreamStart(userId, s.streamer.name.value), "streamStart" @@ -64,11 +64,11 @@ final private class Streaming( liveStreams = newStreams streamers foreach { streamer => streamer.twitch.foreach { t => - if (liveStreams.streams.exists(s => s.serviceName == "twitch" && s.is(streamer))) + if liveStreams.streams.exists(s => s.serviceName == "twitch" && s.is(streamer)) then lila.mon.tv.streamer.present(s"${t.userId}@twitch").increment() } streamer.youTube.foreach { t => - if (liveStreams.streams.exists(s => s.serviceName == "youTube" && s.is(streamer))) + if liveStreams.streams.exists(s => s.serviceName == "youTube" && s.is(streamer)) then lila.mon.tv.streamer.present(s"${t.channelId}@youtube").increment() } } diff --git a/modules/streamer/src/main/TwitchApi.scala b/modules/streamer/src/main/TwitchApi.scala index 76a98e650cbcb..297c7d5ee821a 100644 --- a/modules/streamer/src/main/TwitchApi.scala +++ b/modules/streamer/src/main/TwitchApi.scala @@ -49,7 +49,7 @@ final private class TwitchApi(ws: StandaloneWSClient, config: TwitchConfig)(usin } .monSuccess(_.tv.streamer.twitch) .flatMap { result => - if (result.data.exists(_.nonEmpty)) + if result.data.exists(_.nonEmpty) then fetchStreams(streamers, page + 1, result.pagination) map (result.liveStreams ::: _) else fuccess(Nil) } diff --git a/modules/study/src/main/BSONHandlers.scala b/modules/study/src/main/BSONHandlers.scala index 804ef82da734f..a6ad27987cec0 100644 --- a/modules/study/src/main/BSONHandlers.scala +++ b/modules/study/src/main/BSONHandlers.scala @@ -312,10 +312,9 @@ object BSONHandlers: given BSONHandler[Tag] = tryHandler[Tag]( { case BSONString(v) => - v.split(":", 2) match { + v.split(":", 2) match case Array(name, value) => Success(Tag(name, value)) case _ => handlerBadValue(s"Invalid pgn tag $v") - } }, t => BSONString(s"${t.name}:${t.value}") ) @@ -353,22 +352,21 @@ object BSONHandlers: import Study.From private[study] given BSONHandler[From] = tryHandler[From]( { case BSONString(v) => - v.split(' ') match { + v.split(' ') match case Array("scratch") => Success(From.Scratch) case Array("game", id) => Success(From.Game(GameId(id))) case Array("study", id) => Success(From.Study(StudyId(id))) case Array("relay") => Success(From.Relay(none)) case Array("relay", id) => Success(From.Relay(StudyId(id).some)) case _ => handlerBadValue(s"Invalid from $v") - } }, x => - BSONString(x match { + BSONString(x match case From.Scratch => "scratch" case From.Game(id) => s"game $id" case From.Study(id) => s"study $id" case From.Relay(id) => s"relay${id.fold("")(" " + _)}" - }) + ) ) import Settings.UserSelection private[study] given BSONHandler[UserSelection] = tryHandler[UserSelection]( @@ -401,7 +399,7 @@ object BSONHandlers: ) given BSONDocumentReader[Chapter.Metadata] with - def readDocument(doc: Bdoc) = for { + def readDocument(doc: Bdoc) = for id <- doc.getAsTry[StudyChapterId]("_id") name <- doc.getAsTry[StudyChapterName]("name") setup <- doc.getAsTry[Chapter.Setup]("setup") @@ -413,4 +411,4 @@ object BSONHandlers: .map(Outcome.fromResult) } hasRelayPath = doc.getAsOpt[Bdoc]("relay").flatMap(_ string "path").exists(_.nonEmpty) - } yield Chapter.Metadata(id, name, setup, outcome, hasRelayPath) + yield Chapter.Metadata(id, name, setup, outcome, hasRelayPath) diff --git a/modules/study/src/main/Chapter.scala b/modules/study/src/main/Chapter.scala index 515fa2934c97a..0015237cb390d 100644 --- a/modules/study/src/main/Chapter.scala +++ b/modules/study/src/main/Chapter.scala @@ -87,7 +87,7 @@ case class Chapter( def withoutChildren = copy(root = root.withoutChildren) - def withoutChildrenIfPractice = if (isPractice) copy(root = root.withoutChildren) else this + def withoutChildrenIfPractice = if isPractice then copy(root = root.withoutChildren) else this def relayAndTags = relay map { Chapter.RelayAndTags(id, _, tags) } diff --git a/modules/study/src/main/ChapterMaker.scala b/modules/study/src/main/ChapterMaker.scala index 6017a1cbead3f..92c6820ec5bb3 100644 --- a/modules/study/src/main/ChapterMaker.scala +++ b/modules/study/src/main/ChapterMaker.scala @@ -28,7 +28,7 @@ final private class ChapterMaker( } case Some(game) => fromGame(study, game, data, order, userId, withRatings) } map { (c: Chapter) => - if (c.name.value.isEmpty) c.copy(name = Chapter defaultName order) else c + if c.name.value.isEmpty then c.copy(name = Chapter defaultName order) else c } def fromFenOrPgnOrBlank(study: Study, data: Data, order: Int, userId: UserId): Fu[Chapter] = @@ -37,12 +37,12 @@ final private class ChapterMaker( case None => fuccess(fromFenOrBlank(study, data, order, userId)) private def fromPgn(study: Study, pgn: PgnStr, data: Data, order: Int, userId: UserId): Fu[Chapter] = - for { + for contributors <- lightUser.asyncMany(study.members.contributorIds.toList) parsed <- PgnImport(pgn, contributors.flatten).toFuture recoverWith { case e: Exception => fufail(ValidationException(e.getMessage)) } - } yield Chapter.make( + yield Chapter.make( studyId = study.id, name = getChapterNameFromPgn(data, parsed), setup = Chapter.Setup( @@ -133,10 +133,9 @@ final private class ChapterMaker( setup = Chapter.Setup( !game.synthetic option game.id, game.variant, - data.orientation match { + data.orientation match case Orientation.Auto => Color.white case Orientation.Fixed(color) => color - } ), root = root, tags = PgnTags(tags), @@ -148,7 +147,7 @@ final private class ChapterMaker( ) def notifyChat(study: Study, game: Game, userId: UserId) = - if (study.isPublic) + if study.isPublic then List(game hasUserId userId option game.id.value, s"${game.id}/w".some).flatten foreach { chatId => chatApi.userChat.write( chatId = ChatId(chatId), diff --git a/modules/study/src/main/ChapterRepo.scala b/modules/study/src/main/ChapterRepo.scala index a5d42e9aab1a6..265df1c7f9d39 100644 --- a/modules/study/src/main/ChapterRepo.scala +++ b/modules/study/src/main/ChapterRepo.scala @@ -11,7 +11,7 @@ import lila.db.AsyncColl import lila.db.dsl.{ *, given } import lila.tree.{ Branch, Branches } -import Node.{ BsonFields => F } +import Node.{ BsonFields as F } final class ChapterRepo(val coll: AsyncColl)(using Executor, akka.stream.Materializer): diff --git a/modules/study/src/main/CommentParser.scala b/modules/study/src/main/CommentParser.scala index 96cb7e18242dd..bacbd82435897 100644 --- a/modules/study/src/main/CommentParser.scala +++ b/modules/study/src/main/CommentParser.scala @@ -32,13 +32,13 @@ private[study] object CommentParser: private type ClockAndComment = (Option[Centis], String) private def readCentis(hours: String, minutes: String, seconds: String): Option[Centis] = - for { + for h <- hours.toIntOption m <- minutes.toIntOption cs <- seconds.toDoubleOption match case Some(s) => Some(Maths.roundAt(s * 100, 0).toInt) case _ => none - } yield Centis(h * 360000 + m * 6000 + cs) + yield Centis(h * 360000 + m * 6000 + cs) private val clockHourMinuteRegex = """^(\d++):(\d+)$""".r private val clockHourMinuteSecondRegex = """^(\d++):(\d++)[:\.](\d+)$""".r @@ -70,10 +70,10 @@ private[study] object CommentParser: comment match case circlesRegex(str) => val circles = str.split(',').toList.map(_.trim).flatMap { c => - for { + for color <- c.headOption pos <- Square fromKey c.drop(1) - } yield Shape.Circle(toBrush(color), pos) + yield Shape.Circle(toBrush(color), pos) } Shapes(circles) -> circlesRemoveRegex.replaceAllIn(comment, "").trim case _ => Shapes(Nil) -> comment @@ -82,11 +82,11 @@ private[study] object CommentParser: comment match case arrowsRegex(str) => val arrows = str.split(',').toList.flatMap { c => - for { + for color <- c.headOption orig <- Square fromKey c.slice(1, 3) dest <- Square fromKey c.slice(3, 5) - } yield Shape.Arrow(toBrush(color), orig, dest) + yield Shape.Arrow(toBrush(color), orig, dest) } Shapes(arrows) -> arrowsRemoveRegex.replaceAllIn(comment, "").trim case _ => Shapes(Nil) -> comment diff --git a/modules/study/src/main/ExplorerGame.scala b/modules/study/src/main/ExplorerGame.scala index b6a9bbb68d757..c95a945722420 100644 --- a/modules/study/src/main/ExplorerGame.scala +++ b/modules/study/src/main/ExplorerGame.scala @@ -20,7 +20,7 @@ final private class ExplorerGame( } def insert(study: Study, position: Position, gameId: GameId): Fu[Option[(Chapter, UciPath)]] = - if (position.chapter.isOverweight) + if position.chapter.isOverweight then logger.info(s"Overweight chapter ${study.id}/${position.chapter.id}") fuccess(none) else @@ -46,7 +46,7 @@ final private class ExplorerGame( val (path, foundGameNode) = gameNodes.foldLeft((UciPath.root, none[Branch])) { case ((path, None), gameNode) => val nextPath = path + gameNode.id - if (fromNode.children.nodeAt(nextPath).isDefined) (nextPath, none) + if fromNode.children.nodeAt(nextPath).isDefined then (nextPath, none) else (path, gameNode.some) case (found, _) => found } diff --git a/modules/study/src/main/PgnImport.scala b/modules/study/src/main/PgnImport.scala index 461825fc59edd..26b90a73f721c 100644 --- a/modules/study/src/main/PgnImport.scala +++ b/modules/study/src/main/PgnImport.scala @@ -90,11 +90,11 @@ object PgnImport: ( (shapes ++ s), c orElse clock, - (str.trim match { + (str.trim match case "" => comments case com => comments + Comment(Comment.Id.make, Comment.Text(com), annotator | Comment.Author.Lichess) - }) + ) ) } @@ -122,7 +122,7 @@ object PgnImport: val game = moveOrDrop.applyGame(prev) val uci = moveOrDrop.toUci val sanStr = moveOrDrop.toSanStr - parseComments(node.value.metas.comments, annotator) match { + parseComments(node.value.metas.comments, annotator) match case (shapes, clock, comments) => Branch( id = UciCharPair(uci), @@ -137,7 +137,6 @@ object PgnImport: crazyData = game.situation.board.crazyData, children = node.child.fold(Branches.empty)(makeBranches(game, _, annotator)) ).some - } ) catch case _: StackOverflowError => @@ -155,7 +154,7 @@ object PgnImport: case Some(main) if children.variations.exists(_.id == main.id) => Branches { main +: children.variations.flatMap { node => - if (node.id == main.id) node.children.nodes + if node.id == main.id then node.children.nodes else List(node) } } diff --git a/modules/study/src/main/PgnTags.scala b/modules/study/src/main/PgnTags.scala index 338037c725210..f0e1f7ba3053c 100644 --- a/modules/study/src/main/PgnTags.scala +++ b/modules/study/src/main/PgnTags.scala @@ -19,7 +19,7 @@ object PgnTags: }) private def removeContradictingTermination(tags: Tags) = - if (tags.outcome.isDefined) + if tags.outcome.isDefined then Tags(tags.value.filterNot { t => t.name == Tag.Termination && t.value.toLowerCase == "unterminated" }) diff --git a/modules/study/src/main/Study.scala b/modules/study/src/main/Study.scala index 7e5f3a2949227..5f730e9075357 100644 --- a/modules/study/src/main/Study.scala +++ b/modules/study/src/main/Study.scala @@ -40,7 +40,7 @@ case class Study( def isCurrent(c: Chapter.Like) = c.id == position.chapterId - def withChapter(c: Chapter.Like): Study = if (isCurrent(c)) this else rewindTo(c) + def withChapter(c: Chapter.Like): Study = if isCurrent(c) then this else rewindTo(c) def rewindTo(c: Chapter.Like): Study = copy(position = Position.Ref(chapterId = c.id, path = UciPath.root)) @@ -108,7 +108,7 @@ object Study: def compute(likes: Likes, createdAt: Instant) = Rank(createdAt plusHours likesToHours(likes)) private def likesToHours(likes: Likes): Int = - if (likes < 1) 0 + if likes < 1 then 0 else (5 * math.log(likes) + 1).toInt.min(likes) * 24 enum From: diff --git a/modules/study/src/main/StudyApi.scala b/modules/study/src/main/StudyApi.scala index 7e582dcb027ba..4f1ce3937b756 100644 --- a/modules/study/src/main/StudyApi.scala +++ b/modules/study/src/main/StudyApi.scala @@ -261,7 +261,7 @@ final class StudyApi( private def updateConceal(study: Study, chapter: Chapter, position: Position.Ref) = chapter.conceal so { conceal => chapter.root.lastMainlinePlyOf(position.path).some.filter(_ > conceal) so { newConceal => - if (newConceal >= chapter.root.lastMainlinePly) + if newConceal >= chapter.root.lastMainlinePly then chapterRepo.removeConceal(chapter.id) >>- sendTo(study.id)(_.setConceal(position, none)) else @@ -307,7 +307,7 @@ final class StudyApi( chapter .updateRoot: _.withChildren: children => - if (toMainline) children.promoteToMainlineAt(position.path) + if toMainline then children.promoteToMainlineAt(position.path) else children.promoteUpAt(position.path).map(_._1) .match case Some(newChapter) => @@ -520,7 +520,7 @@ final class StudyApi( sequenceStudyWithChapter(studyId, data.position.chapterId): case Study.WithChapter(study, chapter) => Contribute(who.u, study): - if (data.insert) + if data.insert then explorerGameHandler.insert(study, Position(chapter, data.position.path), data.gameId) flatMap { case None => fufail(s"Invalid explorerGame insert $studyId $data") >>- @@ -606,25 +606,24 @@ final class StudyApi( name = name, practice = data.isPractice option true, gamebook = data.isGamebook option true, - conceal = (chapter.conceal, data.isConceal) match { + conceal = (chapter.conceal, data.isConceal) match case (None, true) => chapter.root.ply.some case (Some(_), false) => None case _ => chapter.conceal - }, + , setup = chapter.setup.copy( - orientation = data.orientation match { + orientation = data.orientation match case ChapterMaker.Orientation.Fixed(color) => color case _ => chapter.setup.orientation - } ), description = data.hasDescription option { chapter.description | "-" } ) - if (chapter == newChapter) funit + if chapter == newChapter then funit else chapterRepo.update(newChapter) >> { - if (chapter.conceal != newChapter.conceal) + if chapter.conceal != newChapter.conceal then (newChapter.conceal.isDefined && study.position.chapterId == chapter.id).so { val newPosition = study.position.withPath(UciPath.root) studyRepo.setPosition(study.id, newPosition) @@ -637,7 +636,7 @@ final class StudyApi( (newChapter.practice != chapter.practice) || (newChapter.gamebook != chapter.gamebook) || (newChapter.description != chapter.description) - if (shouldReload) sendTo(study.id)(_.updateChapter(chapter.id, who)) + if shouldReload then sendTo(study.id)(_.updateChapter(chapter.id, who)) else reloadChapters(study) } } @@ -663,7 +662,7 @@ final class StudyApi( chapterRepo.byIdAndStudy(chapterId, studyId) flatMapz { chapter => chapterRepo.orderedMetadataByStudy(studyId).flatMap { chaps => // deleting the only chapter? Automatically create an empty one - if (chaps.sizeIs < 2) + if chaps.sizeIs < 2 then chapterMaker( study, ChapterMaker.Data(StudyChapterName("Chapter 1")), @@ -748,11 +747,12 @@ final class StudyApi( def like(studyId: StudyId, v: Boolean)(who: Who): Funit = studyRepo.like(studyId, who.u, v) map { likes => sendTo(studyId)(_.setLiking(Study.Liking(likes, v), who)) - if (v) studyRepo byId studyId foreach { - _.filter(_.isPublic) foreach { study => - timeline ! (Propagate(StudyLike(who.u, study.id, study.name)) toFollowersOf who.u) + if v then + studyRepo byId studyId foreach { + _.filter(_.isPublic) foreach { study => + timeline ! (Propagate(StudyLike(who.u, study.id, study.name)) toFollowersOf who.u) + } } - } } def chapterIdNames(studyIds: List[StudyId]): Fu[Map[StudyId, Vector[Chapter.IdName]]] = @@ -804,7 +804,7 @@ final class StudyApi( // work around circular dependency private var socket: Option[StudySocket] = None - private[study] def registerSocket(s: StudySocket) = { socket = s.some } + private[study] def registerSocket(s: StudySocket) = socket = s.some private def sendTo(studyId: StudyId)(f: StudySocket => StudyId => Unit): Unit = socket.foreach: s => f(s)(studyId) diff --git a/modules/study/src/main/StudyInvite.scala b/modules/study/src/main/StudyInvite.scala index 727f801d4f302..81a12b9cd8cd8 100644 --- a/modules/study/src/main/StudyInvite.scala +++ b/modules/study/src/main/StudyInvite.scala @@ -45,13 +45,13 @@ final private class StudyInvite( _ <- relation.has(Block) so fufail[Unit]("This user does not want to join") isPresent <- getIsPresent(invited.id) _ <- - if (isPresent || Granter(_.StudyAdmin)) funit + if isPresent || Granter(_.StudyAdmin) then funit else prefApi.get(invited).map(_.studyInvite).flatMap { case Pref.StudyInvite.ALWAYS => funit case Pref.StudyInvite.NEVER => fufail("This user doesn't accept study invitations") case Pref.StudyInvite.FRIEND => - if (relation.has(Follow)) funit + if relation.has(Follow) then funit else fufail("This user only accept study invitations from friends") } _ <- studyRepo.addMember(study, StudyMember make invited) diff --git a/modules/study/src/main/StudyMaker.scala b/modules/study/src/main/StudyMaker.scala index 4549de8f90f6c..5c14a0edef4d0 100644 --- a/modules/study/src/main/StudyMaker.scala +++ b/modules/study/src/main/StudyMaker.scala @@ -55,7 +55,7 @@ final private class StudyMaker( user: User, withRatings: Boolean ): Fu[Study.WithChapter] = { - for { + for root <- chapterMaker.makeRoot(pov.game, data.form.pgnStr, initialFen) tags <- pgnDump.tags(pov.game, initialFen, none, withOpening = true, withRatings) name <- StudyChapterName from Namer.gameVsText(pov.game, withRatings)(using lightUserApi.async) @@ -76,7 +76,7 @@ final private class StudyMaker( gamebook = false, conceal = None ) - } yield Study.WithChapter(study withChapter chapter, chapter) + yield Study.WithChapter(study withChapter chapter, chapter) } addEffect { swc => chapterMaker.notifyChat(swc.study, pov.game, user.id) } diff --git a/modules/study/src/main/StudyMember.scala b/modules/study/src/main/StudyMember.scala index 1ce29ee158dd6..4825bb5e1be88 100644 --- a/modules/study/src/main/StudyMember.scala +++ b/modules/study/src/main/StudyMember.scala @@ -25,7 +25,7 @@ case class StudyMembers(members: StudyMember.MemberMap): def update(id: UserId, f: StudyMember => StudyMember) = copy( members = members.view.mapValues { m => - if (m.id == id) f(m) else m + if m.id == id then f(m) else m }.toMap ) diff --git a/modules/study/src/main/StudyMultiBoard.scala b/modules/study/src/main/StudyMultiBoard.scala index 8045e50f90103..a4848712c1f71 100644 --- a/modules/study/src/main/StudyMultiBoard.scala +++ b/modules/study/src/main/StudyMultiBoard.scala @@ -23,7 +23,7 @@ final class StudyMultiBoard( import StudyMultiBoard.* def json(studyId: StudyId, page: Int, playing: Boolean): Fu[JsObject] = { - if (page == 1 && !playing) firstPageCache.get(studyId) + if page == 1 && !playing then firstPageCache.get(studyId) else fetch(studyId, page, playing) } map { PaginatorJson(_) } diff --git a/modules/study/src/main/StudyRepo.scala b/modules/study/src/main/StudyRepo.scala index db644c3147d59..266690f02480a 100644 --- a/modules/study/src/main/StudyRepo.scala +++ b/modules/study/src/main/StudyRepo.scala @@ -244,7 +244,7 @@ final class StudyRepo(private[study] val coll: AsyncColl)(using def like(studyId: StudyId, userId: UserId, v: Boolean): Fu[Study.Likes] = coll: c => - c.update.one($id(studyId), if (v) $addToSet(F.likers -> userId) else $pull(F.likers -> userId)) >> { + c.update.one($id(studyId), if v then $addToSet(F.likers -> userId) else $pull(F.likers -> userId)) >> { countLikes(studyId).flatMap: case None => fuccess(Study.Likes(0)) case Some((likes, createdAt)) => @@ -273,11 +273,11 @@ final class StudyRepo(private[study] val coll: AsyncColl)(using ) .cursor[Bdoc]() .foldWhileM(0) { (count, doc) => - ~(for { + ~(for id <- doc.getAsOpt[StudyId]("_id") likes <- doc.getAsOpt[Study.Likes](F.likes) createdAt <- doc.getAsOpt[Instant](F.createdAt) - } yield coll: + yield coll: _.update .one( $id(id), diff --git a/modules/study/src/main/StudyTopic.scala b/modules/study/src/main/StudyTopic.scala index ecc99b3ec68f9..532a91c010c9f 100644 --- a/modules/study/src/main/StudyTopic.scala +++ b/modules/study/src/main/StudyTopic.scala @@ -77,7 +77,7 @@ final class StudyTopicApi(topicRepo: StudyTopicRepo, userTopicRepo: StudyUserTop def userTopics(user: User, json: String): Funit = val topics = - if (json.trim.isEmpty) StudyTopics.empty + if json.trim.isEmpty then StudyTopics.empty else Json.parse(json).validate[List[TagifyTopic]] match case JsSuccess(topics, _) => StudyTopics.fromStrs(topics.map(_.value), StudyTopics.userMax) diff --git a/modules/study/src/main/TreeBuilder.scala b/modules/study/src/main/TreeBuilder.scala index 9116bf49c9e5f..a2169d6a16b81 100644 --- a/modules/study/src/main/TreeBuilder.scala +++ b/modules/study/src/main/TreeBuilder.scala @@ -11,7 +11,7 @@ object TreeBuilder: // DEBUG should be done in BSONHandler def apply(root: Root, variant: Variant): Root = val dests = - if (variant.standard && root.fen.isInitial) initialStandardDests + if variant.standard && root.fen.isInitial then initialStandardDests else val sit = chess.Game(variant.some, root.fen.some).situation sit.playable(false) so sit.destinations diff --git a/modules/study/src/test/CommentParserTest.scala b/modules/study/src/test/CommentParserTest.scala index f6a247a8c43cd..4fd7dc3af4dca 100644 --- a/modules/study/src/test/CommentParserTest.scala +++ b/modules/study/src/test/CommentParserTest.scala @@ -3,7 +3,7 @@ package lila.study import chess.Centis import lila.tree.Node.Shapes -class CommentParserTest extends lila.common.LilaTest { +class CommentParserTest extends lila.common.LilaTest: import chess.format.pgn.Comment import scala.language.implicitConversions @@ -121,4 +121,3 @@ class CommentParserTest extends lila.common.LilaTest { shapes.value.size == 6 && clock == Some(Centis(3843300)) } -} diff --git a/modules/studySearch/src/main/Env.scala b/modules/studySearch/src/main/Env.scala index e39a7772f3118..9dcb3bd2d0ac6 100644 --- a/modules/studySearch/src/main/Env.scala +++ b/modules/studySearch/src/main/Env.scala @@ -31,11 +31,11 @@ final class Env( def apply(me: Option[User])(text: String, page: Int) = Paginator[Study.WithChaptersAndLiked]( - adapter = new AdapterLike[Study] { + adapter = new AdapterLike[Study]: def query = Query(text take 100, me.map(_.id)) def nbResults = api count query def slice(offset: Int, length: Int) = api.search(query, From(offset), Size(length)) - } mapFutureList pager.withChaptersAndLiking(me), + mapFutureList pager.withChaptersAndLiking(me), currentPage = page, maxPerPage = pager.maxPerPage ) diff --git a/modules/studySearch/src/main/StudySearchApi.scala b/modules/studySearch/src/main/StudySearchApi.scala index 8d4f8c5138f04..9f2ceffdb354d 100644 --- a/modules/studySearch/src/main/StudySearchApi.scala +++ b/modules/studySearch/src/main/StudySearchApi.scala @@ -107,7 +107,7 @@ final class StudySearchApi( case c: ESClientHttp => { val sinceOption: Either[Unit, Option[LocalDate]] = - if (sinceStr == "reset") Left(()) else Right(parseDate(sinceStr)) + if sinceStr == "reset" then Left(()) else Right(parseDate(sinceStr)) val since = sinceOption match case Right(None) => sys error "Missing since date argument" case Right(Some(date)) => diff --git a/modules/swiss/src/main/PairingSystem.scala b/modules/swiss/src/main/PairingSystem.scala index df7866e44643c..9950284cf6999 100644 --- a/modules/swiss/src/main/PairingSystem.scala +++ b/modules/swiss/src/main/PairingSystem.scala @@ -21,8 +21,8 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using private def invoke(swiss: Swiss, input: Source[String, ?]): Fu[List[String]] = withTempFile(swiss, input) { file => val flavour = - if (swiss.nbPlayers < 250) "dutch" - else if (swiss.nbPlayers < 700) "burstein" + if swiss.nbPlayers < 250 then "dutch" + else if swiss.nbPlayers < 700 then "burstein" else "fast" val command = s"$executable --$flavour $file -p" val stdout = new collection.mutable.ListBuffer[String] @@ -32,9 +32,9 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using command ! ProcessLogger(stdout append _, stderr append _ unit) } } - if (status != 0) + if status != 0 then val error = stderr.toString - if (error contains "No valid pairing exists") Nil + if error contains "No valid pairing exists" then Nil else throw PairingSystem.BBPairingException(error, swiss) else stdout.toList } @@ -49,10 +49,10 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using Left(SwissPairing.Bye(userId)) } case Array(w, b) => - for { + for white <- w.toIntOption flatMap idsToPlayers.get black <- b.toIntOption flatMap idsToPlayers.get - } yield Right(SwissPairing.Pending(white, black)) + yield Right(SwissPairing.Pending(white, black)) } .flatten diff --git a/modules/swiss/src/main/Swiss.scala b/modules/swiss/src/main/Swiss.scala index 6eec1c181d385..6227839f1dd59 100644 --- a/modules/swiss/src/main/Swiss.scala +++ b/modules/swiss/src/main/Swiss.scala @@ -54,8 +54,8 @@ case class Swiss( def estimatedDurationString = val minutes = estimatedDuration.toMinutes - if (minutes < 60) s"${minutes}m" - else s"${minutes / 60}h" + (if (minutes % 60 != 0) s" ${minutes % 60}m" else "") + if minutes < 60 then s"${minutes}m" + else s"${minutes / 60}h" + (if minutes % 60 != 0 then s" ${minutes % 60}m" else "") def roundInfo = Swiss.RoundInfo(teamId, settings.chatFor) diff --git a/modules/swiss/src/main/SwissApi.scala b/modules/swiss/src/main/SwissApi.scala index e79e01b5c7000..fb79844e6ade7 100644 --- a/modules/swiss/src/main/SwissApi.scala +++ b/modules/swiss/src/main/SwissApi.scala @@ -87,16 +87,17 @@ final class SwissApi( def update(swissId: SwissId, data: SwissForm.SwissData): Fu[Option[Swiss]] = Sequencing(swissId)(cache.swissCache.byId): old => val position = - if (old.isCreated || old.settings.position.isDefined) data.realVariant.standard so data.realPosition + if old.isCreated || old.settings.position.isDefined then + data.realVariant.standard so data.realPosition else old.settings.position val swiss = old.copy( name = data.name | old.name, - clock = if (old.isCreated) data.clock else old.clock, - variant = if (old.isCreated && data.variant.isDefined) data.realVariant else old.variant, + clock = if old.isCreated then data.clock else old.clock, + variant = if old.isCreated && data.variant.isDefined then data.realVariant else old.variant, startsAt = data.startsAt.ifTrue(old.isCreated) | old.startsAt, nextRoundAt = - if (old.isCreated) Some(data.startsAt | old.startsAt) + if old.isCreated then Some(data.startsAt | old.startsAt) else old.nextRoundAt, settings = old.settings.copy( nbRounds = data.nbRounds, @@ -105,7 +106,7 @@ final class SwissApi( position = position, chatFor = data.chatFor | old.settings.chatFor, roundInterval = - if (data.roundInterval.isDefined) data.realRoundInterval + if data.roundInterval.isDefined then data.realRoundInterval else old.settings.roundInterval, password = data.password, conditions = data.conditions, @@ -113,12 +114,9 @@ final class SwissApi( manualPairings = ~data.manualPairings ) ) pipe { s => - if ( - s.isStarted && s.nbOngoing == 0 && (s.nextRoundAt.isEmpty || old.settings.manualRounds) && !s.settings.manualRounds - ) - s.copy(nextRoundAt = nowInstant.plusSeconds(s.settings.roundInterval.toSeconds.toInt).some) - else if (s.settings.manualRounds && !old.settings.manualRounds) - s.copy(nextRoundAt = none) + if s.isStarted && s.nbOngoing == 0 && (s.nextRoundAt.isEmpty || old.settings.manualRounds) && !s.settings.manualRounds + then s.copy(nextRoundAt = nowInstant.plusSeconds(s.settings.roundInterval.toSeconds.toInt).some) + else if s.settings.manualRounds && !old.settings.manualRounds then s.copy(nextRoundAt = none) else s } mongo.swiss.update.one($id(old.id), addFeaturable(swiss)).void >> { @@ -388,7 +386,7 @@ final class SwissApi( private[swiss] def finishGame(game: Game): Funit = game.swissId.so: swissId => Sequencing(swissId)(cache.swissCache.byId): swiss => - if (!swiss.isStarted) + if !swiss.isStarted then logger.info(s"Removing pairing ${game.id} finished after swiss ${swiss.id}") mongo.pairing.delete.one($id(game.id)) inject false else @@ -399,11 +397,10 @@ final class SwissApi( Right(game.winnerColor): SwissPairing.Status ) .flatMap { result => - if (result.nModified == 0) fuccess(false) // dedup + if result.nModified == 0 then fuccess(false) // dedup else { - if (swiss.nbOngoing > 0) - mongo.swiss.update.one($id(swiss.id), $inc("nbOngoing" -> -1)) + if swiss.nbOngoing > 0 then mongo.swiss.update.one($id(swiss.id), $inc("nbOngoing" -> -1)) else fuccess: logger.warn(s"swiss ${swiss.id} nbOngoing = ${swiss.nbOngoing}") @@ -415,9 +412,10 @@ final class SwissApi( .void } >> { (swiss.nbOngoing <= 1) so { - if (swiss.round.value == swiss.settings.nbRounds) doFinish(swiss) - else if (swiss.settings.manualRounds) fuccess: - systemChat(swiss.id, s"Round ${swiss.round.value + 1} needs to be scheduled.") + if swiss.round.value == swiss.settings.nbRounds then doFinish(swiss) + else if swiss.settings.manualRounds then + fuccess: + systemChat(swiss.id, s"Round ${swiss.round.value + 1} needs to be scheduled.") else mongo.swiss .updateField( @@ -447,7 +445,7 @@ final class SwissApi( private[swiss] def finish(oldSwiss: Swiss): Funit = Sequencing(oldSwiss.id)(cache.swissCache.startedById): swiss => mongo.pairing.exists($doc(SwissPairing.Fields.swissId -> swiss.id)) flatMap { - if (_) doFinish(swiss) + if _ then doFinish(swiss) else destroy(swiss) } private def doFinish(swiss: Swiss): Funit = @@ -467,7 +465,7 @@ final class SwissApi( .void zip SwissPairing.fields { f => mongo.pairing.delete.one($doc(f.swissId -> swiss.id, f.status -> true)) map { res => - if (res.n > 0) logger.warn(s"Swiss ${swiss.id} finished with ${res.n} ongoing pairings") + if res.n > 0 then logger.warn(s"Swiss ${swiss.id} finished with ${res.n} ongoing pairings") } } void } >>- { @@ -485,12 +483,12 @@ final class SwissApi( } def kill(swiss: Swiss): Funit = { - if (swiss.isStarted) + if swiss.isStarted then finish(swiss) >>- { logger.info(s"Tournament ${swiss.id} cancelled by its creator.") systemChat(swiss.id, "Tournament cancelled by its creator.") } - else if (swiss.isCreated) destroy(swiss) + else if swiss.isCreated then destroy(swiss) else funit } >>- cache.featuredInTeam.invalidate(swiss.teamId) @@ -522,10 +520,10 @@ final class SwissApi( .flatMap: _.traverse_ : id => Sequencing(id)(cache.swissCache.notFinishedById) { swiss => - if (swiss.round.value >= swiss.settings.nbRounds) doFinish(swiss) - else if (swiss.nbPlayers >= 2) + if swiss.round.value >= swiss.settings.nbRounds then doFinish(swiss) + else if swiss.nbPlayers >= 2 then countPresentPlayers(swiss) flatMap { nbPresent => - if (nbPresent < 2) + if nbPresent < 2 then systemChat(swiss.id, "Not enough players left.") doFinish(swiss) else @@ -545,7 +543,7 @@ final class SwissApi( } } >>- cache.swissCache.clear(swiss.id) } - else if (swiss.startsAt isBefore nowInstant.minusMinutes(60)) destroy(swiss) + else if swiss.startsAt isBefore nowInstant.minusMinutes(60) then destroy(swiss) else systemChat(swiss.id, "Not enough players for first round; delaying start.", volatile = true) mongo.swiss.update @@ -586,10 +584,9 @@ final class SwissApi( lila.mon.swiss.games("ongoing").record(ongoing.size) lila.mon.swiss.games("flagged").record(flagged.size) lila.mon.swiss.games("missing").record(missingIds.size) - if (flagged.nonEmpty) + if flagged.nonEmpty then Bus.publish(lila.hub.actorApi.map.TellMany(flagged.map(_.id.value), QuietFlag), "roundSocket") - if (missingIds.nonEmpty) - mongo.pairing.delete.one($inIds(missingIds)) + if missingIds.nonEmpty then mongo.pairing.delete.one($inIds(missingIds)) finished } } flatMap { diff --git a/modules/swiss/src/main/SwissBan.scala b/modules/swiss/src/main/SwissBan.scala index bbaff76bafab0..a5b86f3f19022 100644 --- a/modules/swiss/src/main/SwissBan.scala +++ b/modules/swiss/src/main/SwissBan.scala @@ -21,7 +21,7 @@ final class SwissBanApi(mongo: SwissMongo)(using Executor): def onGameFinish(game: Game) = game.userIds .map { userId => - if (game.playerWhoDidNotMove.exists(_.userId has userId)) onStall(userId) + if game.playerWhoDidNotMove.exists(_.userId has userId) then onStall(userId) else onGoodGame(userId) } .parallel @@ -30,8 +30,8 @@ final class SwissBanApi(mongo: SwissMongo)(using Executor): private def onStall(user: UserId): Funit = get(user) flatMap { prev => val hours: Int = prev .fold(24) { ban => - if (ban.until.isBefore(nowInstant)) ban.hours * 2 // consecutive - else (ban.hours * 1.5).toInt // simultaneous + if ban.until.isBefore(nowInstant) then ban.hours * 2 // consecutive + else (ban.hours * 1.5).toInt // simultaneous } .atMost(30 * 24) mongo.ban.update diff --git a/modules/swiss/src/main/SwissBoard.scala b/modules/swiss/src/main/SwissBoard.scala index 4eba7a26aaf2d..d046687c79508 100644 --- a/modules/swiss/src/main/SwissBoard.scala +++ b/modules/swiss/src/main/SwissBoard.scala @@ -55,14 +55,14 @@ final private class SwissBoardApi( .distinct .take(displayBoards) .flatMap { pairing => - for { + for p1 <- playerMap get pairing.white p2 <- playerMap get pairing.black u1 <- lightUserApi sync p1.userId u2 <- lightUserApi sync p2.userId r1 <- ranks get p1.userId r2 <- ranks get p2.userId - } yield SwissBoard( + yield SwissBoard( pairing.gameId, white = SwissBoard.Player(u1, r1, p1.rating), black = SwissBoard.Player(u2, r2, p2.rating) diff --git a/modules/swiss/src/main/SwissCondition.scala b/modules/swiss/src/main/SwissCondition.scala index c07c604d7f884..84eb9a0ebf69b 100644 --- a/modules/swiss/src/main/SwissCondition.scala +++ b/modules/swiss/src/main/SwissCondition.scala @@ -7,7 +7,7 @@ import lila.user.{ Me, UserPerfs } import lila.gathering.{ Condition, ConditionList } import lila.gathering.Condition.* import alleycats.Zero -import lila.i18n.{ I18nKeys => trans } +import lila.i18n.{ I18nKeys as trans } import lila.rating.Perf object SwissCondition: diff --git a/modules/swiss/src/main/SwissDirector.scala b/modules/swiss/src/main/SwissDirector.scala index 8451b737eb391..66113438f209d 100644 --- a/modules/swiss/src/main/SwissDirector.scala +++ b/modules/swiss/src/main/SwissDirector.scala @@ -23,10 +23,10 @@ final private class SwissDirector( (manualPairing(from) | pairingSystem(from)) .flatMap { pendings => val pendingPairings = pendings.collect { case Right(p) => p } - if (pendingPairings.isEmpty) fuccess(none) // terminate + if pendingPairings.isEmpty then fuccess(none) // terminate else val swiss = from.startRound - for { + for players <- SwissPlayer.fields { f => mongo.player.list[SwissPlayer]($doc(f.swissId -> swiss.id)) } @@ -67,10 +67,10 @@ final private class SwissDirector( games = pairings.map(makeGame(swiss, players.mapBy(_.userId))) _ <- games.traverse_ : game => gameRepo.insertDenormalized(game) >>- onStart(game.id) - } yield swiss.some + yield swiss.some } .recover { case PairingSystem.BBPairingException(msg, input) => - if (msg contains "The number of rounds is larger than the reported number of rounds.") none + if msg contains "The number of rounds is larger than the reported number of rounds." then none else logger.warn(s"BBPairing ${from.id} $msg") logger.info(s"BBPairing ${from.id} $input") @@ -84,7 +84,7 @@ final private class SwissDirector( chess = chess .Game( variantOption = Some { - if (swiss.settings.position.isEmpty) swiss.variant + if swiss.settings.position.isEmpty then swiss.variant else chess.variant.FromPosition }, fen = swiss.settings.position diff --git a/modules/swiss/src/main/SwissForm.scala b/modules/swiss/src/main/SwissForm.scala index 5b0e8d85ccc8f..ddb4619b3430e 100644 --- a/modules/swiss/src/main/SwissForm.scala +++ b/modules/swiss/src/main/SwissForm.scala @@ -60,7 +60,7 @@ final class SwissForm(using mode: Mode): name = none, clock = ClockConfig(LimitSeconds(180), IncrementSeconds(0)), startsAt = Some(nowInstant plusSeconds { - if (mode == Mode.Prod) 60 * 10 else 20 + if mode == Mode.Prod then 60 * 10 else 20 }), variant = Variant.default.key.some, rated = true.some, @@ -110,7 +110,7 @@ object SwissForm: LimitSeconds raw clockLimits, l => s"${chess.Clock.Config(LimitSeconds(l), IncrementSeconds(0)).limitString}${ - if (l <= 1) " minute" else " minutes" + if l <= 1 then " minute" else " minutes" }" ) @@ -141,11 +141,11 @@ object SwissForm: val roundIntervalChoices = options( roundIntervals, s => - if (s == Swiss.RoundInterval.auto) s"Automatic" - else if (s == Swiss.RoundInterval.manual) s"Manually schedule each round" - else if (s < 60) s"$s seconds" - else if (s < 3600) s"${s / 60} minute(s)" - else if (s < 24 * 3600) s"${s / 3600} hour(s)" + if s == Swiss.RoundInterval.auto then s"Automatic" + else if s == Swiss.RoundInterval.manual then s"Manually schedule each round" + else if s < 60 then s"$s seconds" + else if s < 3600 then s"${s / 60} minute(s)" + else if s < 24 * 3600 then s"${s / 3600} hour(s)" else s"${s / 24 / 3600} days(s)" ) diff --git a/modules/swiss/src/main/SwissJson.scala b/modules/swiss/src/main/SwissJson.scala index 320cea7e6ac78..e6399642dd443 100644 --- a/modules/swiss/src/main/SwissJson.scala +++ b/modules/swiss/src/main/SwissJson.scala @@ -42,14 +42,14 @@ final class SwissJson( socketVersion: Option[SocketVersion] = None, playerInfo: Option[SwissPlayer.ViewExt] = None )(using lang: Lang): Fu[JsObject] = { - for { + for myInfo <- me.so { fetchMyInfo(swiss, _) } page = reqPage orElse myInfo.map(_.page) getOrElse 1 standing <- standingApi(swiss, page) podium <- podiumJson(swiss) boards <- boardApi(swiss.id) stats <- statsApi(swiss) - } yield swissJsonBase(swiss) ++ Json + yield swissJsonBase(swiss) ++ Json .obj( "canJoin" -> { { @@ -167,8 +167,8 @@ object SwissJson: "nbPlayers" -> swiss.nbPlayers, "nbOngoing" -> swiss.nbOngoing, "status" -> { - if (swiss.isStarted) "started" - else if (swiss.isFinished) "finished" + if swiss.isStarted then "started" + else if swiss.isFinished then "finished" else "created" } ) @@ -241,8 +241,8 @@ object SwissJson: private def pairingJsonMin(player: SwissPlayer, pairing: SwissPairing): String = val status = - if (pairing.isOngoing) "o" - else pairing.resultFor(player.userId).fold("d") { r => if (r) "w" else "l" } + if pairing.isOngoing then "o" + else pairing.resultFor(player.userId).fold("d") { r => if r then "w" else "l" } s"${pairing.gameId}$status" private def pairingJson(player: SwissPlayer, pairing: SwissPairing) = diff --git a/modules/swiss/src/main/SwissOfficialSchedule.scala b/modules/swiss/src/main/SwissOfficialSchedule.scala index 8c2991e9441c0..f0d19fbabf7fd 100644 --- a/modules/swiss/src/main/SwissOfficialSchedule.scala +++ b/modules/swiss/src/main/SwissOfficialSchedule.scala @@ -57,7 +57,7 @@ final private class SwissOfficialSchedule(mongo: SwissMongo, cache: SwissCache)( } .parallel .map { res => - if (res.exists(identity)) cache.featuredInTeam.invalidate(lichessTeamId) + if res.exists(identity) then cache.featuredInTeam.invalidate(lichessTeamId) } private def makeSwiss(config: Config, startAt: Instant) = diff --git a/modules/swiss/src/main/SwissPairing.scala b/modules/swiss/src/main/SwissPairing.scala index 9610a538ef185..5ddc547950621 100644 --- a/modules/swiss/src/main/SwissPairing.scala +++ b/modules/swiss/src/main/SwissPairing.scala @@ -16,14 +16,14 @@ case class SwissPairing( def players = List(white, black) def has(userId: UserId) = white == userId || black == userId def colorOf(userId: UserId) = chess.Color.fromWhite(white == userId) - def opponentOf(userId: UserId) = if (white == userId) black else white + def opponentOf(userId: UserId) = if white == userId then black else white def winner: Option[UserId] = (~status.toOption).map(apply) def isOngoing = status.isLeft def resultFor(userId: UserId) = winner.map(userId.==) def whiteWins = status == Right(Some(Color.White)) def blackWins = status == Right(Some(Color.Black)) def isDraw = status == Right(None) - def strResultOf(color: Color) = status.fold(_ => "*", _.fold("1/2")(c => if (c == color) "1" else "0")) + def strResultOf(color: Color) = status.fold(_ => "*", _.fold("1/2")(c => if c == color then "1" else "0")) def forfeit(userId: UserId) = copy(status = Right(Some(!colorOf(userId))), isForfeit = true) object SwissPairing: diff --git a/modules/swiss/src/main/SwissSheet.scala b/modules/swiss/src/main/SwissSheet.scala index 629d5342cea86..80deee3d36bd2 100644 --- a/modules/swiss/src/main/SwissSheet.scala +++ b/modules/swiss/src/main/SwissSheet.scala @@ -77,8 +77,8 @@ private object SwissSheet: case Left(_) => Ongoing case Right(None) => Draw case Right(Some(color)) if pairing.isForfeit => - if (pairing(color) == player.userId) ForfeitWin else ForfeitLoss - case Right(Some(color)) => if (pairing(color) == player.userId) Win else Loss + if pairing(color) == player.userId then ForfeitWin else ForfeitLoss + case Right(Some(color)) => if pairing(color) == player.userId then Win else Loss case None if player.byes(round) => Bye case None if round.value == 1 => Late case None => Absent diff --git a/modules/swiss/src/main/SwissStandingApi.scala b/modules/swiss/src/main/SwissStandingApi.scala index 1b906cf52f6ce..750736d1ef8b4 100644 --- a/modules/swiss/src/main/SwissStandingApi.scala +++ b/modules/swiss/src/main/SwissStandingApi.scala @@ -27,7 +27,7 @@ final class SwissStandingApi( def apply(swiss: Swiss, forPage: Int): Fu[JsObject] = val page = forPage atMost Math.ceil(swiss.nbPlayers.toDouble / perPage).toInt atLeast 1 fuccess(pageCache.getIfPresent(swiss.id -> page)) getOrElse { - if (page == 1) first get swiss.id + if page == 1 then first get swiss.id else compute(swiss, page) } @@ -73,7 +73,7 @@ final class SwissStandingApi( mongo.swiss.byId[Swiss](id) orFail s"No such tournament: $id" flatMap { compute(_, page) } private def compute(swiss: Swiss, page: Int): Fu[JsObject] = - for { + for rankedPlayers <- bestWithRankByPage(swiss.id, perPage, page atLeast 1) pairings <- !swiss.isCreated so SwissPairing.fields { f => mongo.pairing @@ -85,7 +85,7 @@ final class SwissStandingApi( } sheets = SwissSheet.many(swiss, rankedPlayers.map(_.player), pairings) users <- lightUserApi asyncManyFallback rankedPlayers.map(_.player.userId) - } yield Json.obj( + yield Json.obj( "page" -> page, "players" -> rankedPlayers .zip(users) diff --git a/modules/swiss/src/main/SwissStats.scala b/modules/swiss/src/main/SwissStats.scala index 693e44bf78a53..d94a41223ac8c 100644 --- a/modules/swiss/src/main/SwissStats.scala +++ b/modules/swiss/src/main/SwissStats.scala @@ -50,14 +50,14 @@ final class SwissStatsApi( blackWins + pairing.blackWins.so(1), draws + pairing.isDraw.so(1) ) - } match { + } match case (games, whiteWins, blackWins, draws) => sheet.outcomes.foldLeft((0, 0)) { case ((byes, absences), outcome) => ( byes + (outcome == SwissSheet.Outcome.Bye).so(1), absences + (outcome == SwissSheet.Outcome.Absent).so(1) ) - } match { + } match case (byes, absences) => stats.copy( games = stats.games + games, @@ -68,8 +68,6 @@ final class SwissStatsApi( absences = stats.absences + absences, averageRating = stats.averageRating + player.rating ) - } - } })(Keep.right) .run() .dmap { s => diff --git a/modules/swiss/src/main/SwissTrf.scala b/modules/swiss/src/main/SwissTrf.scala index 83d7d1187d38a..703439b793234 100644 --- a/modules/swiss/src/main/SwissTrf.scala +++ b/modules/swiss/src/main/SwissTrf.scala @@ -63,7 +63,7 @@ final class SwissTrf( 97 -> pairing.map(_ colorOf p.userId).so(_.fold("w", "b")), 99 -> { import SwissSheet.Outcome.* - outcome match { + outcome match case Absent => "-" case Late => "H" case Bye => "U" @@ -73,7 +73,6 @@ final class SwissTrf( case Ongoing => "Z" case ForfeitLoss => "-" case ForfeitWin => "+" - } } ).map { case (l, s) => (l + (rn.value - 1) * 10, s) } } @@ -113,16 +112,16 @@ final class SwissTrf( .toMap private def forbiddenPairings(swiss: Swiss, playerIds: PlayerIds): Source[String, ?] = - if (swiss.settings.forbiddenPairings.isEmpty) Source.empty[String] + if swiss.settings.forbiddenPairings.isEmpty then Source.empty[String] else Source.fromIterator { () => swiss.settings.forbiddenPairings.linesIterator.flatMap { _.trim.toLowerCase.split(' ').map(_.trim) match case Array(u1, u2) if u1 != u2 => - for { + for id1 <- playerIds.get(UserId(u1)) id2 <- playerIds.get(UserId(u2)) - } yield s"XXP $id1 $id2" + yield s"XXP $id1 $id2" case _ => none } } diff --git a/modules/swiss/src/test/SwissScoringTest.scala b/modules/swiss/src/test/SwissScoringTest.scala index 645261b78a6f5..8d45735847a43 100644 --- a/modules/swiss/src/test/SwissScoringTest.scala +++ b/modules/swiss/src/test/SwissScoringTest.scala @@ -91,7 +91,8 @@ class SwissScoringTest extends munit.FunSuite: extension (e: SwissPlayer) def pointsAndTieBreak: (Float, Float) = (e.points.value, e.tieBreak.value.toFloat) - def print = { println(e); e } + def print = + println(e); e def makeUserId(name: Char) = UserId(s"user-$name") def makeSwissId = SwissId("swissId") diff --git a/modules/team/src/main/MemberRepo.scala b/modules/team/src/main/MemberRepo.scala index 6252741d151dc..0c54ad7d05318 100644 --- a/modules/team/src/main/MemberRepo.scala +++ b/modules/team/src/main/MemberRepo.scala @@ -43,7 +43,7 @@ final class MemberRepo(val coll: Coll)(using Executor): coll.update .one( selectId(teamId, userId), - if (v) $unset("unsub") + if v then $unset("unsub") else $set("unsub" -> true) ) .void diff --git a/modules/team/src/main/PaginatorBuilder.scala b/modules/team/src/main/PaginatorBuilder.scala index 20028050904db..afc6a9e9fc391 100644 --- a/modules/team/src/main/PaginatorBuilder.scala +++ b/modules/team/src/main/PaginatorBuilder.scala @@ -53,7 +53,7 @@ final private[team] class PaginatorBuilder( final private class TeamAdapter(val team: Team) extends AdapterLike[LightUser] with MembersAdapter: def slice(offset: Int, length: Int): Fu[Seq[LightUser]] = - for { + for docs <- memberRepo.coll .find(selector, $doc("user" -> true, "_id" -> false).some) @@ -63,13 +63,13 @@ final private[team] class PaginatorBuilder( .list(length) userIds = docs.flatMap(_.getAsOpt[UserId]("user")) users <- lightUserApi asyncManyFallback userIds - } yield users + yield users final private class TeamAdapterWithDate(val team: Team) extends AdapterLike[TeamMember.UserAndDate] with MembersAdapter: def slice(offset: Int, length: Int): Fu[Seq[TeamMember.UserAndDate]] = - for { + for docs <- memberRepo.coll .find(selector, $doc("user" -> true, "date" -> true, "_id" -> false).some) @@ -80,7 +80,7 @@ final private[team] class PaginatorBuilder( userIds = docs.flatMap(_.getAsOpt[UserId]("user")) dates = docs.flatMap(_.getAsOpt[Instant]("date")) users <- lightUserApi asyncManyFallback userIds - } yield users.zip(dates) map TeamMember.UserAndDate.apply + yield users.zip(dates) map TeamMember.UserAndDate.apply def declinedRequests(team: Team, page: Int): Fu[Paginator[RequestWithUser]] = Paginator( diff --git a/modules/team/src/main/Request.scala b/modules/team/src/main/Request.scala index a00d42a0037f0..afd3b89450bb2 100644 --- a/modules/team/src/main/Request.scala +++ b/modules/team/src/main/Request.scala @@ -29,7 +29,7 @@ object Request: ) case class RequestWithUser(request: Request, user: User.WithPerfs): - export request.{ user => _, * } + export request.{ user as _, * } object RequestWithUser: def combine(reqs: List[Request], users: List[User.WithPerfs]): List[RequestWithUser] = for diff --git a/modules/team/src/main/Team.scala b/modules/team/src/main/Team.scala index 9e47e8705a269..ec5c48df368a2 100644 --- a/modules/team/src/main/Team.scala +++ b/modules/team/src/main/Team.scala @@ -57,7 +57,7 @@ object Team: val maxJoinCeiling = 50 def maxJoin(u: User) = - if (u.isVerified) maxJoinCeiling * 2 + if u.isVerified then maxJoinCeiling * 2 else { 15 + daysBetween(u.createdAt, nowInstant) / 7 @@ -124,7 +124,7 @@ object Team: def nameToId(name: String) = lila.common.String.slugify(name) pipe { slug => // if most chars are not latin, go for random slug - if (slug.lengthIs > (name.length / 2)) TeamId(slug) else randomId() + if slug.lengthIs > (name.length / 2) then TeamId(slug) else randomId() } private[team] def randomId() = TeamId(ThreadLocalRandom nextString 8) diff --git a/modules/team/src/main/TeamApi.scala b/modules/team/src/main/TeamApi.scala index 96d1d80d39b73..76eed5d3dfe87 100644 --- a/modules/team/src/main/TeamApi.scala +++ b/modules/team/src/main/TeamApi.scala @@ -112,7 +112,7 @@ final class TeamApi( cached .teamIdsList(userIdOf(member)) .map(_.take(lila.team.Team.maxJoinCeiling)) flatMap { allIds => - if (viewer.exists(_ is member) || Granter.opt(_.UserModView)) fuccess(allIds) + if viewer.exists(_ is member) || Granter.opt(_.UserModView) then fuccess(allIds) else allIds.nonEmpty.so: teamRepo.filterHideMembers(allIds) flatMap { hiddenIds => @@ -331,18 +331,16 @@ final class TeamApi( } def toggleEnabled(team: Team, explain: String)(using me: Me): Funit = - if ( - Granter(_.ManageTeam) || me.is(team.createdBy) || + if Granter(_.ManageTeam) || me.is(team.createdBy) || (team.leaders(me) && !team.leaders(team.createdBy)) - ) + then logger.info(s"toggleEnabled ${team.id}: ${!team.enabled} by @${me}: $explain") - if (team.enabled) + if team.enabled then teamRepo.disable(team).void >> memberRepo.userIdsByTeam(team.id).map { _ foreach cached.invalidateTeamIds } >> requestRepo.removeByTeam(team.id).void >>- (indexer ! RemoveTeam(team.id)) - else - teamRepo.enable(team).void >>- (indexer ! InsertTeam(team)) + else teamRepo.enable(team).void >>- (indexer ! InsertTeam(team)) else teamRepo.setLeaders(team.id, team.leaders - me) // delete for ever, with members but not forums diff --git a/modules/teamSearch/src/main/Env.scala b/modules/teamSearch/src/main/Env.scala index 1221627f12af3..22669b3eb76c9 100644 --- a/modules/teamSearch/src/main/Env.scala +++ b/modules/teamSearch/src/main/Env.scala @@ -42,12 +42,12 @@ final class Env( } system.actorOf( - Props(new Actor { + Props(new Actor: import lila.team.{ InsertTeam, RemoveTeam } def receive = { case InsertTeam(team) => api.store(team).unit case RemoveTeam(id) => client.deleteById(id into Id).unit } - }), + ), name = config.actorName ) diff --git a/modules/timeline/src/main/EntryApi.scala b/modules/timeline/src/main/EntryApi.scala index e810b9ad44dec..12544f5e54b9d 100644 --- a/modules/timeline/src/main/EntryApi.scala +++ b/modules/timeline/src/main/EntryApi.scala @@ -88,11 +88,11 @@ final class EntryApi( bcs.headOption.fold(entries) { mostRecentBc => val interleaved = val oldestEntry = entries.lastOption - if (oldestEntry.fold(true)(_.date isBefore mostRecentBc.date)) + if oldestEntry.fold(true)(_.date isBefore mostRecentBc.date) then (entries ++ bcs).sortBy(-_.date.toMillis) else entries // sneak recent broadcast at first place - if (mostRecentBc.date.isAfter(nowInstant minusDays 1)) + if mostRecentBc.date.isAfter(nowInstant minusDays 1) then mostRecentBc +: interleaved.filter(mostRecentBc !=) else interleaved } diff --git a/modules/timeline/src/main/TimelinePush.scala b/modules/timeline/src/main/TimelinePush.scala index 462bd1e460eef..1a874654e46e7 100644 --- a/modules/timeline/src/main/TimelinePush.scala +++ b/modules/timeline/src/main/TimelinePush.scala @@ -21,14 +21,15 @@ final private[timeline] class TimelinePush( private val dedup = lila.memo.OnceEvery.hashCode[Atom](10 minutes) def receive = { case Propagate(data, propagations) => - if (dedup(data)) propagate(propagations) flatMap { users => - unsubApi.filterUnsub(data.channel, users) - } foreach { users => - if (users.nonEmpty) - insertEntry(users, data) >>- - lila.common.Bus.publish(ReloadTimelines(users), "lobbySocket") - lila.mon.timeline.notification.increment(users.size) - } + if dedup(data) then + propagate(propagations) flatMap { users => + unsubApi.filterUnsub(data.channel, users) + } foreach { users => + if users.nonEmpty then + insertEntry(users, data) >>- + lila.common.Bus.publish(ReloadTimelines(users), "lobbySocket") + lila.mon.timeline.notification.increment(users.size) + } } private def propagate(propagations: List[Propagation]): Fu[List[UserId]] = diff --git a/modules/timeline/src/main/UnsubApi.scala b/modules/timeline/src/main/UnsubApi.scala index 9a780febe5de5..2a36e0efe91df 100644 --- a/modules/timeline/src/main/UnsubApi.scala +++ b/modules/timeline/src/main/UnsubApi.scala @@ -11,7 +11,7 @@ final class UnsubApi(coll: Coll)(using Executor): private def select(channel: String, userId: UserId) = $id(makeId(channel, userId)) def set(channel: String, userId: UserId, v: Boolean): Funit = { - if (v) coll.insert.one(select(channel, userId)).void + if v then coll.insert.one(select(channel, userId)).void else coll.delete.one(select(channel, userId)).void } recover { case _: Exception => () diff --git a/modules/tournament/src/main/AutoPairing.scala b/modules/tournament/src/main/AutoPairing.scala index ae6c0f91f1fa2..12119277b8f51 100644 --- a/modules/tournament/src/main/AutoPairing.scala +++ b/modules/tournament/src/main/AutoPairing.scala @@ -19,7 +19,7 @@ final class AutoPairing( chess = chess .Game( variantOption = Some { - if (tour.position.isEmpty) tour.variant + if tour.position.isEmpty then tour.variant else chess.variant.FromPosition }, fen = fen diff --git a/modules/tournament/src/main/ColorHistory.scala b/modules/tournament/src/main/ColorHistory.scala index c8e76b8316254..a609d360b4087 100644 --- a/modules/tournament/src/main/ColorHistory.scala +++ b/modules/tournament/src/main/ColorHistory.scala @@ -9,10 +9,10 @@ import lila.memo.CacheApi case class ColorHistory(strike: Int, balance: Int) extends Ordered[ColorHistory]: override def compare(that: ColorHistory): Int = - if (strike < that.strike) -1 - else if (strike > that.strike) 1 - else if (balance < that.balance) -1 - else if (balance > that.balance) 1 + if strike < that.strike then -1 + else if strike > that.strike then 1 + else if balance < that.balance then -1 + else if balance > that.balance then 1 else 0 def firstGetsWhite(that: ColorHistory)(fallback: () => Boolean) = diff --git a/modules/tournament/src/main/Duel.scala b/modules/tournament/src/main/Duel.scala index cdd558dea1c97..3642a0606bab4 100644 --- a/modules/tournament/src/main/Duel.scala +++ b/modules/tournament/src/main/Duel.scala @@ -51,7 +51,7 @@ final private class DuelStore: get(tour.id) flatMap { _.find(_ has user).map(_.gameId) } def add(tour: Tournament, game: Game, p1: UsernameRating, p2: UsernameRating, ranking: Ranking): Unit = - for { + for p1 <- tbUser(p1, ranking) p2 <- tbUser(p2, ranking) tb = Duel( @@ -60,22 +60,21 @@ final private class DuelStore: p2 = p2, averageRating = IntRating((p1.rating.value + p2.rating.value) / 2) ) - } byTourId.compute( - tour.id, - (_: TourId, v: TreeSet[Duel]) => { - if (v == null) TreeSet(tb)(gameIdOrdering) - else v + tb - } - ) + do + byTourId.compute( + tour.id, + (_: TourId, v: TreeSet[Duel]) => + if v == null then TreeSet(tb)(gameIdOrdering) + else v + tb + ) def remove(game: Game): Unit = game.tournamentId foreach { tourId => byTourId.computeIfPresent( tourId, - (_: TourId, tb: TreeSet[Duel]) => { + (_: TourId, tb: TreeSet[Duel]) => val w = tb - emptyGameId(game.id) - if (w.isEmpty) null else w - } + if w.isEmpty then null else w ) } def remove(tour: Tournament): Unit = byTourId.remove(tour.id).unit diff --git a/modules/tournament/src/main/Env.scala b/modules/tournament/src/main/Env.scala index 1fd4ab5fa0e73..da23e62036988 100644 --- a/modules/tournament/src/main/Env.scala +++ b/modules/tournament/src/main/Env.scala @@ -71,8 +71,8 @@ final class Env( clearWinnersCache = winners.clearCache, clearTrophyCache = tour => { - if (tour.isShield) scheduler.scheduleOnce(10 seconds) { shieldApi.clear() } - else if (Revolution is tour) scheduler.scheduleOnce(10 seconds) { revolutionApi.clear() }.unit + if tour.isShield then scheduler.scheduleOnce(10 seconds) { shieldApi.clear() } + else if Revolution is tour then scheduler.scheduleOnce(10 seconds) { revolutionApi.clear() }.unit }.unit, indexLeaderboard = leaderboardIndexer.indexOne ) diff --git a/modules/tournament/src/main/JsonView.scala b/modules/tournament/src/main/JsonView.scala index 532ac9faa4a2d..2c2b425564398 100644 --- a/modules/tournament/src/main/JsonView.scala +++ b/modules/tournament/src/main/JsonView.scala @@ -76,9 +76,8 @@ final class JsonView( .dmap(some) stats <- statsApi(tour) shieldOwner <- full.so { shieldApi currentOwner tour } - teamsToJoinWith <- full.so(~(for { - u <- me; battle <- tour.teamBattle - } yield getMyTeamIds(u) map { teams => + teamsToJoinWith <- full.so(~(for u <- me; battle <- tour.teamBattle + yield getMyTeamIds(u) map { teams => battle.teams.intersect(teams.toSet).toList })) teamStanding <- getTeamStanding(tour) @@ -134,7 +133,7 @@ final class JsonView( def addReloadEndpoint(js: JsObject, tour: Tournament, useLilaHttp: Tournament => Boolean) = js + ("reloadEndpoint" -> JsString({ - if (useLilaHttp(tour)) reloadEndpointSetting.get() else reloadEndpointSetting.default + if useLilaHttp(tour) then reloadEndpointSetting.get() else reloadEndpointSetting.default }.replace("{id}", tour.id.value))) def clearCache(tour: Tournament): Unit = @@ -201,7 +200,7 @@ final class JsonView( ) private def fetchCurrentGameId(tour: Tournament, user: User): Fu[Option[GameId]] = - if (Uptime.startedSinceSeconds(60)) fuccess(duelStore.find(tour, user)) + if Uptime.startedSinceSeconds(60) then fuccess(duelStore.find(tour, user)) else pairingRepo.playingByTourAndUserId(tour.id, user.id) private def fetchFeaturedGame(tour: Tournament): Fu[Option[FeaturedGame]] = @@ -209,11 +208,11 @@ final class JsonView( proxyRepo game pairing.gameId flatMapz { game => cached ranking tour flatMap { ranking => playerRepo.pairByTourAndUserIds(tour.id, pairing.user1, pairing.user2) map { pairOption => - for { + for (p1, p2) <- pairOption rp1 <- RankedPlayer(ranking.ranking)(p1) rp2 <- RankedPlayer(ranking.ranking)(p2) - } yield FeaturedGame(game, rp1, rp2) + yield FeaturedGame(game, rp1, rp2) } } } diff --git a/modules/tournament/src/main/LeaderboardApi.scala b/modules/tournament/src/main/LeaderboardApi.scala index d0ebdd07fea41..5fe60cd4cf2cf 100644 --- a/modules/tournament/src/main/LeaderboardApi.scala +++ b/modules/tournament/src/main/LeaderboardApi.scala @@ -71,7 +71,7 @@ final class LeaderboardApi( Paginator( currentPage = page, maxPerPage = maxPerPage, - adapter = new AdapterLike[TourEntry] { + adapter = new AdapterLike[TourEntry]: private val selector = $doc("u" -> user.id) def nbResults: Fu[Int] = repo.coll.countSel(selector) def slice(offset: Int, length: Int): Fu[Seq[TourEntry]] = @@ -79,7 +79,7 @@ final class LeaderboardApi( .aggregateList(length, _.sec): framework => import framework.* Match(selector) -> List( - Sort(if (sortBest) Ascending("w") else Descending("d")), + Sort(if sortBest then Ascending("w") else Descending("d")), Skip(offset), Limit(length), PipelineOperator( @@ -98,8 +98,6 @@ final class LeaderboardApi( entry <- doc.asOpt[Entry] tour <- doc.getAsOpt[Tournament]("tour") yield TourEntry(tour, entry) - - } ) object LeaderboardApi: diff --git a/modules/tournament/src/main/LeaderboardIndexer.scala b/modules/tournament/src/main/LeaderboardIndexer.scala index ddf6d231993e6..4e751e7ad4b57 100644 --- a/modules/tournament/src/main/LeaderboardIndexer.scala +++ b/modules/tournament/src/main/LeaderboardIndexer.scala @@ -38,10 +38,10 @@ final private class LeaderboardIndexer( entries.nonEmpty so leaderboardRepo.coll.insert.many(entries).void private def generateTourEntries(tour: Tournament): Fu[List[Entry]] = - for { + for nbGames <- pairingRepo.countByTourIdAndUserIds(tour.id) players <- playerRepo.bestByTourWithRank(tour.id, nb = 9000, skip = 0) - } yield players.flatMap { case RankedPlayer(rank, player) => + yield players.flatMap { case RankedPlayer(rank, player) => nbGames get player.userId map { nb => Entry( id = player._id, @@ -50,7 +50,7 @@ final private class LeaderboardIndexer( nbGames = nb, score = player.score, rank = rank, - rankRatio = Ratio(if (tour.nbPlayers > 0) rank.value.toDouble / tour.nbPlayers else 0), + rankRatio = Ratio(if tour.nbPlayers > 0 then rank.value.toDouble / tour.nbPlayers else 0), freq = tour.schedule.map(_.freq), speed = tour.schedule.map(_.speed), perf = tour.perfType, diff --git a/modules/tournament/src/main/Pairing.scala b/modules/tournament/src/main/Pairing.scala index 1d1f15b24c899..5386be6eb2734 100644 --- a/modules/tournament/src/main/Pairing.scala +++ b/modules/tournament/src/main/Pairing.scala @@ -26,8 +26,8 @@ case class Pairing( def notContains(user: UserId) = !contains(user) def opponentOf(userId: UserId) = - if (userId == user1) user2.some - else if (userId == user2) user1.some + if userId == user1 then user2.some + else if userId == user2 then user1.some else none def finished = status >= chess.Status.Mate @@ -36,11 +36,11 @@ case class Pairing( def quickFinish = finished && turns.exists(20 >) def quickDraw = draw && turns.exists(20 >) def notSoQuickFinish = finished && turns.exists(14 <=) - def longGame(variant: Variant) = turns.exists(_ >= (variant match { + def longGame(variant: Variant) = turns.exists(_ >= (variant match case Standard | Chess960 | Horde => 60 case Antichess | Crazyhouse | KingOfTheHill => 40 case ThreeCheck | Atomic | RacingKings => 20 - })) + )) def wonBy(user: UserId): Boolean = winner.exists(user is _) def lostBy(user: UserId): Boolean = winner.exists(user isnt _) @@ -90,9 +90,9 @@ private[tournament] object Pairing: WithPlayers(make(gameId, tourId, player1.userId, player2.userId), player1, player2) def prepWithColor(p1: RankedPlayerWithColorHistory, p2: RankedPlayerWithColorHistory) = - if (p1.colorHistory.firstGetsWhite(p2.colorHistory)(() => ThreadLocalRandom.nextBoolean())) + if p1.colorHistory.firstGetsWhite(p2.colorHistory)(() => ThreadLocalRandom.nextBoolean()) then Prep(p1.player, p2.player) else Prep(p2.player, p1.player) def prepWithRandomColor(p1: Player, p2: Player) = - if (ThreadLocalRandom.nextBoolean()) Prep(p1, p2) else Prep(p2, p1) + if ThreadLocalRandom.nextBoolean() then Prep(p1, p2) else Prep(p2, p1) diff --git a/modules/tournament/src/main/PairingRepo.scala b/modules/tournament/src/main/PairingRepo.scala index 9d0080aa49a1e..68ea15faa0929 100644 --- a/modules/tournament/src/main/PairingRepo.scala +++ b/modules/tournament/src/main/PairingRepo.scala @@ -46,8 +46,8 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): case (acc, List(u1, u2)) => val b1 = userIds.contains(u1) val b2 = !b1 || userIds.contains(u2) - val acc1 = if (!b1 || acc.contains(u1)) acc else acc.updated(u1, u2) - if (!b2 || acc.contains(u2)) acc1 else acc1.updated(u2, u1) + val acc1 = if !b1 || acc.contains(u1) then acc else acc.updated(u1, u2) + if !b2 || acc.contains(u2) then acc1 else acc1.updated(u2, u1) case (acc, _) => acc } .takeWhile( @@ -168,7 +168,7 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): }.void def finishAndGet(g: Game): Fu[Option[Pairing]] = - if (g.aborted) coll.delete.one($id(g.id)) inject none + if g.aborted then coll.delete.one($id(g.id)) inject none else coll.findAndUpdateSimplified[Pairing]( selector = $id(g.id), @@ -181,8 +181,8 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): ) def setBerserk(pairing: Pairing, userId: UserId) = { - if (pairing.user1 == userId) "b1".some - else if (pairing.user2 == userId) "b2".some + if pairing.user1 == userId then "b1".some + else if pairing.user2 == userId then "b2".some else none } so { field => coll.update diff --git a/modules/tournament/src/main/PlayerRepo.scala b/modules/tournament/src/main/PlayerRepo.scala index 30116c1f81474..f9c78b38e1337 100644 --- a/modules/tournament/src/main/PlayerRepo.scala +++ b/modules/tournament/src/main/PlayerRepo.scala @@ -101,7 +101,7 @@ final class PlayerRepo(coll: Coll)(using Executor): .sorted.mapWithIndex: (rt, pos) => rt.updateRank(pos + 1) } map { ranked => - if (ranked.sizeIs == battle.teams.size) ranked + if ranked.sizeIs == battle.teams.size then ranked else ranked ::: battle.teams .foldLeft(List.empty[RankedTeam]) { @@ -138,7 +138,7 @@ final class PlayerRepo(coll: Coll)(using Executor): ) } .map { docO => - for { + for doc <- docO aggs <- doc.getAsOpt[List[Bdoc]]("agg") agg <- aggs.headOption @@ -147,7 +147,7 @@ final class PlayerRepo(coll: Coll)(using Executor): perf = agg.double("perf").so(math.round) score = agg.double("score").so(math.round) topPlayers <- doc.getAsOpt[List[Player]]("topPlayers") - } yield TeamBattle.TeamInfo(teamId, nbPlayers, rating.toInt, perf.toInt, score.toInt, topPlayers) + yield TeamBattle.TeamInfo(teamId, nbPlayers, rating.toInt, perf.toInt, score.toInt, topPlayers) } .dmap(_ | TeamBattle.TeamInfo(teamId, 0, 0, 0, 0, Nil)) @@ -264,7 +264,7 @@ final class PlayerRepo(coll: Coll)(using Executor): val playerIndex = new Array[TourPlayerId](all.size) val ranking = Map.newBuilder[UserId, Rank] var r = 0 - for (u <- all.values) + for u <- all.values do val both = u.asInstanceOf[BSONString].value val userId = UserId(both.drop(8)) playerIndex(r) = TourPlayerId(both.take(8)) diff --git a/modules/tournament/src/main/Revolution.scala b/modules/tournament/src/main/Revolution.scala index 6c6db9863308e..07f704518d351 100644 --- a/modules/tournament/src/main/Revolution.scala +++ b/modules/tournament/src/main/Revolution.scala @@ -33,12 +33,12 @@ final class RevolutionApi( .cursor[Bdoc](ReadPref.sec) .list(300) map { docOpt => val awards = - for { + for doc <- docOpt winner <- doc.getAsOpt[UserId]("winner") variant <- doc.getAsOpt[Variant.Id]("variant") map Variant.orDefault id <- doc.getAsOpt[TourId]("_id") - } yield Award( + yield Award( owner = winner, variant = variant, tourId = id diff --git a/modules/tournament/src/main/Schedule.scala b/modules/tournament/src/main/Schedule.scala index cd8e7c3961021..4e047ccc523b2 100644 --- a/modules/tournament/src/main/Schedule.scala +++ b/modules/tournament/src/main/Schedule.scala @@ -25,7 +25,7 @@ case class Schedule( import Schedule.Freq.* import Schedule.Speed.* import lila.i18n.I18nKeys.tourname.* - if (variant.standard && position.isEmpty) + if variant.standard && position.isEmpty then (conditions.minRating, conditions.maxRating) match case (None, None) => (freq, speed) match @@ -75,11 +75,11 @@ case class Schedule( case (Some(_), _) => eliteX.txt(speed.trans) case (_, Some(max)) if full => s"≤${max.rating} ${xArena.txt(speed.trans)}" case (_, Some(max)) => s"≤${max.rating} ${speed.trans}" - else if (variant.standard) + else if variant.standard then val n = position.flatMap(Thematic.byFen).fold(speed.trans) { pos => s"${pos.family.name} ${speed.trans}" } - if (full) xArena.txt(n) else n + if full then xArena.txt(n) else n else freq match case Hourly if full => hourlyXArena.txt(variant.name) @@ -98,7 +98,7 @@ case class Schedule( case Shield => xShield.txt(variant.name) case _ => val n = s"${freq.name} ${variant.name}" - if (full) xArena.txt(n) else n + if full then xArena.txt(n) else n def day = at.withTimeAtStartOfDay @@ -208,12 +208,12 @@ object Schedule: case _ => false def fromClock(clock: chess.Clock.Config) = val time = clock.estimateTotalSeconds - if (time < 30) UltraBullet - else if (time < 60) HyperBullet - else if (time < 120) Bullet - else if (time < 180) HippoBullet - else if (time < 480) Blitz - else if (time < 1500) Rapid + if time < 30 then UltraBullet + else if time < 60 then HyperBullet + else if time < 120 then Bullet + else if time < 180 then HippoBullet + else if time < 480 then Blitz + else if time < 1500 then Rapid else Classical def toPerfType(speed: Speed) = speed match diff --git a/modules/tournament/src/main/StartedOrganizer.scala b/modules/tournament/src/main/StartedOrganizer.scala index 997feda241989..8dd51d0956406 100644 --- a/modules/tournament/src/main/StartedOrganizer.scala +++ b/modules/tournament/src/main/StartedOrganizer.scala @@ -24,8 +24,8 @@ final private class StartedOrganizer( tournamentRepo .startedCursorWithNbPlayersGte { - if (doAllTournaments) none // every 15s, do all tournaments - else if (runCounter % 2 == 0) 50.some // every 2s, do all decent tournaments + if doAllTournaments then none // every 15s, do all tournaments + else if runCounter % 2 == 0 then 50.some // every 2s, do all decent tournaments else 1000.some // always do massive tournaments } .documentSource() @@ -38,7 +38,7 @@ final private class StartedOrganizer( .toMat(LilaStream.sinkCount)(Keep.right) .run() .addEffect { nb => - if (doAllTournaments) lila.mon.tournament.started.update(nb).unit + if doAllTournaments then lila.mon.tournament.started.update(nb).unit runCounter = runCounter + 1 } .monSuccess(_.tournament.startedOrganizer.tick) @@ -46,12 +46,12 @@ final private class StartedOrganizer( } private def processTour(tour: Tournament): Funit = - if (tour.secondsToFinish <= 0) api finish tour - else if (api.killSchedule contains tour.id) + if tour.secondsToFinish <= 0 then api finish tour + else if api.killSchedule contains tour.id then api.killSchedule remove tour.id api finish tour - else if (tour.nbPlayers < 2) funit - else if (tour.nbPlayers < 30) + else if tour.nbPlayers < 2 then funit + else if tour.nbPlayers < 30 then playerRepo nbActivePlayers tour.id flatMap { nb => (nb >= 2) so startPairing(tour, nb.some) } diff --git a/modules/tournament/src/main/TeamBattle.scala b/modules/tournament/src/main/TeamBattle.scala index 635cc98c1733b..35dfeffa8ee6f 100644 --- a/modules/tournament/src/main/TeamBattle.scala +++ b/modules/tournament/src/main/TeamBattle.scala @@ -35,8 +35,8 @@ object TeamBattle: this(rank, teamId, leaders, leaders.foldLeft(0)(_ + _.score)) def updateRank(newRank: Int) = new RankedTeam(newRank, teamId, leaders, score) override def compare(that: RankedTeam) = - if (this.score > that.score) -1 - else if (this.score < that.score) 1 + if this.score > that.score then -1 + else if this.score < that.score then 1 else that.magicScore - this.magicScore case class TeamLeader(userId: UserId, magicScore: Int): @@ -75,6 +75,6 @@ object TeamBattle: def potentialTeamIds: Set[TeamId] = val lines = teams.linesIterator.toList val dirtyIds = - if (lines.sizeIs > 1) lines.map(_.takeWhile(' ' !=)) + if lines.sizeIs > 1 then lines.map(_.takeWhile(' ' !=)) else lines.headOption.so(_.split(',').toList) dirtyIds.map(_.trim).filter(_.nonEmpty).map(TeamId(_)).toSet diff --git a/modules/tournament/src/main/Tournament.scala b/modules/tournament/src/main/Tournament.scala index a4dd32a2a504d..49cac532dc9d6 100644 --- a/modules/tournament/src/main/Tournament.scala +++ b/modules/tournament/src/main/Tournament.scala @@ -48,10 +48,10 @@ case class Tournament( def isTeamBattle = teamBattle.isDefined def name(full: Boolean = true)(using Lang): String = - if (isMarathon || isUnique) name - else if (isTeamBattle && full) lila.i18n.I18nKeys.tourname.xTeamBattle.txt(name) - else if (isTeamBattle) name - else schedule.fold(if (full) s"$name Arena" else name)(_.name(full)) + if isMarathon || isUnique then name + else if isTeamBattle && full then lila.i18n.I18nKeys.tourname.xTeamBattle.txt(name) + else if isTeamBattle then name + else schedule.fold(if full then s"$name Arena" else name)(_.name(full)) def isMarathon = schedule.map(_.freq) exists { @@ -108,8 +108,8 @@ case class Tournament( def perfType: PerfType = PerfType(variant, speed) def durationString = - if (minutes < 60) s"${minutes}m" - else s"${minutes / 60}h" + (if (minutes % 60 != 0) s" ${minutes % 60}m" else "") + if minutes < 60 then s"${minutes}m" + else s"${minutes / 60}h" + (if minutes % 60 != 0 then s" ${minutes % 60}m" else "") def berserkable = !noBerserk && clock.berserkable def streakable = !noStreak @@ -133,7 +133,7 @@ case class Tournament( def nonLichessCreatedBy = (createdBy != User.lichessId) option createdBy - def ratingVariant = if (variant.fromPosition) chess.variant.Standard else variant + def ratingVariant = if variant.fromPosition then chess.variant.Standard else variant def startingPosition = position flatMap Thematic.byFen diff --git a/modules/tournament/src/main/TournamentApi.scala b/modules/tournament/src/main/TournamentApi.scala index 880c02d27641e..08f655f4b0e7e 100644 --- a/modules/tournament/src/main/TournamentApi.scala +++ b/modules/tournament/src/main/TournamentApi.scala @@ -232,8 +232,8 @@ final class TournamentApi( private[tournament] val killSchedule = scala.collection.mutable.Set.empty[TourId] def kill(tour: Tournament): Funit = - if (tour.isStarted) fuccess(killSchedule add tour.id).void - else if (tour.isCreated) destroy(tour) + if tour.isStarted then fuccess(killSchedule add tour.id).void + else if tour.isCreated then destroy(tour) else funit private def awardTrophies(tour: Tournament): Funit = @@ -276,7 +276,7 @@ final class TournamentApi( playerRepo.find(tour.id, me) flatMap { prevPlayer => import Tournament.JoinResult val fuResult: Fu[JoinResult] = - if (me.marks.prizeban && tour.looksLikePrize) fuccess(JoinResult.PrizeBanned) + if me.marks.prizeban && tour.looksLikePrize then fuccess(JoinResult.PrizeBanned) else if prevPlayer.nonEmpty || tour.password.forall(p => // plain text access code MessageDigest.isEqual(p.getBytes(UTF_8), (~data.password).getBytes(UTF_8)) || @@ -289,8 +289,8 @@ final class TournamentApi( ) then getVerdicts(tour, prevPlayer.isDefined) flatMap { verdicts => - if (!verdicts.accepted) fuccess(JoinResult.Verdicts) - else if (!pause.canJoin(me, tour)) fuccess(JoinResult.Paused) + if !verdicts.accepted then fuccess(JoinResult.Verdicts) + else if !pause.canJoin(me, tour) then fuccess(JoinResult.Paused) else def proceedWithTeam(team: Option[TeamId]): Fu[JoinResult] = for user <- perfsRepo.withPerf(me.value, tour.perfType) @@ -369,7 +369,7 @@ final class TournamentApi( then cached.ranking(tour).map { _.ranking get userId exists (_ < 7) } else fuccess(isStalling) yield - if (pausable) pause.add(userId) + if pausable then pause.add(userId) socket.reload(tour.id) publish() case _ => funit @@ -442,15 +442,16 @@ final class TournamentApi( private def performanceOf(g: Game, userId: UserId): Option[IntRating] = for opponent <- g.opponentByUserId(userId) opponentRating <- opponent.rating - multiplier = g.winnerUserId.so(winner => if (winner == userId) 1 else -1) + multiplier = g.winnerUserId.so(winner => if winner == userId then 1 else -1) yield opponentRating + 500 * multiplier private def withdrawNonMover(game: Game): Unit = - if (game.status == chess.Status.NoStart) for - tourId <- game.tournamentId - player <- game.playerWhoDidNotMove - userId <- player.userId - yield withdraw(tourId, userId, isPause = false, isStalling = false) + if game.status == chess.Status.NoStart then + for + tourId <- game.tournamentId + player <- game.playerWhoDidNotMove + userId <- player.userId + yield withdraw(tourId, userId, isPause = false, isStalling = false) def pausePlaybanned(userId: UserId) = tournamentRepo.withdrawableIds(userId, reason = "pausePlaybanned") flatMap { @@ -464,7 +465,7 @@ final class TournamentApi( _.map { tourId => Parallel(tourId, "kickFromTeam")(tournamentRepo.byId) { tour => val fu = - if (tour.isCreated) playerRepo.remove(tour.id, userId) + if tour.isCreated then playerRepo.remove(tour.id, userId) else playerRepo.withdraw(tour.id, userId) fu >> updateNbPlayers(tourId) >>- socket.reload(tourId) } @@ -474,8 +475,7 @@ final class TournamentApi( // withdraws the player and forfeits all pairings in ongoing tournaments private[tournament] def ejectLameFromEnterable(tourId: TourId, userId: UserId): Funit = Parallel(tourId, "ejectLameFromEnterable")(cached.tourCache.enterable) { tour => - if (tour.isCreated) - playerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) + if tour.isCreated then playerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) else playerRepo.remove(tourId, userId) >> { tour.isStarted so { @@ -710,12 +710,11 @@ final class TournamentApi( (Tournament.PastAndNext.apply).tupled def toggleFeaturing(tourId: TourId, v: Boolean): Funit = - if (v) + if v then tournamentRepo.byId(tourId) flatMapz { tour => tournamentRepo.setSchedule(tour.id, Schedule.uniqueFor(tour).some) } - else - tournamentRepo.setSchedule(tourId, none) + else tournamentRepo.setSchedule(tourId, none) private def playerPovs(tour: Tournament, userId: UserId, nb: Int): Fu[List[LightPov]] = pairingRepo.recentIdsByTourAndUserId(tour.id, userId, nb) flatMap @@ -754,7 +753,7 @@ final class TournamentApi( private def publishNow(tourId: TourId) = tournamentTop(tourId) map { top => val lastHash: Int = ~lastPublished.getIfPresent(tourId) - if (lastHash != top.hashCode) + if lastHash != top.hashCode then Bus.publish( lila.hub.actorApi.round.TourStanding(tourId, JsonView.top(top, lightUserApi.sync)), "tourStanding" @@ -765,7 +764,7 @@ final class TournamentApi( private val throttler = new lila.hub.EarlyMultiThrottler[TourId](logger) def apply(tour: Tournament): Unit = - if (!tour.isTeamBattle) throttler(tour.id, 15.seconds) { publishNow(tour.id) } + if !tour.isTeamBattle then throttler(tour.id, 15.seconds) { publishNow(tour.id) } private object TournamentApi: diff --git a/modules/tournament/src/main/TournamentCache.scala b/modules/tournament/src/main/TournamentCache.scala index 5aa3f2a3beeda..83e9f390f368e 100644 --- a/modules/tournament/src/main/TournamentCache.scala +++ b/modules/tournament/src/main/TournamentCache.scala @@ -41,7 +41,7 @@ final class TournamentCache( .buildAsyncFuture(_ => tournamentRepo.onHomepage) def ranking(tour: Tournament): Fu[FullRanking] = - if (tour.isFinished) finishedRanking get tour.id + if tour.isFinished then finishedRanking get tour.id else ongoingRanking get tour.id // only applies to ongoing tournaments diff --git a/modules/tournament/src/main/TournamentForm.scala b/modules/tournament/src/main/TournamentForm.scala index bcb622dff9050..248adef672364 100644 --- a/modules/tournament/src/main/TournamentForm.scala +++ b/modules/tournament/src/main/TournamentForm.scala @@ -157,7 +157,7 @@ private[tournament] case class TournamentSetup( def validClock = (clockTime + clockIncrement.value) > 0 def realMode = - if (realPosition.isDefined) Mode.Casual + if realPosition.isDefined then Mode.Casual else Mode(rated.orElse(mode.map(Mode.Rated.id ===)) | true) def realVariant = variant.flatMap(TournamentForm.guessVariant) | chess.variant.Standard @@ -187,18 +187,18 @@ private[tournament] case class TournamentSetup( // update all fields and use default values for missing fields // meant for HTML form updates def updateAll(old: Tournament): Tournament = - val newVariant = if (old.isCreated && variant.isDefined) realVariant else old.variant + val newVariant = if old.isCreated && variant.isDefined then realVariant else old.variant old .copy( name = name | old.name, - clock = if (old.isCreated) clockConfig else old.clock, + clock = if old.isCreated then clockConfig else old.clock, minutes = minutes, mode = realMode, variant = newVariant, startsAt = startDate | old.startsAt, password = password, position = newVariant.standard so { - if (old.isCreated || old.position.isDefined) realPosition + if old.isCreated || old.position.isDefined then realPosition else old.position }, noBerserk = !isBerserkable, @@ -211,18 +211,18 @@ private[tournament] case class TournamentSetup( // update only fields that are specified // meant for API updates def updatePresent(old: Tournament): Tournament = - val newVariant = if (old.isCreated) realVariant else old.variant + val newVariant = if old.isCreated then realVariant else old.variant old .copy( name = name | old.name, - clock = if (old.isCreated) clockConfig else old.clock, + clock = if old.isCreated then clockConfig else old.clock, minutes = minutes, - mode = if (rated.isDefined) realMode else old.mode, + mode = if rated.isDefined then realMode else old.mode, variant = newVariant, startsAt = startDate | old.startsAt, password = password.fold(old.password)(_.some.filter(_.nonEmpty)), position = newVariant.standard so { - if (position.isDefined && (old.isCreated || old.position.isDefined)) realPosition + if position.isDefined && (old.isCreated || old.position.isDefined) then realPosition else old.position }, noBerserk = berserkable.fold(old.noBerserk)(!_) || timeControlPreventsBerserk, diff --git a/modules/tournament/src/main/TournamentNotify.scala b/modules/tournament/src/main/TournamentNotify.scala index 38266cc2189fc..530cf3a36c35c 100644 --- a/modules/tournament/src/main/TournamentNotify.scala +++ b/modules/tournament/src/main/TournamentNotify.scala @@ -19,7 +19,7 @@ final private class TournamentNotify(repo: TournamentRepo, cached: TournamentCac lila.mon.tournament.notifier.tournaments.increment() doneMemo put tour.id cached ranking tour map { ranking => - if (ranking.ranking.nonEmpty) + if ranking.ranking.nonEmpty then Bus .publish( TourSoon( diff --git a/modules/tournament/src/main/TournamentRepo.scala b/modules/tournament/src/main/TournamentRepo.scala index b248b01d78581..ffac944cc4f9b 100644 --- a/modules/tournament/src/main/TournamentRepo.scala +++ b/modules/tournament/src/main/TournamentRepo.scala @@ -20,7 +20,7 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu private def forTeamsSelect(ids: Seq[TeamId]) = $doc("forTeams" $in ids) private def sinceSelect(date: Instant) = $doc("startsAt" $gt date) private def variantSelect(variant: Variant) = - if (variant.standard) $doc("variant" $exists false) + if variant.standard then $doc("variant" $exists false) else $doc("variant" -> variant.id) private def nbPlayersSelect(nb: Int) = $doc("nbPlayers" $gte nb) private val nonEmptySelect = nbPlayersSelect(1) @@ -236,7 +236,7 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu case Weekly | Weekend => 3 * 45 case Daily => 1 * 30 case _ => 20 - if (tour.variant.exotic && schedule.freq != Unique) base / 3 else base + if tour.variant.exotic && schedule.freq != Unique then base / 3 else base } } @@ -281,11 +281,10 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu case ((tours, skip), (tour, sched)) => ( tour :: tours, - sched.freq match { + sched.freq match case Schedule.Freq.Daily => Schedule.Freq.Eastern.some case Schedule.Freq.Eastern => Schedule.Freq.Daily.some case _ => skip - } ) }._1 .reverse diff --git a/modules/tournament/src/main/TournamentScheduler.scala b/modules/tournament/src/main/TournamentScheduler.scala index f4572aff8f6c7..675e766fae5cc 100644 --- a/modules/tournament/src/main/TournamentScheduler.scala +++ b/modules/tournament/src/main/TournamentScheduler.scala @@ -172,7 +172,7 @@ Thank you all, you rock!""", at(day, 19) map { date => Schedule( Monthly, - if (variant == Chess960 || variant == Crazyhouse) Blitz else SuperBlitz, + if variant == Chess960 || variant == Crazyhouse then Blitz else SuperBlitz, variant, none, date @@ -243,7 +243,7 @@ Thank you all, you rock!""", at(day, 19) map { date => Schedule( Weekly, - if (variant == Chess960 || variant == Crazyhouse) Blitz else SuperBlitz, + if variant == Chess960 || variant == Crazyhouse then Blitz else SuperBlitz, variant, none, date pipe orNextWeek @@ -389,7 +389,7 @@ Thank you all, you rock!""", allowList = none ) val finalWhen = when plusHours hourDelay - if (speed == Bullet) + if speed == Bullet then List( Schedule(Hourly, speed, Standard, none, finalWhen, conditions).plan, Schedule(Hourly, speed, Standard, none, finalWhen plusMinutes 30, conditions) @@ -480,7 +480,7 @@ Thank you all, you rock!""", private def pruneConflicts(scheds: List[Tournament], newTourns: List[Tournament]) = newTourns .foldLeft(List[Tournament]()): (tourns, t) => - if (overlaps(t, tourns) || overlaps(t, scheds)) tourns + if overlaps(t, tourns) || overlaps(t, scheds) then tourns else t :: tourns .reverse diff --git a/modules/tournament/src/main/TournamentShield.scala b/modules/tournament/src/main/TournamentShield.scala index 85c2adc0636c2..d9e6f1fa5b5f1 100644 --- a/modules/tournament/src/main/TournamentShield.scala +++ b/modules/tournament/src/main/TournamentShield.scala @@ -40,7 +40,7 @@ final class TournamentShieldApi( private[tournament] def clearAfterMarking(userId: UserId): Funit = cache.getUnit map { hist => import cats.syntax.all.* - if (hist.value.exists(_._2.exists(_.owner == userId))) clear() + if hist.value.exists(_._2.exists(_.owner == userId)) then clear() } private val cache = cacheApi.unit[History]: diff --git a/modules/tournament/src/main/TournamentStandingApi.scala b/modules/tournament/src/main/TournamentStandingApi.scala index 530c63935033e..3e26222e43de1 100644 --- a/modules/tournament/src/main/TournamentStandingApi.scala +++ b/modules/tournament/src/main/TournamentStandingApi.scala @@ -44,8 +44,8 @@ final class TournamentStandingApi( def apply(tour: Tournament, forPage: Int, withScores: Boolean): Fu[JsObject] = val page = forPage atMost Math.ceil(tour.nbPlayers.toDouble / perPage).toInt atLeast 1 - if (page == 1) first get tour.id - else if (page > 50 && tour.isCreated) createdCache.get(tour.id -> page) + if page == 1 then first get tour.id + else if page > 50 && tour.isCreated then createdCache.get(tour.id -> page) else compute(tour, page, withScores) private val first = cacheApi[TourId, JsObject](64, "tournament.page.first") { @@ -74,9 +74,9 @@ final class TournamentStandingApi( } private def compute(tour: Tournament, page: Int, withScores: Boolean): Fu[JsObject] = - for { + for rankedPlayers <- - if (page < 10) playerRepo.bestByTourWithRankByPage(tour.id, perPage, page) + if page < 10 then playerRepo.bestByTourWithRankByPage(tour.id, perPage, page) else playerIdsOnPage(tour, page) flatMap { playerRepo.byPlayerIdsOnPage(_, page) } sheets <- rankedPlayers .map { p => @@ -87,7 +87,7 @@ final class TournamentStandingApi( players <- rankedPlayers .map(JsonView.playerJson(lightUserApi, sheets, streakable = tour.streakable, withScores = withScores)) .parallel - } yield Json.obj( + yield Json.obj( "page" -> page, "players" -> players ) diff --git a/modules/tournament/src/main/TournamentStats.scala b/modules/tournament/src/main/TournamentStats.scala index 6bcf289845291..268e727d17b59 100644 --- a/modules/tournament/src/main/TournamentStats.scala +++ b/modules/tournament/src/main/TournamentStats.scala @@ -24,10 +24,10 @@ final class TournamentStatsApi( } private def fetch(tournamentId: TourId): Fu[TournamentStats] = - for { + for rating <- playerRepo.averageRating(tournamentId) rawStats <- pairingRepo.rawStats(tournamentId) - } yield TournamentStats.readAggregation(rating)(rawStats) + yield TournamentStats.readAggregation(rating)(rawStats) case class TournamentStats( games: Int, diff --git a/modules/tournament/src/main/WaitingUsers.scala b/modules/tournament/src/main/WaitingUsers.scala index 0107277b956f4..31b032646ad2c 100644 --- a/modules/tournament/src/main/WaitingUsers.scala +++ b/modules/tournament/src/main/WaitingUsers.scala @@ -19,8 +19,8 @@ private case class WaitingUsers( // 5+0 -> 36 -> 36 // 10+0 -> 66 -> 50 private val waitSeconds: Int = - if (clock.estimateTotalSeconds < 30) 8 - else if (clock.estimateTotalSeconds < 60) 10 + if clock.estimateTotalSeconds < 30 then 8 + else if clock.estimateTotalSeconds < 60 then 10 else (clock.estimateTotalSeconds / 10 + 6) atMost 50 atLeast 15 lazy val all = hash.keySet @@ -30,7 +30,7 @@ private case class WaitingUsers( // skips the most recent user if odd def evenNumber: Set[UserId] = - if (isOdd) all - hash.maxBy(_._2.toMillis)._1 + if isOdd then all - hash.maxBy(_._2.toMillis)._1 else all lazy val haveWaitedEnough: Boolean = @@ -56,7 +56,7 @@ private case class WaitingUsers( def addApiUser(userId: UserId) = val memo = apiUsers | new ExpireSetMemo[UserId](70 seconds) memo put userId - if (apiUsers.isEmpty) copy(apiUsers = memo.some) else this + if apiUsers.isEmpty then copy(apiUsers = memo.some) else this def removePairedUsers(us: Set[UserId]) = apiUsers.foreach(_ removeAll us) @@ -75,11 +75,10 @@ final private class WaitingUsersApi: def registerWaitingUsers(tourId: TourId, users: Set[UserId]) = store.computeIfPresent( tourId, - (_: TourId, cur: WaitingUsers.WithNext) => { + (_: TourId, cur: WaitingUsers.WithNext) => val newWaiting = cur.waiting.update(users) cur.next.foreach(_ success newWaiting) WaitingUsers.WithNext(newWaiting, none) - } ) def registerPairedUsers(tourId: TourId, users: Set[UserId]) = diff --git a/modules/tournament/src/main/WinnersApi.scala b/modules/tournament/src/main/WinnersApi.scala index 431b6422397af..0bdbac6535669 100644 --- a/modules/tournament/src/main/WinnersApi.scala +++ b/modules/tournament/src/main/WinnersApi.scala @@ -87,14 +87,14 @@ final class WinnersApi( tours.find(_.variant == variant).flatMap(_.winner) private def fetchAll: Fu[AllWinners] = - for { + for yearlies <- fetchLastFreq(Freq.Yearly, nowInstant.minusYears(1)) monthlies <- fetchLastFreq(Freq.Monthly, nowInstant.minusMonths(2)) weeklies <- fetchLastFreq(Freq.Weekly, nowInstant.minusWeeks(2)) dailies <- fetchLastFreq(Freq.Daily, nowInstant.minusDays(2)) elites <- fetchLastFreq(Freq.Weekend, nowInstant.minusWeeks(3)) marathons <- fetchLastFreq(Freq.Marathon, nowInstant.minusMonths(13)) - } yield + yield def standardFreqWinners(speed: Speed): FreqWinners = FreqWinners( yearly = firstStandardWinner(yearlies, speed), @@ -132,11 +132,11 @@ final class WinnersApi( // because we read on secondaries, delay cache clear def clearCache(tour: Tournament): Unit = - if (tour.schedule.exists(_.freq.isDailyOrBetter)) + if tour.schedule.exists(_.freq.isDailyOrBetter) then scheduler.scheduleOnce(5.seconds) { allCache.invalidate {}.unit }.unit private[tournament] def clearAfterMarking(userId: UserId): Funit = all map { winners => - if (winners.userIds contains userId) allCache.invalidate {}.unit + if winners.userIds contains userId then allCache.invalidate {}.unit } object WinnersApi: diff --git a/modules/tournament/src/main/arena/AntmaPairing.scala b/modules/tournament/src/main/arena/AntmaPairing.scala index a104eafab4a2e..0433e9941b596 100644 --- a/modules/tournament/src/main/arena/AntmaPairing.scala +++ b/modules/tournament/src/main/arena/AntmaPairing.scala @@ -21,10 +21,9 @@ private object AntmaPairing: lastOpponents.hash.get(u2).contains(u1) def pairScore(a: RPlayer, b: RPlayer): Option[Int] = - if ( - justPlayedTogether(a.player.userId, b.player.userId) || + if justPlayedTogether(a.player.userId, b.player.userId) || !a.colorHistory.couldPlay(b.colorHistory, maxStrike) - ) None + then None else Some { Math.abs(a.rank.value - b.rank.value) * rankFactor(a, b) + @@ -39,14 +38,14 @@ private object AntmaPairing: Chronometer.syncMon(_.tournament.pairing.wmmatching) { WMMatching( players.toArray, - if (data.tour.isTeamBattle) battleScore - else if (data.onlyTwoActivePlayers) duelScore + if data.tour.isTeamBattle then battleScore + else if data.onlyTwoActivePlayers then duelScore else pairScore ).fold( - err => { + err => logger.error("WMMatching", err) Nil - }, + , _ map { case (a, b) => Pairing.prepWithColor(a, b) } diff --git a/modules/tournament/src/main/arena/ArenaSheet.scala b/modules/tournament/src/main/arena/ArenaSheet.scala index 9657f245b238d..6fbc0fb709453 100644 --- a/modules/tournament/src/main/arena/ArenaSheet.scala +++ b/modules/tournament/src/main/arena/ArenaSheet.scala @@ -13,24 +13,23 @@ case class Sheet(scores: List[Sheet.Score], total: Int, variant: Variant): def addResult(userId: UserId, p: Pairing, version: Version, streakable: Streakable): Sheet = val berserk = - if (p berserkOf userId) - if p.notSoQuickFinish then Berserk.Valid else Berserk.Invalid + if p berserkOf userId then if p.notSoQuickFinish then Berserk.Valid else Berserk.Invalid else Berserk.No val score = p.winner match case None if p.quickDraw => Score(Result.DQ, Flag.Normal, berserk) case None => Score( Result.Draw, - if (streakable && isOnFire) Flag.Double - else if (version != Version.V1 && !p.longGame(variant) && isDrawStreak(scores)) Flag.Null + if streakable && isOnFire then Flag.Double + else if version != Version.V1 && !p.longGame(variant) && isDrawStreak(scores) then Flag.Null else Flag.Normal, berserk ) case Some(w) if userId == w => Score( Result.Win, - if (!streakable) Flag.Normal - else if (isOnFire) Flag.Double + if !streakable then Flag.Normal + else if isOnFire then Flag.Double else Flag.StreakStarter, berserk ) diff --git a/modules/tournament/src/main/arena/PairingSystem.scala b/modules/tournament/src/main/arena/PairingSystem.scala index 8bf6c3c1ef008..2318e7c14d67b 100644 --- a/modules/tournament/src/main/arena/PairingSystem.scala +++ b/modules/tournament/src/main/arena/PairingSystem.scala @@ -21,15 +21,15 @@ final private[tournament] class PairingSystem( ranking: FullRanking, smallTourNbActivePlayers: Option[Int] ): Fu[List[Pairing.WithPlayers]] = { - for { + for lastOpponents <- - if (tour.isRecentlyStarted) fuccess(Pairing.LastOpponents(Map.empty)) + if tour.isRecentlyStarted then fuccess(Pairing.LastOpponents(Map.empty)) else pairingRepo.lastOpponents(tour.id, users.all, Math.min(300, users.size * 4)) onlyTwoActivePlayers = smallTourNbActivePlayers.exists(2 ==) data = Data(tour, lastOpponents, ranking.ranking, onlyTwoActivePlayers) preps <- evenOrAll(data, users) pairings <- prepsToPairings(tour, preps) - } yield pairings + yield pairings }.chronometer .logIfSlow(500, pairingLogger) { pairings => s"createPairings ${tournamentUrl(tour.id)} ${pairings.size} pairings" @@ -46,13 +46,13 @@ final private[tournament] class PairingSystem( private def makePreps(data: Data, users: Set[UserId]): Fu[List[Pairing.Prep]] = { import data.* - if (users.sizeIs < 2) fuccess(Nil) + if users.sizeIs < 2 then fuccess(Nil) else playerRepo.rankedByTourAndUserIds(tour.id, users, ranking) map { idles => lazy val nbIdles = idles.size - if (nbIdles < 2) Nil - else if (data.tour.isRecentlyStarted && !data.tour.isTeamBattle) initialPairings(idles) - else if (nbIdles <= maxGroupSize) bestPairings(data, idles) + if nbIdles < 2 then Nil + else if data.tour.isRecentlyStarted && !data.tour.isTeamBattle then initialPairings(idles) + else if nbIdles <= maxGroupSize then bestPairings(data, idles) else // make sure groupSize is even with / 4 * 2 val groupSize = (nbIdles / 4 * 2) atMost maxGroupSize @@ -116,7 +116,6 @@ private object PairingSystem: players: List[RankedPlayerWithColorHistory] ): (RankedPlayerWithColorHistory, RankedPlayerWithColorHistory) => Int = val maxRank = players.maxBy(_.rank.value).rank - (a, b) => { + (a, b) => val rank = a.rank atMost b.rank 300 + 1700 * (maxRank - rank).value / maxRank.value - } diff --git a/modules/tournament/src/main/crud/CrudApi.scala b/modules/tournament/src/main/crud/CrudApi.scala index c09c9769e868a..d038bb3e69861 100644 --- a/modules/tournament/src/main/crud/CrudApi.scala +++ b/modules/tournament/src/main/crud/CrudApi.scala @@ -93,7 +93,7 @@ final class CrudApi(tournamentRepo: TournamentRepo, crudForm: CrudForm): clock = clock, minutes = minutes, variant = realVariant, - mode = if (data.rated) Mode.Rated else Mode.Casual, + mode = if data.rated then Mode.Rated else Mode.Casual, startsAt = date.instant, schedule = Schedule( freq = Schedule.Freq.Unique, diff --git a/modules/tournament/src/main/model.scala b/modules/tournament/src/main/model.scala index e28bc895a5302..3f2d0ca4d7c2a 100644 --- a/modules/tournament/src/main/model.scala +++ b/modules/tournament/src/main/model.scala @@ -61,10 +61,10 @@ case class RankedPairing(pairing: Pairing, rank1: Rank, rank2: Rank): object RankedPairing: def apply(ranking: Ranking)(pairing: Pairing): Option[RankedPairing] = - for { + for r1 <- ranking get pairing.user1 r2 <- ranking get pairing.user2 - } yield RankedPairing(pairing, r1 + 1, r2 + 1) + yield RankedPairing(pairing, r1 + 1, r2 + 1) case class RankedPlayer(rank: Rank, player: Player): diff --git a/modules/tournament/src/test/ColorHistoryTest.scala b/modules/tournament/src/test/ColorHistoryTest.scala index cd77f86ee9c23..f8b86d5456bf0 100644 --- a/modules/tournament/src/test/ColorHistoryTest.scala +++ b/modules/tournament/src/test/ColorHistoryTest.scala @@ -1,14 +1,12 @@ package lila.tournament -object ColorHistoryTest { - def apply(s: String): ColorHistory = { +object ColorHistoryTest: + def apply(s: String): ColorHistory = s.foldLeft(ColorHistory(0, 0)) { (acc, c) => - c match { + c match case 'W' => acc.inc(chess.White) case 'B' => acc.inc(chess.Black) - } } - } def toTuple2(history: ColorHistory): (Int, Int) = (history.strike, history.balance) def unpack(s: String): (Int, Int) = toTuple2(apply(s)) def couldPlay(s1: String, s2: String, maxStreak: Int): Boolean = apply(s1).couldPlay(apply(s2), maxStreak) @@ -17,9 +15,8 @@ object ColorHistoryTest { apply(s1).firstGetsWhite(apply(s2)) { () => true } -} -class ColorHistoryTest extends munit.FunSuite { +class ColorHistoryTest extends munit.FunSuite: import ColorHistoryTest.{ apply, couldPlay, firstGetsWhite, sameColors, unpack } test("hand tests") { assertEquals(unpack("WWW"), ((3, 3))) @@ -49,4 +46,3 @@ class ColorHistoryTest extends munit.FunSuite { assertEquals(apply(""), apply("")) assertEquals(apply("WBW"), apply("W")) } -} diff --git a/modules/tutor/src/main/TutorBsonHandlers.scala b/modules/tutor/src/main/TutorBsonHandlers.scala index eeb0a95798afe..7c1077dc7ab98 100644 --- a/modules/tutor/src/main/TutorBsonHandlers.scala +++ b/modules/tutor/src/main/TutorBsonHandlers.scala @@ -25,12 +25,12 @@ private object TutorBsonHandlers: quickHandler[Option[ValueCount[V]]]( { case arr: BSONArray => - for { v <- arr.getAsOpt[V](0); c <- arr.getAsOpt[Int](1) } yield ValueCount(v, c) + for v <- arr.getAsOpt[V](0); c <- arr.getAsOpt[Int](1) yield ValueCount(v, c) case _ => None }, vcOpt => { - for { vc <- vcOpt; v <- handler.writeOpt(vc.value) } yield $arr(v, BSONInteger(vc.count)) + for vc <- vcOpt; v <- handler.writeOpt(vc.value) yield $arr(v, BSONInteger(vc.count)) } getOrElse BSONNull ) diff --git a/modules/tutor/src/main/TutorCompare.scala b/modules/tutor/src/main/TutorCompare.scala index dd89a107359fc..1e4d4ac190cad 100644 --- a/modules/tutor/src/main/TutorCompare.scala +++ b/modules/tutor/src/main/TutorCompare.scala @@ -17,10 +17,10 @@ case class TutorCompare[D, V]( lazy val dimensionComparisons: List[AnyComparison] = val myPoints: List[(D, ValueCount[V])] = points.collect { case (dim, TutorBothValueOptions(Some(mine), _)) => dim -> mine } - for { + for (dim1, met1) <- myPoints.filter(_._2 relevantTo totalCountMine) avg = number.mean(myPoints.filter(_._1 != dim1).map(_._2)) - } yield Comparison(dimensionType, dim1, metric, met1, DimAvg(avg), color) + yield Comparison(dimensionType, dim1, metric, met1, DimAvg(avg), color) lazy val peerComparisons: List[AnyComparison] = points.collect { case (dim, TutorBothValueOptions(Some(mine), Some(peer))) @@ -75,6 +75,7 @@ object TutorCompare: } .toList - sealed trait Reference[V] { val value: ValueCount[V] } + sealed trait Reference[V]: + val value: ValueCount[V] case class Peers[V](value: ValueCount[V]) extends Reference[V] case class DimAvg[V](value: ValueCount[V]) extends Reference[V] diff --git a/modules/tutor/src/main/TutorFlagging.scala b/modules/tutor/src/main/TutorFlagging.scala index 3d7437b8d67c5..7c52f506352cc 100644 --- a/modules/tutor/src/main/TutorFlagging.scala +++ b/modules/tutor/src/main/TutorFlagging.scala @@ -20,10 +20,10 @@ object TutorFlagging: val question = Question(InsightDimension.Result, InsightMetric.Termination) filter TutorBuilder.perfFilter(user.perfType) val clockFlagValueName = InsightMetric.MetricValueName(Termination.ClockFlag.name) - for { + for mine <- insightApi.ask(question, user.user, withPovs = false) peer <- insightApi.askPeers(question, user.perfStats.rating, nbGames = maxPeerGames) - } yield + yield def valueCountOf(answer: Answer[Result], result: Result) = answer.clusters.collectFirst { case Cluster(res, Insight.Stacked(points), _, _) if res == result => diff --git a/modules/tutor/src/main/TutorNumber.scala b/modules/tutor/src/main/TutorNumber.scala index 54599934e501f..5576eb5de919a 100644 --- a/modules/tutor/src/main/TutorNumber.scala +++ b/modules/tutor/src/main/TutorNumber.scala @@ -14,9 +14,9 @@ trait TutorNumber[V]: vs.foldLeft((0d, 0)) { case ((sum, total), ValueCount(value, count)) => (sum + iso.to(value) * count, total + count) } match - case (sum, total) => ValueCount(iso.from(if (total > 0) sum / total else 0), total) + case (sum, total) => ValueCount(iso.from(if total > 0 then sum / total else 0), total) def mean(a: ValueCount[V], b: ValueCount[V]): ValueCount[V] = - if (a.count < 1 && b.count < 1) ValueCount(iso from 0, 0) + if a.count < 1 && b.count < 1 then ValueCount(iso from 0, 0) else ValueCount( iso.from((double(a.value) * a.count + double(b.value) * b.count) / (a.count + b.count)), diff --git a/modules/tutor/src/main/model.scala b/modules/tutor/src/main/model.scala index 8fbc18564724b..599e077215ab6 100644 --- a/modules/tutor/src/main/model.scala +++ b/modules/tutor/src/main/model.scala @@ -31,7 +31,7 @@ case class TutorBothValueOptions[A](mine: Option[ValueCount[A]], peer: Option[Va ): def map[B: Ordering](f: A => B) = TutorBothValueOptions(mine.map(_ map f), peer.map(_ map f)) def higher = mine.exists(m => peer.exists(p => o.compare(m.value, p.value) >= 0)) - def asAvailable = for { m <- mine; p <- peer } yield TutorBothValuesAvailable(m, p) + def asAvailable = for m <- mine; p <- peer yield TutorBothValuesAvailable(m, p) def grade(using TutorNumber[A]): Option[Grade] = asAvailable.map(_.grade) def mix(other: TutorBothValueOptions[A])(using number: TutorNumber[A]): TutorBothValueOptions[A] = diff --git a/modules/tutor/src/test/GlickoTest.scala b/modules/tutor/src/test/GlickoTest.scala index f19b90fa1a27d..9ebcbcd9c9206 100644 --- a/modules/tutor/src/test/GlickoTest.scala +++ b/modules/tutor/src/test/GlickoTest.scala @@ -2,7 +2,7 @@ package lila.tutor import lila.rating.Perf -class GlickoTest extends munit.FunSuite { +class GlickoTest extends munit.FunSuite: test("glicko for arbitrary outcomes") { assertEquals( @@ -16,4 +16,3 @@ class GlickoTest extends munit.FunSuite { 1669 ) } -} diff --git a/modules/tv/src/main/Tv.scala b/modules/tv/src/main/Tv.scala index 818f947eea298..550615358eeb9 100644 --- a/modules/tv/src/main/Tv.scala +++ b/modules/tv/src/main/Tv.scala @@ -27,7 +27,7 @@ final class Tv( def getGameAndHistory(channel: Tv.Channel): Fu[Option[(Game, List[Pov])]] = trouper.ask[GameIdAndHistory](TvSyncActor.GetGameIdAndHistory(channel, _)) flatMap { case GameIdAndHistory(gameId, historyIds) => - for { + for game <- gameId so roundProxyGame games <- historyIds @@ -37,7 +37,7 @@ final class Tv( .parallel .dmap(_.flatten) history = games map Pov.naturalOrientation - } yield game map (_ -> history) + yield game map (_ -> history) } def getGames(channel: Tv.Channel, max: Int): Fu[List[Game]] = diff --git a/modules/tv/src/main/TvSyncActor.scala b/modules/tv/src/main/TvSyncActor.scala index 9b58ecbcd57a0..b78f612d5156a 100644 --- a/modules/tv/src/main/TvSyncActor.scala +++ b/modules/tv/src/main/TvSyncActor.scala @@ -53,7 +53,7 @@ final private[tv] class TvSyncActor( case GetChampions(promise) => promise success Tv.Champions(channelChampions) case lila.game.actorApi.StartGame(g) => - if (g.hasClock) + if g.hasClock then val candidate = Tv.Candidate(g, g.userIds.exists(lightUserApi.isBotSync)) channelTroupers collect { case (chan, trouper) if chan filter candidate => trouper @@ -89,7 +89,7 @@ final private[tv] class TvSyncActor( } ) Bus.publish(lila.hub.actorApi.tv.TvSelect(game.id, game.speed, data), "tvSelect") - if (channel == Tv.Channel.Best) + if channel == Tv.Channel.Best then actorAsk(renderer.actor, RenderFeaturedJs(game))(makeTimeout(100 millis)) foreach { case html: String => val pov = Pov naturalOrientation game diff --git a/modules/ublog/src/main/UblogApi.scala b/modules/ublog/src/main/UblogApi.scala index a4958e15a991f..c14776cb925d0 100644 --- a/modules/ublog/src/main/UblogApi.scala +++ b/modules/ublog/src/main/UblogApi.scala @@ -39,11 +39,11 @@ final class UblogApi( colls.post.updateField($id(post.id), "rank", rank).void } >>- { lila.common.Bus.publish(UblogPost.Create(post), "ublogPost") - if (blog.visible) + if blog.visible then timeline ! Propagate( lila.hub.actorApi.timeline.UblogPost(user.id, post.id, post.slug, post.title) ).toFollowersOf(user.id) - if (blog.modTier.isEmpty) sendPostToZulipMaybe(user, post).unit + if blog.modTier.isEmpty then sendPostToZulipMaybe(user, post).unit } def getUserBlog(user: User, insertMissing: Boolean = false): Fu[UblogBlog] = @@ -146,7 +146,7 @@ final class UblogApi( colls.post.find($doc("blog" -> s"user:${user.id}")).cursor[UblogPost](temporarilyPrimary) private[ublog] def setShadowban(userId: UserId, v: Boolean) = { - if (v) fuccess(UblogBlog.Tier.HIDDEN) + if v then fuccess(UblogBlog.Tier.HIDDEN) else userApi.withPerfs(userId).map(_.fold(UblogBlog.Tier.HIDDEN)(UblogBlog.Tier.default)) }.flatMap: setTier(UblogBlog.Id.User(userId), _) diff --git a/modules/ublog/src/main/UblogPaginator.scala b/modules/ublog/src/main/UblogPaginator.scala index d573c55b458f1..5c21b6febedf9 100644 --- a/modules/ublog/src/main/UblogPaginator.scala +++ b/modules/ublog/src/main/UblogPaginator.scala @@ -31,7 +31,7 @@ final class UblogPaginator( collection = colls.post, selector = $doc("blog" -> blog, "live" -> live), projection = previewPostProjection.some, - sort = if (live) $doc("lived.at" -> -1) else $doc("created.at" -> -1), + sort = if live then $doc("lived.at" -> -1) else $doc("created.at" -> -1), _.sec ), currentPage = page, @@ -40,12 +40,12 @@ final class UblogPaginator( def liveByCommunity(lang: Option[Lang], page: Int): Fu[Paginator[PreviewPost]] = Paginator( - adapter = new AdapterLike[PreviewPost] { + adapter = new AdapterLike[PreviewPost]: val select = $doc("live" -> true, "topics" $ne UblogTopic.offTopic) ++ lang.so: l => $doc("language" -> l.code) def nbResults: Fu[Int] = fuccess(10 * maxPerPage.value) def slice(offset: Int, length: Int) = aggregateVisiblePosts(select, offset, length) - }, + , currentPage = page, maxPerPage = maxPerPage ) @@ -65,11 +65,11 @@ final class UblogPaginator( def liveByTopic(topic: UblogTopic, page: Int): Fu[Paginator[PreviewPost]] = Paginator( - adapter = new AdapterLike[PreviewPost] { + adapter = new AdapterLike[PreviewPost]: def nbResults: Fu[Int] = fuccess(10 * maxPerPage.value) def slice(offset: Int, length: Int) = aggregateVisiblePosts($doc("topics" -> topic), offset, length) - }, + , currentPage = page, maxPerPage = maxPerPage ) diff --git a/modules/ublog/src/main/UblogViewCounter.scala b/modules/ublog/src/main/UblogViewCounter.scala index 0df818507e612..8ce8f275cb931 100644 --- a/modules/ublog/src/main/UblogViewCounter.scala +++ b/modules/ublog/src/main/UblogViewCounter.scala @@ -13,13 +13,14 @@ final class UblogViewCounter(colls: UblogColls)(using Executor): ) def apply(post: UblogPost, ip: IpAddress): UblogPost = - if (post.live) post.copy(views = - val key = s"${post.id}:${ip.value}" - if bloomFilter mightContain key then post.views - else - bloomFilter.add(key) - lila.mon.ublog.view(post.created.by.value).increment() - colls.post.incFieldUnchecked($id(post.id), "views") - post.views + 1 - ) + if post.live then + post.copy(views = + val key = s"${post.id}:${ip.value}" + if bloomFilter mightContain key then post.views + else + bloomFilter.add(key) + lila.mon.ublog.view(post.created.by.value).increment() + colls.post.incFieldUnchecked($id(post.id), "views") + post.views + 1 + ) else post diff --git a/modules/ublog/src/test/UblogMarkupTest.scala b/modules/ublog/src/test/UblogMarkupTest.scala index e6ba0c5b2e990..01da3e162b75c 100644 --- a/modules/ublog/src/test/UblogMarkupTest.scala +++ b/modules/ublog/src/test/UblogMarkupTest.scala @@ -2,7 +2,7 @@ package lila.ublog import lila.common.Markdown -class UblogMarkupTest extends munit.FunSuite { +class UblogMarkupTest extends munit.FunSuite: val m = UblogMarkup @@ -47,4 +47,3 @@ class UblogMarkupTest extends munit.FunSuite { assertEquals(m.unescapeAtUsername(Markdown("""> \(By @neio_1\)""")), Markdown("""> \(By @neio_1\)""")) assertEquals(m.unescapeAtUsername(Markdown("""> \(By @neio\_1\)""")), Markdown("""> \(By @neio_1\)""")) } -} diff --git a/modules/user/src/main/Authenticator.scala b/modules/user/src/main/Authenticator.scala index e6cec0c82cde0..1f133b820e958 100644 --- a/modules/user/src/main/Authenticator.scala +++ b/modules/user/src/main/Authenticator.scala @@ -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(if (~auth.sha512) salted.sha512 else salted.sha1) + ClearPassword(if ~auth.sha512 then salted.sha512 else salted.sha1) } passHasher.check(auth.bpass, newP) @@ -50,7 +50,7 @@ final class Authenticator( private def authWithBenefits(auth: AuthData)(p: ClearPassword): Boolean = val res = compare(auth, p) - if (res && auth.salt.isDefined) + if res && auth.salt.isDefined then setPassword(id = auth._id, p) >>- lila.mon.user.auth.bcFullMigrate.increment().unit res diff --git a/modules/user/src/main/Cached.scala b/modules/user/src/main/Cached.scala index 3f99cded61758..564f286c6de81 100644 --- a/modules/user/src/main/Cached.scala +++ b/modules/user/src/main/Cached.scala @@ -98,5 +98,5 @@ final class Cached( _.expireAfterWrite(5 minutes).buildAsyncFuture(userIdsLikeFetch) def userIdsLike(text: UserStr): Fu[List[UserId]] = - if (text.value.lengthIs < 5) userIdsLikeCache get text + if text.value.lengthIs < 5 then userIdsLikeCache get text else userIdsLikeFetch(text) diff --git a/modules/user/src/main/LightUserApi.scala b/modules/user/src/main/LightUserApi.scala index 8f1e06d88d60e..16637e11aeba1 100644 --- a/modules/user/src/main/LightUserApi.scala +++ b/modules/user/src/main/LightUserApi.scala @@ -43,11 +43,12 @@ final class LightUserApi(repo: UserRepo, cacheApi: CacheApi)(using Executor) ext name = "user.light", initialCapacity = 1024 * 1024, compute = id => - if (User isGhost id) fuccess(LightUser.ghost.some) + if User isGhost id then fuccess(LightUser.ghost.some) else repo.coll.find($id(id), projection).one[LightUser] recover { case _: reactivemongo.api.bson.exceptions.BSONValueNotFoundException => LightUser.ghost.some - }, + } + , default = id => LightUser(id, id into UserName, None, isPatron = false).some, strategy = Syncache.Strategy.WaitAfterUptime(10 millis), expireAfter = Syncache.ExpireAfter.Write(20 minutes) diff --git a/modules/user/src/main/Links.scala b/modules/user/src/main/Links.scala index 9aab5b2bb5d7f..1653b5b0c31ae 100644 --- a/modules/user/src/main/Links.scala +++ b/modules/user/src/main/Links.scala @@ -17,11 +17,11 @@ object Links: } private def toLink(line: String): Option[Link] = - for { + for url <- Try(URL.parse(line)).toOption if url.scheme == "http" || url.scheme == "https" host <- Option(url.host).map(_.toHostString) - } yield Site.allKnown.find(_ matches host).map(site => Link(site, url.toString)) | Link( + yield Site.allKnown.find(_ matches host).map(site => Link(site, url.toString)) | Link( Site.Other(host), url.toString ) diff --git a/modules/user/src/main/PasswordHasher.scala b/modules/user/src/main/PasswordHasher.scala index 6ca6ef615f45a..8017610cc41ca 100644 --- a/modules/user/src/main/PasswordHasher.scala +++ b/modules/user/src/main/PasswordHasher.scala @@ -17,9 +17,9 @@ final private class Aes(secret: Secret): private val sKey = val sk = Base64.getDecoder.decode(secret.value) val kBits = sk.length * 8 - if (kBits != 128) - if (!(kBits == 192 || kBits == 256)) throw new IllegalArgumentException - if (kBits > Cipher.getMaxAllowedKeyLength("AES/CTS/NoPadding")) + if kBits != 128 then + if !(kBits == 192 || kBits == 256) then throw new IllegalArgumentException + if kBits > Cipher.getMaxAllowedKeyLength("AES/CTS/NoPadding") then throw new IllegalStateException(s"$kBits bit AES unavailable") new SecretKeySpec(sk, "AES") diff --git a/modules/user/src/main/Stat.scala b/modules/user/src/main/Stat.scala index cdac99bfb15a3..f8f7e64c7c111 100644 --- a/modules/user/src/main/Stat.scala +++ b/modules/user/src/main/Stat.scala @@ -8,6 +8,6 @@ object Stat: def percentile(ratings: List[Int], rating: IntRating): (Int, Int) = ratings.zipWithIndex.foldLeft(0 -> 0) { case ((under, sum), (nb, i)) => { - if (rating > minRating.value + i * group + group / 2) under + nb else under + if rating > minRating.value + i * group + group / 2 then under + nb else under } -> (sum + nb) } diff --git a/modules/user/src/main/Trophy.scala b/modules/user/src/main/Trophy.scala index f4f71865d6cf5..dd1d78da45639 100644 --- a/modules/user/src/main/Trophy.scala +++ b/modules/user/src/main/Trophy.scala @@ -11,7 +11,7 @@ case class Trophy( def timestamp = date.toMillis def compare(other: Trophy) = - if (kind.order == other.kind.order) date compareTo other.date + if kind.order == other.kind.order then date compareTo other.date else Integer.compare(kind.order, other.kind.order) def anyUrl = url orElse kind.url diff --git a/modules/user/src/main/TrophyApi.scala b/modules/user/src/main/TrophyApi.scala index 15b75a933b6a0..968a01dc929d4 100644 --- a/modules/user/src/main/TrophyApi.scala +++ b/modules/user/src/main/TrophyApi.scala @@ -15,10 +15,10 @@ final class TrophyApi( cacheApi.sync[String, TrophyKind]( name = "trophy.kind", initialCapacity = 32, - compute = id => { + compute = id => given BSONDocumentReader[TrophyKind] = Macros.reader[TrophyKind] kindColl.byId[TrophyKind](id).dmap(_ | TrophyKind.Unknown) - }, + , default = _ => TrophyKind.Unknown, strategy = Syncache.Strategy.WaitAfterUptime(20 millis), expireAfter = Syncache.ExpireAfter.Write(1 hour) diff --git a/modules/user/src/main/User.scala b/modules/user/src/main/User.scala index d1cdaed0f6eef..67bdbd97881b8 100644 --- a/modules/user/src/main/User.scala +++ b/modules/user/src/main/User.scala @@ -132,7 +132,7 @@ object User: if check(p.password) then user.totpSecret.fold[Result](Result.Success(user)) { tp => p.token.fold[Result](Result.MissingTotpToken) { token => - if (tp verify token) Result.Success(user) else Result.InvalidTotpToken + if tp verify token then Result.Success(user) else Result.InvalidTotpToken } } else if isBlanked then Result.BlankedPassword diff --git a/modules/user/src/main/UserApi.scala b/modules/user/src/main/UserApi.scala index 3d2ab6575ca9c..cd20bd75cd7a0 100644 --- a/modules/user/src/main/UserApi.scala +++ b/modules/user/src/main/UserApi.scala @@ -76,7 +76,7 @@ final class UserApi(userRepo: UserRepo, perfsRepo: UserPerfsRepo, cacheApi: Cach userRepo.addTitle(user.id, Title.BOT) >> perfsRepo.setBotInitialPerfs(user.id) - def botsByIdsStream(ids: Iterable[UserId], nb: Option[Int]): Source[User.WithPerfs, _] = + def botsByIdsStream(ids: Iterable[UserId], nb: Option[Int]): Source[User.WithPerfs, ?] = userRepo.coll .find($inIds(ids) ++ userRepo.botSelect(true)) .cursor[User](temporarilyPrimary) diff --git a/modules/user/src/main/UserMark.scala b/modules/user/src/main/UserMark.scala index 3fe52e42521d0..b09827f01e183 100644 --- a/modules/user/src/main/UserMark.scala +++ b/modules/user/src/main/UserMark.scala @@ -37,7 +37,7 @@ object UserMarks extends TotalWrapper[UserMarks, List[UserMark]]: def anyVisible = a.boost || a.engine def set(sel: UserMark.type => UserMark, v: Boolean) = UserMarks { - if (v) sel(UserMark) :: a.value + if v then sel(UserMark) :: a.value else a.value.filter(sel(UserMark) !=) } diff --git a/modules/user/src/main/UserPerfs.scala b/modules/user/src/main/UserPerfs.scala index 9aa033c13ac59..b99a933c44b55 100644 --- a/modules/user/src/main/UserPerfs.scala +++ b/modules/user/src/main/UserPerfs.scala @@ -91,7 +91,7 @@ case class UserPerfs( ps.foldLeft(none[IntRating]): case (ro, p) if p.nb >= minNb => ro.fold(p.intRating) { r => - if (p.intRating > r) p.intRating else r + if p.intRating > r then p.intRating else r }.some case (ro, _) => ro .getOrElse(Perf.default.intRating) @@ -108,7 +108,7 @@ case class UserPerfs( def bestProgressIn(types: List[PerfType]): IntRatingDiff = types.foldLeft(IntRatingDiff(0)): (max, t) => val p = apply(t).progress - if (p > max) p else max + if p > max then p else max lazy val perfsMap: Map[Perf.Key, Perf] = Map( Perf.Key("chess960") -> chess960, diff --git a/modules/user/src/main/UserRepo.scala b/modules/user/src/main/UserRepo.scala index be6441310dd46..61eade552259c 100644 --- a/modules/user/src/main/UserRepo.scala +++ b/modules/user/src/main/UserRepo.scala @@ -45,10 +45,9 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): def enabledById[U: UserIdOf](u: U): Fu[Option[User]] = User.noGhost(u.id) so coll.one[User](enabledSelect ++ $id(u)) - def enabledByIds[U: UserIdOf](us: Iterable[U]): Fu[List[User]] = { + def enabledByIds[U: UserIdOf](us: Iterable[U]): Fu[List[User]] = val ids = us.map(_.id).filter(User.noGhost) coll.list[User](enabledSelect ++ $inIds(ids), _.priTemp) - } def byIdOrGhost(id: UserId): Fu[Option[Either[LightUser.Ghost, User]]] = if User isGhost id @@ -165,8 +164,8 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): _.fold(ThreadLocalRandom.nextBoolean()): doc => doc.string("_id") contains u1 .addEffect: v => - incColor(u1, if (v) 1 else -1) - incColor(u2, if (v) -1 else 1) + incColor(u1, if v then 1 else -1) + incColor(u2, if v then -1 else 1) def firstGetsWhite(u1O: Option[UserId], u2O: Option[UserId]): Fu[Boolean] = (u1O, u2O).mapN(firstGetsWhite) | fuccess(ThreadLocalRandom.nextBoolean()) @@ -176,7 +175,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): .update(ordered = false, WriteConcern.Unacknowledged) .one( // limit to -3 <= colorIt <= 5 but set when undefined - $id(userId) ++ $doc(F.colorIt -> $not(if (value < 0) $lte(-3) else $gte(5))), + $id(userId) ++ $doc(F.colorIt -> $not(if value < 0 then $lte(-3) else $gte(5))), $inc(F.colorIt -> value) ) .unit @@ -189,12 +188,12 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): coll.updateField($id(id), F.profile, profile).void def setUsernameCased(id: UserId, name: UserName): Funit = - if (id is name) + if id is name then coll.update.one( $id(id) ++ (F.changedCase $exists false), $set(F.username -> name, F.changedCase -> true) ) flatMap { result => - if (result.n == 0) fufail(s"You have already changed your username") + if result.n == 0 then fufail(s"You have already changed your username") else funit } else fufail(s"Proposed username $name does not match old username $id") @@ -211,7 +210,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): val enabledSelect = $doc(F.enabled -> true) val disabledSelect = $doc(F.enabled -> false) def markSelect(mark: UserMark)(v: Boolean): Bdoc = - if (v) $doc(F.marks -> mark.key) + if v then $doc(F.marks -> mark.key) else F.marks $ne mark.key def engineSelect = markSelect(UserMark.Engine) def trollSelect = markSelect(UserMark.Troll) @@ -237,12 +236,12 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): "count.game".some, rated option "count.rated", ai option "count.ai", - (result match { + (result match case -1 => "count.loss".some case 1 => "count.win".some case 0 => "count.draw".some case _ => none - }), + ), (result match { case -1 => "count.lossH".some case 1 => "count.winH".some @@ -361,7 +360,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): .one( $id(user.id), $set(F.enabled -> false) ++ $unset(F.roles) ++ { - if (keepEmail) $unset(F.mustConfirmEmail) + if keepEmail then $unset(F.mustConfirmEmail) else $doc("$rename" -> $doc(F.email -> F.prevEmail)) } ) diff --git a/modules/user/src/test/AuthTest.scala b/modules/user/src/test/AuthTest.scala index 5e0f5dd9f0a61..758d224560939 100644 --- a/modules/user/src/test/AuthTest.scala +++ b/modules/user/src/test/AuthTest.scala @@ -2,11 +2,11 @@ package lila.user import java.util.Base64 import Authenticator.AuthData -import User.{ ClearPassword => P } +import User.{ ClearPassword as P } import lila.common.config.Secret import scala.concurrent.ExecutionContext.Implicits.global -class AuthTest extends munit.FunSuite { +class AuthTest extends munit.FunSuite: given Conversion[String, UserId] = UserId(_) @@ -86,4 +86,3 @@ class AuthTest extends munit.FunSuite { test("migrated wrong sha") { assert(!auth.compare(shaToBcrypt.copy(sha512 = Some(true)), P("password"))) } -} diff --git a/modules/user/src/test/BCryptTest.scala b/modules/user/src/test/BCryptTest.scala index 051d09c45308a..16dbb0c3e67af 100644 --- a/modules/user/src/test/BCryptTest.scala +++ b/modules/user/src/test/BCryptTest.scala @@ -3,7 +3,7 @@ package lila.user import java.nio.charset.StandardCharsets.UTF_8 import org.mindrot.BCrypt -class BCryptTest extends munit.FunSuite { +class BCryptTest extends munit.FunSuite: // From jBcrypt test suite. val pass = "abc" @@ -28,7 +28,7 @@ class BCryptTest extends munit.FunSuite { assertEquals(rawHash.size, 23) } - import BCrypt.{ encode_base64 => bc64 } + import BCrypt.{ encode_base64 as bc64 } val bString = "$2a$06$" + bc64(salt) + bc64(rawHash) test("raw bytes accept good") { assert(BCrypt.checkpw(pass, bString)) @@ -36,4 +36,3 @@ class BCryptTest extends munit.FunSuite { test("raw bytes reject bad") { assert(!BCrypt.checkpw("", bString)) } -} diff --git a/modules/user/src/test/PasswordHasherTest.scala b/modules/user/src/test/PasswordHasherTest.scala index eee1313bb8b4c..c5d9d79552db0 100644 --- a/modules/user/src/test/PasswordHasherTest.scala +++ b/modules/user/src/test/PasswordHasherTest.scala @@ -1,9 +1,9 @@ package lila.user import lila.common.config.Secret -import User.{ ClearPassword => P } +import User.{ ClearPassword as P } -class PasswordHasherTest extends munit.FunSuite { +class PasswordHasherTest extends munit.FunSuite: test("bad secrets throw exceptions") { intercept[IllegalArgumentException] { @@ -57,4 +57,3 @@ class PasswordHasherTest extends munit.FunSuite { test("hasher uniq hash") { assertNotEquals(liHash, passHasher.hash(P("abc"))) } -} diff --git a/modules/user/src/test/TotpTest.scala b/modules/user/src/test/TotpTest.scala index 30e66229a5ac7..c2fe6ff6caaa1 100644 --- a/modules/user/src/test/TotpTest.scala +++ b/modules/user/src/test/TotpTest.scala @@ -3,7 +3,7 @@ package lila.user import java.nio.charset.StandardCharsets.UTF_8 import User.TotpToken -class TotpTest extends munit.FunSuite { +class TotpTest extends munit.FunSuite: test("read and write secret") { val secret = TotpSecret.random @@ -33,4 +33,3 @@ class TotpTest extends munit.FunSuite { assertEquals(secret.totp(2000000000L / 30), TotpToken("279037")) assertEquals(secret.totp(20000000000L / 30), TotpToken("353130")) } -} diff --git a/modules/user/src/test/UserTest.scala b/modules/user/src/test/UserTest.scala index bea864af82a8b..145a3a8d09bdf 100644 --- a/modules/user/src/test/UserTest.scala +++ b/modules/user/src/test/UserTest.scala @@ -1,6 +1,6 @@ package lila.user -class UserTest extends munit.FunSuite { +class UserTest extends munit.FunSuite: given Conversion[String, UserStr] = UserStr(_) given Conversion[String, UserId] = UserId(_) @@ -53,5 +53,3 @@ class UserTest extends munit.FunSuite { assert(couldBeUsername("G_FOo")) assert(couldBeUsername("g-foo")) } - -} diff --git a/modules/video/src/main/CsvParser.scala b/modules/video/src/main/CsvParser.scala index bb9180759070f..b3cfe2a8cdbfa 100644 --- a/modules/video/src/main/CsvParser.scala +++ b/modules/video/src/main/CsvParser.scala @@ -38,94 +38,76 @@ object CSVParser: var pos = 0 val buflen = buf.length - if (buf.length > 0 && buf(0) == '\uFEFF') - pos += 1 + if buf.length > 0 && buf(0) == '\uFEFF' then pos += 1 - while (state != End && pos < buflen) + while state != End && pos < buflen do val c = buf(pos) (state: @switch) match - case Start => { + case Start => c match - case `quoteChar` => { + case `quoteChar` => state = QuoteStart pos += 1 - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case Delimiter => { + case Delimiter => c match - case `quoteChar` => { + case `quoteChar` => state = QuoteStart pos += 1 - } - case `escapeChar` => { - if ( - pos + 1 < buflen + case `escapeChar` => + if pos + 1 < buflen && (buf(pos + 1) == escapeChar || buf(pos + 1) == delimiter) - ) + then field += buf(pos + 1) state = Field pos += 2 else throw new MalformedCSVException(buf.mkString) - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case Field => { + case Field => c match - case `escapeChar` => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == delimiter - ) + then field += buf(pos + 1) state = Field pos += 2 @@ -133,97 +115,77 @@ object CSVParser: else state = QuoteEnd pos += 1 - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case QuoteStart => { + case QuoteStart => c match - case `escapeChar` if escapeChar != quoteChar => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` if escapeChar != quoteChar => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == quoteChar - ) + then field += buf(pos + 1) state = QuotedField pos += 2 else throw new MalformedCSVException(buf.mkString) - else - throw new MalformedCSVException(buf.mkString) - } - case `quoteChar` => { - if (pos + 1 < buflen && buf(pos + 1) == quoteChar) + else throw new MalformedCSVException(buf.mkString) + case `quoteChar` => + if pos + 1 < buflen && buf(pos + 1) == quoteChar then field += quoteChar state = QuotedField pos += 2 else state = QuoteEnd pos += 1 - } - case x => { + case x => field += x state = QuotedField pos += 1 - } - } - case QuoteEnd => { + case QuoteEnd => c match - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case _ => { + case _ => throw new MalformedCSVException(buf.mkString) - } - } - case QuotedField => { + case QuotedField => c match - case `escapeChar` if escapeChar != quoteChar => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` if escapeChar != quoteChar => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == quoteChar - ) + then field += buf(pos + 1) state = QuotedField pos += 2 @@ -232,41 +194,31 @@ object CSVParser: field += buf(pos + 1) state = QuotedField pos += 2 - else - throw new MalformedCSVException(buf.mkString) - } - case `quoteChar` => { - if (pos + 1 < buflen && buf(pos + 1) == quoteChar) + else throw new MalformedCSVException(buf.mkString) + case `quoteChar` => + if pos + 1 < buflen && buf(pos + 1) == quoteChar then field += quoteChar state = QuotedField pos += 2 else state = QuoteEnd pos += 1 - } - case x => { + case x => field += x state = QuotedField pos += 1 - } - } - case End => { + case End => sys.error("unexpected error") - } (state: @switch) match - case Delimiter => { + case Delimiter => fields :+= "" Some(fields.toList) - } - case QuotedField => { + case QuotedField => None - } - case _ => { + case _ => // When no crlf at end of file state match - case Field | QuoteEnd => { + case Field | QuoteEnd => fields :+= field.toString - } case _ => {} Some(fields.toList) - } diff --git a/modules/video/src/main/Env.scala b/modules/video/src/main/Env.scala index 1010a4da49a47..9997c5ef7ca8e 100644 --- a/modules/video/src/main/Env.scala +++ b/modules/video/src/main/Env.scala @@ -52,7 +52,7 @@ final class Env( case "video" :: "sheet" :: Nil => sheet.fetchAll map { nb => s"Processed $nb videos" } - if (mode == Mode.Prod) + if mode == Mode.Prod then scheduler.scheduleWithFixedDelay(config.sheetDelay, config.sheetDelay) { () => sheet.fetchAll.logFailure(logger).unit } diff --git a/modules/video/src/main/Video.scala b/modules/video/src/main/Video.scala index 334067a79a7fd..a357440276d9c 100644 --- a/modules/video/src/main/Video.scala +++ b/modules/video/src/main/Video.scala @@ -20,7 +20,7 @@ case class Video( def similarity(other: Video) = (tags intersect other.tags).size + (targets intersect other.targets).size + - (if (author == other.author) 1 else 0) + (if author == other.author then 1 else 0) def durationString = metadata.duration.map { seconds => diff --git a/modules/video/src/main/VideoApi.scala b/modules/video/src/main/VideoApi.scala index 1a65d0e06f9cf..429c851e09a1b 100644 --- a/modules/video/src/main/VideoApi.scala +++ b/modules/video/src/main/VideoApi.scala @@ -94,7 +94,7 @@ final private[video] class VideoApi( ) def byTags(user: Option[User], tags: List[Tag], page: Int): Fu[Paginator[VideoView]] = - if (tags.isEmpty) popular(user, page) + if tags.isEmpty then popular(user, page) else Paginator( adapter = new Adapter[Video]( @@ -197,9 +197,10 @@ final private[video] class VideoApi( _.expireAfterAccess(10 minutes) .buildAsyncFuture { filterTags => val allPaths = - if (filterTags.isEmpty) allPopular map { tags => - tags.filterNot(_.isNumeric) - } + if filterTags.isEmpty then + allPopular map { tags => + tags.filterNot(_.isNumeric) + } else videoColl .aggregateList(maxDocs = Int.MaxValue, _.sec): framework => @@ -222,7 +223,7 @@ final private[video] class VideoApi( all find (_.tag == t) } list.sortBy { t => - if (filterTags contains t.tag) Int.MinValue + if filterTags contains t.tag then Int.MinValue else -t.nb } } diff --git a/modules/video/src/main/VideoSheet.scala b/modules/video/src/main/VideoSheet.scala index a976226d7545e..92ba9a6523a82 100644 --- a/modules/video/src/main/VideoSheet.scala +++ b/modules/video/src/main/VideoSheet.scala @@ -52,7 +52,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp api.video .removeNotIn(entries.map(_.youtubeId)) .map: n => - if (n > 0) logger.info(s"$n videos removed") + if n > 0 then logger.info(s"$n videos removed") processed private def fetch: Fu[List[Entry]] = @@ -69,7 +69,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp ) } .flatMap { parsed => - for { + for p <- parsed entry <- p match case List(id, author, title, target, tags, lang, ads, _, include, start, _, _) => @@ -80,8 +80,8 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp title = title.trim, targets = targets, tags = tags.split(';').map(_.trim.toLowerCase).toList.filter(_.nonEmpty) ::: { - if (targets contains 1) List("beginner") - else if (targets contains 3) List("advanced") + if targets contains 1 then List("beginner") + else if targets contains 3 then List("advanced") else Nil }, lang = lang.trim, @@ -92,7 +92,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp case _ => none if entry.include if entry.lang == "en" - } yield entry + yield entry } .toList } diff --git a/modules/video/src/main/control.scala b/modules/video/src/main/control.scala index 23d9697c7d0f7..34d86b4d7d417 100644 --- a/modules/video/src/main/control.scala +++ b/modules/video/src/main/control.scala @@ -12,7 +12,7 @@ case class Filter(tags: List[String]): def toggle(tag: String) = copy( - tags = if (tags contains tag) tags filter (tag !=) else tags :+ tag + tags = if tags contains tag then tags filter (tag !=) else tags :+ tag ) case class UserControl(