let tournament owners disable the chat - closes #6436
This commit is contained in:
parent
2f8ddc6531
commit
b13f73ffcd
|
@ -68,7 +68,7 @@ final class Tournament(
|
||||||
}
|
}
|
||||||
|
|
||||||
private[controllers] def canHaveChat(tour: Tour, json: Option[JsObject])(implicit ctx: Context): Boolean =
|
private[controllers] def canHaveChat(tour: Tour, json: Option[JsObject])(implicit ctx: Context): Boolean =
|
||||||
!ctx.kid && // no public chats for kids
|
tour.hasChat && !ctx.kid && // no public chats for kids
|
||||||
ctx.me.fold(!tour.isPrivate) { u => // anon can see public chats, except for private tournaments
|
ctx.me.fold(!tour.isPrivate) { u => // anon can see public chats, except for private tournaments
|
||||||
(!tour.isPrivate || json.fold(true)(jsonHasMe) || isGranted(_.ChatTimeout)) && // private tournament that I joined or has ChatTimeout
|
(!tour.isPrivate || json.fold(true)(jsonHasMe) || isGranted(_.ChatTimeout)) && // private tournament that I joined or has ChatTimeout
|
||||||
env.chat.panic.allowed(u, tighter = tour.variant == chess.variant.Antichess)
|
env.chat.panic.allowed(u, tighter = tour.variant == chess.variant.Antichess)
|
||||||
|
|
|
@ -118,7 +118,7 @@ object crud {
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
h2("Entry requirements"),
|
h2("Entry requirements"),
|
||||||
tournament.form.condition(form, auto = false, Nil),
|
tournament.form.condition(form, new TourFields(form), auto = false, Nil),
|
||||||
form3.action(form3.submit(trans.apply()))
|
form3.action(form3.submit(trans.apply()))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,7 @@ object form {
|
||||||
fieldset(cls := "conditions")(
|
fieldset(cls := "conditions")(
|
||||||
fields.advancedSettings,
|
fields.advancedSettings,
|
||||||
div(cls := "form")(
|
div(cls := "form")(
|
||||||
fields.password,
|
condition(form, fields, auto = true, teams = myTeams),
|
||||||
condition(form, auto = true, teams = myTeams),
|
|
||||||
fields.startDate
|
fields.startDate
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -85,8 +84,7 @@ object form {
|
||||||
fieldset(cls := "conditions")(
|
fieldset(cls := "conditions")(
|
||||||
fields.advancedSettings,
|
fields.advancedSettings,
|
||||||
div(cls := "form")(
|
div(cls := "form")(
|
||||||
fields.password,
|
condition(form, fields, auto = true, teams = myTeams)
|
||||||
condition(form, auto = true, teams = myTeams)
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
form3.actions(
|
form3.actions(
|
||||||
|
@ -107,60 +105,74 @@ object form {
|
||||||
if (auto) form3.hidden(field) else visible(field)
|
if (auto) form3.hidden(field) else visible(field)
|
||||||
)
|
)
|
||||||
|
|
||||||
def condition(form: Form[_], auto: Boolean, teams: List[lila.hub.LightTeam])(implicit ctx: Context) = frag(
|
def condition(form: Form[_], fields: TourFields, auto: Boolean, teams: List[lila.hub.LightTeam])(
|
||||||
|
implicit ctx: Context
|
||||||
|
) = frag(
|
||||||
form3.split(
|
form3.split(
|
||||||
form3.group(form("conditions.nbRatedGame.nb"), raw("Minimum rated games"), half = true)(
|
fields.password,
|
||||||
|
(auto && teams.size > 0) option {
|
||||||
|
val baseField = form("conditions.teamMember.teamId")
|
||||||
|
val field = ctx.req.queryString get "team" flatMap (_.headOption) match {
|
||||||
|
case None => baseField
|
||||||
|
case Some(team) => baseField.copy(value = team.some)
|
||||||
|
}
|
||||||
|
form3.group(field, frag("Only members of team"), half = true)(
|
||||||
|
form3.select(_, List(("", "No Restriction")) ::: teams.map(_.pair))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
form3.split(
|
||||||
|
form3.group(form("conditions.nbRatedGame.nb"), frag("Minimum rated games"), half = true)(
|
||||||
form3.select(_, Condition.DataForm.nbRatedGameChoices)
|
form3.select(_, Condition.DataForm.nbRatedGameChoices)
|
||||||
),
|
),
|
||||||
autoField(auto, form("conditions.nbRatedGame.perf")) { field =>
|
autoField(auto, form("conditions.nbRatedGame.perf")) { field =>
|
||||||
form3.group(field, raw("In variant"), half = true)(
|
form3.group(field, frag("In variant"), half = true)(
|
||||||
form3.select(_, ("", "Any") :: Condition.DataForm.perfChoices)
|
form3.select(_, ("", "Any") :: Condition.DataForm.perfChoices)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
form3.split(
|
form3.split(
|
||||||
form3.group(form("conditions.minRating.rating"), raw("Minimum rating"), half = true)(
|
form3.group(form("conditions.minRating.rating"), frag("Minimum rating"), half = true)(
|
||||||
form3.select(_, Condition.DataForm.minRatingChoices)
|
form3.select(_, Condition.DataForm.minRatingChoices)
|
||||||
),
|
),
|
||||||
autoField(auto, form("conditions.minRating.perf")) { field =>
|
autoField(auto, form("conditions.minRating.perf")) { field =>
|
||||||
form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices))
|
form3.group(field, frag("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices))
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
form3.split(
|
form3.split(
|
||||||
form3.group(form("conditions.maxRating.rating"), raw("Maximum weekly rating"), half = true)(
|
form3.group(form("conditions.maxRating.rating"), frag("Maximum weekly rating"), half = true)(
|
||||||
form3.select(_, Condition.DataForm.maxRatingChoices)
|
form3.select(_, Condition.DataForm.maxRatingChoices)
|
||||||
),
|
),
|
||||||
autoField(auto, form("conditions.maxRating.perf")) { field =>
|
autoField(auto, form("conditions.maxRating.perf")) { field =>
|
||||||
form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices))
|
form3.group(field, frag("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices))
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
form3.split(
|
form3.split(
|
||||||
(ctx.me.exists(_.hasTitle) || isGranted(_.ManageTournament)) ?? {
|
(ctx.me.exists(_.hasTitle) || isGranted(_.ManageTournament)) ?? {
|
||||||
form3.checkbox(
|
form3.checkbox(
|
||||||
form("conditions.titled"),
|
form("conditions.titled"),
|
||||||
raw("Only titled players"),
|
frag("Only titled players"),
|
||||||
help = raw("Require an official title to join the tournament").some,
|
help = frag("Require an official title to join the tournament").some,
|
||||||
half = true
|
half = true
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
form3.checkbox(
|
form3.checkbox(
|
||||||
form("berserkable"),
|
form("berserkable"),
|
||||||
raw("Allow Berserk"),
|
frag("Allow Berserk"),
|
||||||
help = raw("Let players halve their clock time to gain an extra point").some,
|
help = frag("Let players halve their clock time to gain an extra point").some,
|
||||||
half = true
|
half = true
|
||||||
),
|
),
|
||||||
input(tpe := "hidden", st.name := form("berserkable").name, value := "false") // hack allow disabling berserk
|
input(tpe := "hidden", st.name := form("berserkable").name, value := "false") // hack to allow disabling berserk
|
||||||
),
|
),
|
||||||
(auto && teams.size > 0) option {
|
form3.split(
|
||||||
val baseField = form("conditions.teamMember.teamId")
|
form3.checkbox(
|
||||||
val field = ctx.req.queryString get "team" flatMap (_.headOption) match {
|
form("hasChat"),
|
||||||
case None => baseField
|
trans.chatRoom(),
|
||||||
case Some(team) => baseField.copy(value = team.some)
|
help = frag("Let players discuss in a chat room").some,
|
||||||
}
|
half = true
|
||||||
form3.group(field, raw("Only members of team"), half = false)(
|
),
|
||||||
form3.select(_, List(("", "No Restriction")) ::: teams.map(_.pair))
|
input(tpe := "hidden", st.name := form("hasChat").name, value := "false") // hack to allow disabling chat
|
||||||
)
|
)
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def startingPosition(field: Field) =
|
def startingPosition(field: Field) =
|
||||||
|
@ -240,7 +252,7 @@ final private class TourFields(form: Form[_])(implicit ctx: Context) {
|
||||||
def description =
|
def description =
|
||||||
form3.group(
|
form3.group(
|
||||||
form("description"),
|
form("description"),
|
||||||
raw("Tournament description"),
|
frag("Tournament description"),
|
||||||
help = frag("Anything special you want to tell the participants? Try to keep it short.").some
|
help = frag("Anything special you want to tell the participants? Try to keep it short.").some
|
||||||
)(form3.textarea(_)(rows := 2))
|
)(form3.textarea(_)(rows := 2))
|
||||||
def password =
|
def password =
|
||||||
|
@ -248,13 +260,14 @@ final private class TourFields(form: Form[_])(implicit ctx: Context) {
|
||||||
form3.group(
|
form3.group(
|
||||||
form("password"),
|
form("password"),
|
||||||
trans.password(),
|
trans.password(),
|
||||||
help = trans.makePrivateTournament().some
|
help = trans.makePrivateTournament().some,
|
||||||
|
half = true
|
||||||
)(form3.input(_))
|
)(form3.input(_))
|
||||||
def startDate =
|
def startDate =
|
||||||
form3.group(
|
form3.group(
|
||||||
form("startDate"),
|
form("startDate"),
|
||||||
raw("Custom start date"),
|
frag("Custom start date"),
|
||||||
help = raw("""This overrides the "Time before tournament starts" setting""").some
|
help = frag("""This overrides the "Time before tournament starts" setting""").some
|
||||||
)(form3.flatpickr(_))
|
)(form3.flatpickr(_))
|
||||||
def advancedSettings = frag(
|
def advancedSettings = frag(
|
||||||
legend(trans.advancedSettings()),
|
legend(trans.advancedSettings()),
|
||||||
|
|
|
@ -86,7 +86,8 @@ object BSONHandlers {
|
||||||
winnerId = r strO "winner",
|
winnerId = r strO "winner",
|
||||||
featuredId = r strO "featured",
|
featuredId = r strO "featured",
|
||||||
spotlight = r.getO[Spotlight]("spotlight"),
|
spotlight = r.getO[Spotlight]("spotlight"),
|
||||||
description = r strO "description"
|
description = r strO "description",
|
||||||
|
hasChat = r boolO "chat" getOrElse true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
def writes(w: BSON.Writer, o: Tournament) = $doc(
|
def writes(w: BSON.Writer, o: Tournament) = $doc(
|
||||||
|
@ -115,7 +116,8 @@ object BSONHandlers {
|
||||||
"winner" -> o.winnerId,
|
"winner" -> o.winnerId,
|
||||||
"featured" -> o.featuredId,
|
"featured" -> o.featuredId,
|
||||||
"spotlight" -> o.spotlight,
|
"spotlight" -> o.spotlight,
|
||||||
"description" -> o.description
|
"description" -> o.description,
|
||||||
|
"chat" -> (!o.hasChat).option(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ final class DataForm {
|
||||||
conditions = Condition.DataForm.AllSetup.default,
|
conditions = Condition.DataForm.AllSetup.default,
|
||||||
teamBattleByTeam = teamBattleId,
|
teamBattleByTeam = teamBattleId,
|
||||||
berserkable = true.some,
|
berserkable = true.some,
|
||||||
description = none
|
description = none,
|
||||||
|
hasChat = true.some
|
||||||
)
|
)
|
||||||
|
|
||||||
def edit(user: User, tour: Tournament) = form(user) fill TournamentSetup(
|
def edit(user: User, tour: Tournament) = form(user) fill TournamentSetup(
|
||||||
|
@ -49,7 +50,8 @@ final class DataForm {
|
||||||
conditions = Condition.DataForm.AllSetup(tour.conditions),
|
conditions = Condition.DataForm.AllSetup(tour.conditions),
|
||||||
teamBattleByTeam = none,
|
teamBattleByTeam = none,
|
||||||
berserkable = tour.berserkable.some,
|
berserkable = tour.berserkable.some,
|
||||||
description = tour.description
|
description = tour.description,
|
||||||
|
hasChat = tour.hasChat.some
|
||||||
)
|
)
|
||||||
|
|
||||||
private val nameType = text.verifying(
|
private val nameType = text.verifying(
|
||||||
|
@ -85,7 +87,8 @@ final class DataForm {
|
||||||
"conditions" -> Condition.DataForm.all,
|
"conditions" -> Condition.DataForm.all,
|
||||||
"teamBattleByTeam" -> optional(nonEmptyText),
|
"teamBattleByTeam" -> optional(nonEmptyText),
|
||||||
"berserkable" -> optional(boolean),
|
"berserkable" -> optional(boolean),
|
||||||
"description" -> optional(nonEmptyText)
|
"description" -> optional(nonEmptyText),
|
||||||
|
"hasChat" -> optional(boolean)
|
||||||
)(TournamentSetup.apply)(TournamentSetup.unapply)
|
)(TournamentSetup.apply)(TournamentSetup.unapply)
|
||||||
.verifying("Invalid clock", _.validClock)
|
.verifying("Invalid clock", _.validClock)
|
||||||
.verifying("15s variant games cannot be rated", _.validRatedUltraBulletVariant)
|
.verifying("15s variant games cannot be rated", _.validRatedUltraBulletVariant)
|
||||||
|
@ -152,7 +155,8 @@ private[tournament] case class TournamentSetup(
|
||||||
conditions: Condition.DataForm.AllSetup,
|
conditions: Condition.DataForm.AllSetup,
|
||||||
teamBattleByTeam: Option[String],
|
teamBattleByTeam: Option[String],
|
||||||
berserkable: Option[Boolean],
|
berserkable: Option[Boolean],
|
||||||
description: Option[String]
|
description: Option[String],
|
||||||
|
hasChat: Option[Boolean]
|
||||||
) {
|
) {
|
||||||
|
|
||||||
def validClock = (clockTime + clockIncrement) > 0
|
def validClock = (clockTime + clockIncrement) > 0
|
||||||
|
|
|
@ -32,7 +32,8 @@ case class Tournament(
|
||||||
winnerId: Option[User.ID] = None,
|
winnerId: Option[User.ID] = None,
|
||||||
featuredId: Option[String] = None,
|
featuredId: Option[String] = None,
|
||||||
spotlight: Option[Spotlight] = None,
|
spotlight: Option[Spotlight] = None,
|
||||||
description: Option[String] = None
|
description: Option[String] = None,
|
||||||
|
hasChat: Boolean = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
def isCreated = status == Status.Created
|
def isCreated = status == Status.Created
|
||||||
|
@ -151,7 +152,8 @@ object Tournament {
|
||||||
startDate: Option[DateTime],
|
startDate: Option[DateTime],
|
||||||
berserkable: Boolean,
|
berserkable: Boolean,
|
||||||
teamBattle: Option[TeamBattle],
|
teamBattle: Option[TeamBattle],
|
||||||
description: Option[String]
|
description: Option[String],
|
||||||
|
hasChat: Boolean
|
||||||
) = Tournament(
|
) = Tournament(
|
||||||
id = makeId,
|
id = makeId,
|
||||||
name = name | {
|
name = name | {
|
||||||
|
@ -176,7 +178,8 @@ object Tournament {
|
||||||
case Some(startDate) => startDate plusSeconds scala.util.Random.nextInt(60)
|
case Some(startDate) => startDate plusSeconds scala.util.Random.nextInt(60)
|
||||||
case None => DateTime.now plusMinutes waitMinutes
|
case None => DateTime.now plusMinutes waitMinutes
|
||||||
},
|
},
|
||||||
description = description
|
description = description,
|
||||||
|
hasChat = hasChat
|
||||||
)
|
)
|
||||||
|
|
||||||
def scheduleAs(sched: Schedule, minutes: Int) = Tournament(
|
def scheduleAs(sched: Schedule, minutes: Int) = Tournament(
|
||||||
|
|
|
@ -74,7 +74,8 @@ final class TournamentApi(
|
||||||
DataForm.startingPosition(setup.position | chess.StartingPosition.initial.fen, setup.realVariant),
|
DataForm.startingPosition(setup.position | chess.StartingPosition.initial.fen, setup.realVariant),
|
||||||
berserkable = setup.berserkable | true,
|
berserkable = setup.berserkable | true,
|
||||||
teamBattle = setup.teamBattleByTeam map TeamBattle.init,
|
teamBattle = setup.teamBattleByTeam map TeamBattle.init,
|
||||||
description = setup.description
|
description = setup.description,
|
||||||
|
hasChat = setup.hasChat | true
|
||||||
) |> { tour =>
|
) |> { tour =>
|
||||||
tour.perfType.fold(tour) { perfType =>
|
tour.perfType.fold(tour) { perfType =>
|
||||||
tour.copy(conditions = setup.conditions.convert(perfType, myTeams.view.map(_.pair).toMap))
|
tour.copy(conditions = setup.conditions.convert(perfType, myTeams.view.map(_.pair).toMap))
|
||||||
|
@ -97,7 +98,8 @@ final class TournamentApi(
|
||||||
position = DataForm.startingPosition(position | chess.StartingPosition.initial.fen, realVariant),
|
position = DataForm.startingPosition(position | chess.StartingPosition.initial.fen, realVariant),
|
||||||
noBerserk = !(~berserkable),
|
noBerserk = !(~berserkable),
|
||||||
teamBattle = old.teamBattle,
|
teamBattle = old.teamBattle,
|
||||||
description = description
|
description = description,
|
||||||
|
hasChat = data.hasChat | true
|
||||||
) |> { tour =>
|
) |> { tour =>
|
||||||
tour.perfType.fold(tour) { perfType =>
|
tour.perfType.fold(tour) { perfType =>
|
||||||
tour.copy(conditions = conditions.convert(perfType, myTeams.view.map(_.pair).toMap))
|
tour.copy(conditions = conditions.convert(perfType, myTeams.view.map(_.pair).toMap))
|
||||||
|
|
|
@ -27,9 +27,8 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(
|
||||||
private def variantSelect(variant: Variant) =
|
private def variantSelect(variant: Variant) =
|
||||||
if (variant.standard) $doc("variant" $exists false)
|
if (variant.standard) $doc("variant" $exists false)
|
||||||
else $doc("variant" -> variant.id)
|
else $doc("variant" -> variant.id)
|
||||||
private val nonEmptySelect = $doc("nbPlayers" $ne 0)
|
private val nonEmptySelect = $doc("nbPlayers" $ne 0)
|
||||||
private def hasPlayersSelect(nb: Int) = $doc("nbPlayers" $gte nb)
|
private[tournament] val selectUnique = $doc("schedule.freq" -> "unique")
|
||||||
private[tournament] val selectUnique = $doc("schedule.freq" -> "unique")
|
|
||||||
|
|
||||||
def byId(id: Tournament.ID): Fu[Option[Tournament]] = coll.byId[Tournament](id)
|
def byId(id: Tournament.ID): Fu[Option[Tournament]] = coll.byId[Tournament](id)
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,8 @@ final class CrudApi(tournamentRepo: TournamentRepo) {
|
||||||
startDate = none,
|
startDate = none,
|
||||||
berserkable = true,
|
berserkable = true,
|
||||||
teamBattle = none,
|
teamBattle = none,
|
||||||
description = none
|
description = none,
|
||||||
|
hasChat = true
|
||||||
)
|
)
|
||||||
|
|
||||||
private def updateTour(tour: Tournament, data: CrudForm.Data) = {
|
private def updateTour(tour: Tournament, data: CrudForm.Data) = {
|
||||||
|
|
Loading…
Reference in a new issue