game filter multiple choices wip
parent
a73e5c9cb6
commit
c3543ac9d0
|
@ -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 ⇒
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>@trans.variant()</td>
|
||||
<td>@setup.filterRadios(form, "variant", translatedVariantChoices)</td>
|
||||
<td>@setup.filterCheckboxes(form, "variant", filter.variant.map(_.id.toString), translatedVariantChoices)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>@trans.timeControl()</td>
|
||||
<td>@setup.filterRadios(form, "speed", translatedSpeedChoices)</td>
|
||||
<td>@setup.filterCheckboxes(form, "speed", filter.speed.map(_.id.toString), translatedSpeedChoices)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>@trans.mode()</td>
|
||||
<td>@setup.filterRadios(form, "mode", translatedModeChoices)</td>
|
||||
<td>@setup.filterCheckboxes(form, "mode", filter.mode.map(_.id.toString), translatedModeChoices)</td>
|
||||
</tr>
|
||||
@ctx.me.map { me =>
|
||||
<tr>
|
||||
<td>@trans.eloRange()</td>
|
||||
<td>@setup.filterRadios(form, "eloDiff", eloDiffChoices(me.elo))</td>
|
||||
<td>@helper.inputText(form("eloRange"))</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
@(form: Form[_], key: String, index: Int, value: String, checks: List[String], text: Html)
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="@{form(key).name}[@index]"
|
||||
value="@value"
|
||||
@(if(checks contains value) "checked" else "") />
|
||||
@text
|
||||
</label>
|
|
@ -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))
|
||||
}
|
||||
}
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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");
|
||||
|
|
6
todo
6
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})
|
||||
|
|
Loading…
Reference in New Issue