diff --git a/app/controllers/Setup.scala b/app/controllers/Setup.scala index c284550649..421cb24f2e 100644 --- a/app/controllers/Setup.scala +++ b/app/controllers/Setup.scala @@ -1,12 +1,11 @@ package controllers -import play.api.data.Form -import play.api.mvc.{ Result, Call } - import lila.app._ import lila.game.GameRepo import lila.user.UserRepo import lila.user.{ Context, BodyContext } +import play.api.data.Form +import play.api.mvc.{ Result, Call } import views._ object Setup extends LilaController with TheftPrevention { @@ -69,7 +68,9 @@ object Setup extends LilaController with TheftPrevention { } def filterForm = Open { implicit ctx ⇒ - env.forms.filterFilled map { html.setup.filter(_) } + env.forms.filterFilled map { + case (form, filter) ⇒ html.setup.filter(form, filter) + } } def filter = OpenBody { implicit ctx ⇒ diff --git a/app/templating/SetupHelper.scala b/app/templating/SetupHelper.scala index 78e2fbb3a7..e9a17f7e03 100644 --- a/app/templating/SetupHelper.scala +++ b/app/templating/SetupHelper.scala @@ -29,8 +29,4 @@ trait SetupHelper extends scalaz.Booleans { self: I18nHelper ⇒ } } } - - def eloDiffChoices(elo: Int)(implicit ctx: Context) = FilterConfig.eloDiffs map { diff ⇒ - diff -> "%d - %d (±%d)".format(elo - diff, elo + diff, diff) - } } diff --git a/app/views/setup/filter.scala.html b/app/views/setup/filter.scala.html index 43e344e078..4cc3fac74b 100644 --- a/app/views/setup/filter.scala.html +++ b/app/views/setup/filter.scala.html @@ -1,24 +1,24 @@ -@(form: Form[_])(implicit ctx: Context) +@(form: Form[_], filter: lila.setup.FilterConfig)(implicit ctx: Context) @helper.form(action = routes.Setup.filter(), 'novalidate -> "novalidate") { - + - + - + @ctx.me.map { me => - + } diff --git a/app/views/setup/filterCheckbox.scala.html b/app/views/setup/filterCheckbox.scala.html new file mode 100644 index 0000000000..29a36f648c --- /dev/null +++ b/app/views/setup/filterCheckbox.scala.html @@ -0,0 +1,10 @@ +@(form: Form[_], key: String, index: Int, value: String, checks: List[String], text: Html) + + diff --git a/app/views/setup/filterCheckboxes.scala.html b/app/views/setup/filterCheckboxes.scala.html new file mode 100644 index 0000000000..ba6b6ea9f5 --- /dev/null +++ b/app/views/setup/filterCheckboxes.scala.html @@ -0,0 +1,7 @@ +@(form: Form[_], key: String, checks: List[String], options: Seq[(Any,String)])(implicit ctx: Context) + +@options.zipWithIndex.map { +case ((value, text), index) => { +@setup.filterCheckbox(form, key, index, value.toString, checks, Html(text)) +} +} diff --git a/modules/common/src/main/PimpedJson.scala b/modules/common/src/main/PimpedJson.scala index 30262ab450..9b1d6278b7 100644 --- a/modules/common/src/main/PimpedJson.scala +++ b/modules/common/src/main/PimpedJson.scala @@ -26,6 +26,11 @@ trait PimpedJson { def arr(key: String): Option[JsArray] = (js \ key).asOpt[JsArray] + def ints(key: String): Option[List[Int]] = + (js \ key).asOpt[JsArray] map { arr ⇒ + arr.value.toList map { v ⇒ v.asOpt[Int] } flatten + } + def get[A: Reads](key: String): Option[A] = (js \ key).asOpt[A] } diff --git a/modules/setup/src/main/FilterConfig.scala b/modules/setup/src/main/FilterConfig.scala index 260ed01c05..161f0c9985 100644 --- a/modules/setup/src/main/FilterConfig.scala +++ b/modules/setup/src/main/FilterConfig.scala @@ -4,62 +4,62 @@ import play.api.libs.json._ import chess.{ Variant, Mode, Speed } import lila.common.PimpedJson._ +import lila.common.EloRange case class FilterConfig( - variant: Option[Variant], - mode: Option[Mode], - speed: Option[Speed], - eloDiff: Option[Int]) { + variant: List[Variant], + mode: List[Mode], + speed: List[Speed], + eloRange: EloRange) { def encode = RawFilterConfig( - v = ~variant.map(_.id), - m = mode.map(_.id) | -1, - s = ~speed.map(_.id), - e = ~eloDiff + v = variant.map(_.id), + m = mode.map(_.id), + s = speed.map(_.id), + e = eloRange.toString ) def >> = ( variant map (_.id), mode map (_.id), speed map (_.id), - eloDiff + eloRange.toString ).some def render = Json.obj( "variant" -> variant.map(_.toString), "mode" -> mode.map(_.toString), "speed" -> speed.map(_.id), - "eloDiff" -> eloDiff + "eloRange" -> eloRange.toString ) } object FilterConfig { + val variants = List(Variant.Standard, Variant.Chess960) + val modes = Mode.all + val speeds = Speed.all + val default = FilterConfig( - variant = none, - mode = none, - speed = none, - eloDiff = none) + variant = variants, + mode = modes, + speed = speeds, + eloRange = EloRange.default) - val variants = 0 :: Config.variants - val modes = -1 :: Mode.all.map(_.id) - val speeds = 0 :: Config.speeds - val eloDiffs = 100 :: 200 :: 300 :: 500 :: Nil - - def <<(v: Option[Int], m: Option[Int], s: Option[Int], e: Option[Int]) = new FilterConfig( - variant = v flatMap Variant.apply, - mode = m flatMap Mode.apply, - speed = s flatMap Speed.apply, - eloDiff = e filter (0!=) + def <<(v: List[Int], m: List[Int], s: List[Int], e: String) = new FilterConfig( + variant = v map Variant.apply flatten, + mode = m map Mode.apply flatten, + speed = s map Speed.apply flatten, + eloRange = EloRange orDefault e ) def fromDB(obj: JsObject): Option[FilterConfig] = for { filter ← obj obj "filter" - variant ← filter int "v" - mode ← filter int "m" - speed ← filter int "s" - eloDiff ← filter int "e" - config ← RawFilterConfig(variant, mode, speed, eloDiff).decode + variant ← filter ints "v" + mode ← filter ints "m" + speed ← filter ints "s" + eloRange ← filter str "e" + config ← RawFilterConfig(variant, mode, speed, eloRange).decode } yield config import lila.db.Tube @@ -79,13 +79,13 @@ object FilterConfig { ) } -private[setup] case class RawFilterConfig(v: Int, m: Int, s: Int, e: Int) { +private[setup] case class RawFilterConfig(v: List[Int], m: List[Int], s: List[Int], e: String) { def decode = FilterConfig( - variant = Variant(v), - mode = Mode(m), - speed = Speed(s), - eloDiff = e.some filter (0!=) + variant = v map Variant.apply flatten, + mode = m map Mode.apply flatten, + speed = s map Speed.apply flatten, + eloRange = EloRange orDefault e ).some } diff --git a/modules/setup/src/main/FormFactory.scala b/modules/setup/src/main/FormFactory.scala index 11ff59262f..65c4dabbce 100644 --- a/modules/setup/src/main/FormFactory.scala +++ b/modules/setup/src/main/FormFactory.scala @@ -1,28 +1,27 @@ package lila.setup -import play.api.data._ -import play.api.data.Forms._ - import chess.Variant import lila.common.EloRange import lila.db.api._ import lila.lobby.Color import lila.user.Context +import play.api.data._ +import play.api.data.Forms._ import tube.{ userConfigTube, anonConfigTube } private[setup] final class FormFactory { import Mappings._ - def filterFilled(implicit ctx: Context): Fu[Form[FilterConfig]] = - filterConfig map filter(ctx).fill + def filterFilled(implicit ctx: Context): Fu[(Form[FilterConfig], FilterConfig)] = + filterConfig map { f ⇒ filter(ctx).fill(f) -> f } def filter(ctx: Context) = Form( mapping( - "variant" -> optional(variant), - "mode" -> mode(true), - "speed" -> optional(speed), - "eloDiff" -> optional(eloDiff) + "variant" -> list(variant), + "mode" -> list(rawMode(true)), + "speed" -> list(speed), + "eloRange" -> nonEmptyText )(FilterConfig.<<)(_.>>) ) @@ -30,7 +29,7 @@ private[setup] final class FormFactory { def aiFilled(fen: Option[String])(implicit ctx: Context): Fu[Form[AiConfig]] = aiConfig map { config ⇒ - ai(ctx) fill fen.fold(config) { f ⇒ + ai(ctx) fill fen.fold(config) { f ⇒ config.copy(fen = f.some, variant = Variant.FromPosition) } } @@ -51,7 +50,7 @@ private[setup] final class FormFactory { def friendFilled(fen: Option[String])(implicit ctx: Context): Fu[Form[FriendConfig]] = friendConfig map { config ⇒ - friend(ctx) fill fen.fold(config) { f ⇒ + friend(ctx) fill fen.fold(config) { f ⇒ config.copy(fen = f.some, variant = Variant.FromPosition) } } @@ -90,6 +89,6 @@ private[setup] final class FormFactory { def hookConfig(implicit ctx: Context): Fu[HookConfig] = savedConfig map (_.hook) - def savedConfig(implicit ctx: Context): Fu[UserConfig] = + def savedConfig(implicit ctx: Context): Fu[UserConfig] = ctx.me.fold(AnonConfigRepo config ctx.req)(UserConfigRepo.config) } diff --git a/modules/setup/src/main/Mappings.scala b/modules/setup/src/main/Mappings.scala index 1b90c4b0c8..e3129b9dae 100644 --- a/modules/setup/src/main/Mappings.scala +++ b/modules/setup/src/main/Mappings.scala @@ -13,14 +13,14 @@ object Mappings { val variantWithFen = number.verifying(Config.variantsWithFen contains _) val time = number.verifying(HookConfig.times contains _) val increment = number.verifying(HookConfig.increments contains _) - def mode(isAuth: Boolean) = optional(number + def mode(isAuth: Boolean) = optional(rawMode(isAuth)) + def rawMode(isAuth: Boolean) = number .verifying(HookConfig.modes contains _) - .verifying(m ⇒ m == Mode.Casual.id || isAuth)) + .verifying(m ⇒ m == Mode.Casual.id || isAuth) val eloRange = optional(nonEmptyText.verifying(EloRange valid _)) val color = nonEmptyText.verifying(Color.names contains _) val level = number.verifying(AiConfig.levels contains _) val speed = number.verifying(Config.speeds contains _) - val eloDiff = number.verifying(FilterConfig.eloDiffs contains _) def fen(strict: Boolean) = optional { nonEmptyText verifying { source ⇒ ~(Forsyth <<< source).map(_.situation playable strict) } diff --git a/public/javascripts/big.js b/public/javascripts/big.js index c2fc4e3aae..dbf0865851 100644 --- a/public/javascripts/big.js +++ b/public/javascripts/big.js @@ -2033,7 +2033,7 @@ var storage = { $div.fadeOut(500); } return false; - }); + }).click(); $bot.on("click", "tr", function() { location.href = $(this).find('a.watch').attr("href"); diff --git a/todo b/todo index 927b4913b3..c8a584d180 100644 --- a/todo +++ b/todo @@ -57,4 +57,8 @@ customize sound notifications http://imgur.com/70WVyb5 opera issue http://en.lichess.org/forum/lichess-feedback/new-game-wont-show-on-games-list-opera#1 embedded games links http://2ls.ru/chessonline/ filter ranges http://en.lichess.org/forum/lichess-feedback/my-proposed-changes-with-filter-window#1 -takeback en passant http://fr.lichess.org/forum/general-chess-discussion/bug-with-take-back-and-en-passant#2 + +deploy +------ +db.config.update({filter:{$exists:1}},{$unset:{filter:1}},{multi:1}) +db.config_anon.update({filter:{$exists:1}},{$unset:{filter:1}},{multi:1})
@trans.variant()@setup.filterRadios(form, "variant", translatedVariantChoices)@setup.filterCheckboxes(form, "variant", filter.variant.map(_.id.toString), translatedVariantChoices)
@trans.timeControl()@setup.filterRadios(form, "speed", translatedSpeedChoices)@setup.filterCheckboxes(form, "speed", filter.speed.map(_.id.toString), translatedSpeedChoices)
@trans.mode()@setup.filterRadios(form, "mode", translatedModeChoices)@setup.filterCheckboxes(form, "mode", filter.mode.map(_.id.toString), translatedModeChoices)
@trans.eloRange()@setup.filterRadios(form, "eloDiff", eloDiffChoices(me.elo))@helper.inputText(form("eloRange"))