implement user tournament custom start date - closes #4353
parent
babf2c5819
commit
680759f946
|
@ -226,7 +226,9 @@ object Tournament extends LilaController {
|
|||
html = env.forms(me).bindFromRequest.fold(
|
||||
err => BadRequest(html.tournament.form(err, env.forms, me)).fuccess,
|
||||
setup => {
|
||||
val cost = if (me.hasTitle || Env.streamer.liveStreamApi.isStreaming(me.id)) 1 else 4
|
||||
val cost = if (me.hasTitle ||
|
||||
Env.streamer.liveStreamApi.isStreaming(me.id) ||
|
||||
isGranted(_.ManageTournament)) 1 else 4
|
||||
CreateLimitPerUser(me.id, cost = 1) {
|
||||
CreateLimitPerIP(HTTPRequest lastRemoteAddress ctx.req, cost = 1) {
|
||||
env.api.createTournament(setup, me) map { tour =>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
@moreJs = {
|
||||
@jsAt("vendor/flatpickr/dist/flatpickr.min.js")
|
||||
@flatpickrTag
|
||||
@embedJs {
|
||||
$(".flatpickr").flatpickr();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
@moreJs = {
|
||||
@jsAt("vendor/flatpickr/dist/flatpickr.min.js")
|
||||
@flatpickrTag
|
||||
@embedJs {
|
||||
$(".flatpickr").flatpickr();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
@(title: String)(body: Html)(implicit ctx: Context)
|
||||
|
||||
@moreCss = {
|
||||
@cssAt("vendor/flatpickr/dist/flatpickr.min.css")
|
||||
@cssTag("flatpickr.css")
|
||||
@cssTag("material.form.css")
|
||||
@cssTag("tournament.crud.css")
|
||||
}
|
||||
|
||||
@moreJs = {
|
||||
@jsAt("vendor/flatpickr/dist/flatpickr.min.js")
|
||||
@flatpickrTag
|
||||
@embedJs {
|
||||
$(".flatpickr").flatpickr();
|
||||
$(function() { $(".flatpickr").flatpickr(); })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
@import lila.tournament.DataForm._
|
||||
|
||||
@moreJs = {
|
||||
@flatpickrTag
|
||||
@jsTag("tournamentForm.js")
|
||||
}
|
||||
@moreCss = {
|
||||
@cssTag("tournament.form.css")
|
||||
@cssTag("flatpickr.css")
|
||||
@cssTag("material.form.css")
|
||||
@cssTag("tournament.form.css")
|
||||
}
|
||||
|
||||
@tournament.layout(
|
||||
|
@ -40,7 +42,7 @@ moreJs = moreJs) {
|
|||
@base.form.input(form("name")) Arena<br />
|
||||
@errMsg(form("name"))
|
||||
<strong>@trans.safeTournamentName()<br />
|
||||
@trans.inappropriateNameWarning()</strong><br />
|
||||
@trans.inappropriateNameWarning()</strong><br />
|
||||
@trans.emptyTournamentName()
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -85,6 +87,9 @@ moreJs = moreJs) {
|
|||
</p>
|
||||
<div class="material form">
|
||||
@tournament.conditionForm(form, auto = true)
|
||||
@base.form.group(form("startDate"), Html("Custom start date"), help = Html("""This overrides the "Time before tournament starts" setting""").some) { field =>
|
||||
@base.form.flatpickr(field)
|
||||
}
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="submit" class="submit button" data-icon="g">
|
||||
|
|
|
@ -7,34 +7,36 @@ import play.api.data.Forms._
|
|||
|
||||
object Form {
|
||||
|
||||
def options(it: Iterable[Int], pattern: String) = it map { d =>
|
||||
type Options[A] = Iterable[(A, String)]
|
||||
|
||||
def options(it: Iterable[Int], pattern: String): Options[Int] = it map { d =>
|
||||
d -> (pluralize(pattern, d) format d)
|
||||
}
|
||||
|
||||
def options(it: Iterable[Int], transformer: Int => Int, pattern: String) = it map { d =>
|
||||
def options(it: Iterable[Int], transformer: Int => Int, pattern: String): Options[Int] = it map { d =>
|
||||
d -> (pluralize(pattern, transformer(d)) format transformer(d))
|
||||
}
|
||||
|
||||
def options(it: Iterable[Int], code: String, pattern: String) = it map { d =>
|
||||
def options(it: Iterable[Int], code: String, pattern: String): Options[String] = it map { d =>
|
||||
(d + code) -> (pluralize(pattern, d) format d)
|
||||
}
|
||||
|
||||
def optionsDouble(it: Iterable[Double], format: Double => String) = it map { d =>
|
||||
def optionsDouble(it: Iterable[Double], format: Double => String): Options[Double] = it map { d =>
|
||||
d -> format(d)
|
||||
}
|
||||
|
||||
def numberIn(choices: Iterable[(Int, String)]) =
|
||||
def numberIn(choices: Options[Int]) =
|
||||
number.verifying(hasKey(choices, _))
|
||||
|
||||
def numberInDouble(choices: Iterable[(Double, String)]) =
|
||||
def numberInDouble(choices: Options[Double]) =
|
||||
of[Double].verifying(hasKey(choices, _))
|
||||
|
||||
def stringIn(choices: Iterable[(String, String)]) =
|
||||
def stringIn(choices: Options[String]) =
|
||||
text.verifying(hasKey(choices, _))
|
||||
|
||||
def tolerantBoolean = of[Boolean](formatter.tolerantBooleanFormatter)
|
||||
|
||||
def hasKey[A](choices: Iterable[(A, _)], key: A) =
|
||||
def hasKey[A](choices: Options[A], key: A) =
|
||||
choices.map(_._1).toList contains key
|
||||
|
||||
def trueish(v: Any) = v == 1 || v == "1" || v == "true" || v == "on" || v == "yes"
|
||||
|
@ -66,4 +68,9 @@ object Form {
|
|||
val utcDate = jodaDate(dateTimePattern, DateTimeZone.UTC)
|
||||
implicit val dateTimeFormat = jodaDateTimeFormat(dateTimePattern)
|
||||
}
|
||||
object ISODate {
|
||||
val dateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
|
||||
val isoDate = jodaDate(dateTimePattern, DateTimeZone.UTC)
|
||||
implicit val dateTimeFormat = jodaDateTimeFormat(dateTimePattern)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package lila.tournament
|
||||
|
||||
import org.joda.time.DateTime
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
import play.api.data.validation.Constraints
|
||||
|
@ -7,6 +8,7 @@ import play.api.data.validation.Constraints
|
|||
import chess.Mode
|
||||
import chess.StartingPosition
|
||||
import lila.common.Form._
|
||||
import lila.common.Form.ISODate._
|
||||
import lila.user.User
|
||||
|
||||
final class DataForm {
|
||||
|
@ -19,6 +21,7 @@ final class DataForm {
|
|||
clockIncrement = clockIncrementDefault,
|
||||
minutes = minuteDefault,
|
||||
waitMinutes = waitMinuteDefault.some,
|
||||
startDate = none,
|
||||
variant = chess.variant.Standard.key.some,
|
||||
position = StartingPosition.initial.fen.some,
|
||||
`private` = false,
|
||||
|
@ -43,6 +46,7 @@ final class DataForm {
|
|||
"clockIncrement" -> numberIn(clockIncrementPrivateChoices),
|
||||
"minutes" -> numberIn(minutePrivateChoices),
|
||||
"waitMinutes" -> optional(numberIn(waitMinuteChoices)),
|
||||
"startDate" -> optional(isoDate),
|
||||
"variant" -> optional(nonEmptyText.verifying(v => guessVariant(v).isDefined)),
|
||||
"position" -> optional(nonEmptyText),
|
||||
"mode" -> optional(number.verifying(Mode.all map (_.id) contains _)),
|
||||
|
@ -114,6 +118,7 @@ private[tournament] case class TournamentSetup(
|
|||
clockIncrement: Int,
|
||||
minutes: Int,
|
||||
waitMinutes: Option[Int],
|
||||
startDate: Option[DateTime],
|
||||
variant: Option[String],
|
||||
position: Option[String],
|
||||
mode: Option[Int],
|
||||
|
|
|
@ -143,6 +143,7 @@ object Tournament {
|
|||
`private`: Boolean,
|
||||
password: Option[String],
|
||||
waitMinutes: Int,
|
||||
startDate: Option[DateTime],
|
||||
berserkable: Boolean
|
||||
) = Tournament(
|
||||
id = Random nextString 8,
|
||||
|
@ -165,7 +166,9 @@ object Tournament {
|
|||
conditions = Condition.All.empty,
|
||||
noBerserk = !berserkable,
|
||||
schedule = None,
|
||||
startsAt = DateTime.now plusMinutes waitMinutes
|
||||
startsAt = startDate | {
|
||||
DateTime.now plusMinutes waitMinutes
|
||||
}
|
||||
)
|
||||
|
||||
def schedule(sched: Schedule, minutes: Int) = Tournament(
|
||||
|
|
|
@ -51,6 +51,7 @@ final class TournamentApi(
|
|||
clock = setup.clockConfig,
|
||||
minutes = setup.minutes,
|
||||
waitMinutes = setup.waitMinutes | DataForm.waitMinuteDefault,
|
||||
startDate = setup.startDate,
|
||||
mode = setup.realMode,
|
||||
`private` = setup.`private`,
|
||||
password = setup.password ifTrue setup.`private`,
|
||||
|
|
|
@ -47,6 +47,7 @@ final class CrudApi {
|
|||
`private` = false,
|
||||
password = None,
|
||||
waitMinutes = 0,
|
||||
startDate = none,
|
||||
berserkable = true
|
||||
)
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ $(function() {
|
|||
var $minutes = $('#tournament tr.minutes td');
|
||||
|
||||
function replace($el, $paste) {
|
||||
var prvVal = $el.children().first().val();
|
||||
$el.html($paste.html());
|
||||
if (prvVal) {
|
||||
$el.children().first().val(prvVal);
|
||||
}
|
||||
var prvVal = $el.children().first().val();
|
||||
$el.html($paste.html());
|
||||
if (prvVal) {
|
||||
$el.children().first().val(prvVal);
|
||||
}
|
||||
}
|
||||
|
||||
function showPrivate() {
|
||||
|
@ -38,4 +38,14 @@ $(function() {
|
|||
$(this).remove();
|
||||
$('.conditions .form').show();
|
||||
});
|
||||
$('.conditions .form').show();
|
||||
|
||||
$(".flatpickr").flatpickr({
|
||||
enableTime: true,
|
||||
minDate: 'today',
|
||||
maxDate: new Date().fp_incr(31),
|
||||
dateFormat: 'Z',
|
||||
altInput: true,
|
||||
altFormat: 'Y-m-d h:i K'
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue