Merge branch 'master' into stripe-api-version
* master: add ModNote permission to Shusher package fix impersonation of the lichess user dark board 3d refactor event name form, allow single quotes fix swiss faq style fix compile error {master} ignore more streamer image upload exceptions {master} help timeago with layout reflow {master} tweak scalatags {master} improve captcha help url uianalysestripe-api-version
commit
8af5dd1152
|
@ -156,7 +156,7 @@ final class Mod(
|
||||||
env.mod.impersonate.stop(me)
|
env.mod.impersonate.stop(me)
|
||||||
Redirect(routes.User.show(me.username))
|
Redirect(routes.User.show(me.username))
|
||||||
}
|
}
|
||||||
else if (isGranted(_.Impersonate) || (isGranted(_.Admin) && username == "lichess"))
|
else if (isGranted(_.Impersonate) || (isGranted(_.Admin) && username.toLowerCase == "lichess"))
|
||||||
OptionFuRedirect(env.user.repo named username) { user =>
|
OptionFuRedirect(env.user.repo named username) { user =>
|
||||||
env.mod.impersonate.start(me, user)
|
env.mod.impersonate.start(me, user)
|
||||||
fuccess(routes.User.show(user.username))
|
fuccess(routes.User.show(user.username))
|
||||||
|
|
|
@ -137,7 +137,7 @@ final class Streamer(
|
||||||
ctx.body.body.file("picture") match {
|
ctx.body.body.file("picture") match {
|
||||||
case Some(pic) =>
|
case Some(pic) =>
|
||||||
api.uploadPicture(s.streamer, pic) recover { case e: Exception =>
|
api.uploadPicture(s.streamer, pic) recover { case e: Exception =>
|
||||||
BadRequest(html.streamer.picture(s, e.message.some))
|
BadRequest(html.streamer.picture(s, e.getMessage.some))
|
||||||
} inject Redirect(routes.Streamer.edit())
|
} inject Redirect(routes.Streamer.edit())
|
||||||
case None => fuccess(Redirect(routes.Streamer.edit()))
|
case None => fuccess(Redirect(routes.Streamer.edit()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import play.api.data.format.Formats._
|
||||||
import play.api.data.format.{ Formatter, JodaFormats }
|
import play.api.data.format.{ Formatter, JodaFormats }
|
||||||
import play.api.data.Forms._
|
import play.api.data.Forms._
|
||||||
import play.api.data.JodaForms._
|
import play.api.data.JodaForms._
|
||||||
import play.api.data.validation.Constraint
|
import play.api.data.validation.{ Constraint, Constraints }
|
||||||
import play.api.data.{ Field, FormError, Mapping }
|
import play.api.data.{ Field, FormError, Mapping }
|
||||||
import scala.util.Try
|
import scala.util.Try
|
||||||
|
|
||||||
|
@ -60,6 +60,16 @@ object Form {
|
||||||
trim(m)
|
trim(m)
|
||||||
.verifying("This text contains invalid chars", s => !String.hasZeroWidthChars(s))
|
.verifying("This text contains invalid chars", s => !String.hasZeroWidthChars(s))
|
||||||
|
|
||||||
|
def eventName(minLength: Int, maxLength: Int) =
|
||||||
|
clean(text).verifying(
|
||||||
|
Constraints minLength minLength,
|
||||||
|
Constraints maxLength maxLength,
|
||||||
|
Constraints.pattern(
|
||||||
|
regex = """[\p{L}\p{N}-\s:,;'\+]+""".r,
|
||||||
|
error = "Invalid characters"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def stringIn(choices: Options[String]) =
|
def stringIn(choices: Options[String]) =
|
||||||
text.verifying(hasKey(choices, _))
|
text.verifying(hasKey(choices, _))
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,8 @@ object Permission {
|
||||||
ReportBan,
|
ReportBan,
|
||||||
ModMessage,
|
ModMessage,
|
||||||
SeeReport,
|
SeeReport,
|
||||||
ModLog
|
ModLog,
|
||||||
|
ModNote
|
||||||
),
|
),
|
||||||
"Shusher"
|
"Shusher"
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,13 +32,7 @@ object SimulForm {
|
||||||
val colorDefault = "white"
|
val colorDefault = "white"
|
||||||
|
|
||||||
private def nameType(host: User) =
|
private def nameType(host: User) =
|
||||||
clean(text).verifying(
|
eventName(2, 40).verifying(
|
||||||
Constraints minLength 2,
|
|
||||||
Constraints maxLength 40,
|
|
||||||
Constraints.pattern(
|
|
||||||
regex = """[\p{L}\p{N}-\s:,;]+""".r,
|
|
||||||
error = "error.unknown"
|
|
||||||
),
|
|
||||||
Constraint[String] { (t: String) =>
|
Constraint[String] { (t: String) =>
|
||||||
if (t.toLowerCase contains "lichess")
|
if (t.toLowerCase contains "lichess")
|
||||||
validation.Invalid(validation.ValidationError("Must not contain \"lichess\""))
|
validation.Invalid(validation.ValidationError("Must not contain \"lichess\""))
|
||||||
|
|
|
@ -5,7 +5,6 @@ import chess.variant.Variant
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import play.api.data._
|
import play.api.data._
|
||||||
import play.api.data.Forms._
|
import play.api.data.Forms._
|
||||||
import play.api.data.validation.Constraints
|
|
||||||
import play.api.Mode
|
import play.api.Mode
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
@ -18,16 +17,7 @@ final class SwissForm(implicit mode: Mode) {
|
||||||
def form(minRounds: Int = 3) =
|
def form(minRounds: Int = 3) =
|
||||||
Form(
|
Form(
|
||||||
mapping(
|
mapping(
|
||||||
"name" -> optional(
|
"name" -> optional(eventName(2, 3)),
|
||||||
clean(text).verifying(
|
|
||||||
Constraints minLength 2,
|
|
||||||
Constraints maxLength 30,
|
|
||||||
Constraints.pattern(
|
|
||||||
regex = """[\p{L}\p{N}-\s:,;\+]+""".r,
|
|
||||||
error = "Invalid characters"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
"clock" -> mapping(
|
"clock" -> mapping(
|
||||||
"limit" -> number.verifying(clockLimits.contains _),
|
"limit" -> number.verifying(clockLimits.contains _),
|
||||||
"increment" -> number(min = 0, max = 600)
|
"increment" -> number(min = 0, max = 600)
|
||||||
|
|
|
@ -59,13 +59,7 @@ final class TournamentForm {
|
||||||
hasChat = tour.hasChat.some
|
hasChat = tour.hasChat.some
|
||||||
)
|
)
|
||||||
|
|
||||||
private def nameType(user: User) = clean(text).verifying(
|
private def nameType(user: User) = eventName(2, 30).verifying(
|
||||||
Constraints minLength 2,
|
|
||||||
Constraints maxLength 30,
|
|
||||||
Constraints.pattern(
|
|
||||||
regex = """[\p{L}\p{N}-\s:,;]+""".r,
|
|
||||||
error = "error.unknown"
|
|
||||||
),
|
|
||||||
Constraint[String] { (t: String) =>
|
Constraint[String] { (t: String) =>
|
||||||
if (t.toLowerCase.contains("lichess") && !user.isVerified && !user.isAdmin)
|
if (t.toLowerCase.contains("lichess") && !user.isVerified && !user.isAdmin)
|
||||||
validation.Invalid(validation.ValidationError("Must not contain \"lichess\""))
|
validation.Invalid(validation.ValidationError("Must not contain \"lichess\""))
|
||||||
|
|
|
@ -272,6 +272,10 @@ declare namespace Tree {
|
||||||
cp?: number;
|
cp?: number;
|
||||||
mate?: number;
|
mate?: number;
|
||||||
best?: Uci;
|
best?: Uci;
|
||||||
|
fen: Fen;
|
||||||
|
knodes: number;
|
||||||
|
depth: number;
|
||||||
|
pvs: PvData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PvData {
|
export interface PvData {
|
||||||
|
|
|
@ -20,7 +20,7 @@ const evalPutMinDepth = 20;
|
||||||
const evalPutMinNodes = 3e6;
|
const evalPutMinNodes = 3e6;
|
||||||
const evalPutMaxMoves = 10;
|
const evalPutMaxMoves = 10;
|
||||||
|
|
||||||
function qualityCheck(ev): boolean {
|
function qualityCheck(ev: Tree.ClientEval): boolean {
|
||||||
// below 500k nodes, the eval might come from an imminent threefold repetition
|
// below 500k nodes, the eval might come from an imminent threefold repetition
|
||||||
// and should therefore be ignored
|
// and should therefore be ignored
|
||||||
return ev.nodes > 500000 && (
|
return ev.nodes > 500000 && (
|
||||||
|
@ -29,7 +29,7 @@ function qualityCheck(ev): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
// from client eval to server eval
|
// from client eval to server eval
|
||||||
function toPutData(variant: VariantKey, ev) {
|
function toPutData(variant: VariantKey, ev: Tree.ClientEval) {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
fen: ev.fen,
|
fen: ev.fen,
|
||||||
knodes: Math.round(ev.nodes / 1000),
|
knodes: Math.round(ev.nodes / 1000),
|
||||||
|
@ -47,7 +47,7 @@ function toPutData(variant: VariantKey, ev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// from server eval to client eval
|
// from server eval to client eval
|
||||||
function toCeval(e) {
|
function toCeval(e: Tree.ServerEval) {
|
||||||
const res: any = {
|
const res: any = {
|
||||||
fen: e.fen,
|
fen: e.fen,
|
||||||
nodes: e.knodes * 1000,
|
nodes: e.knodes * 1000,
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
body.dark-board {
|
body.dark-board {
|
||||||
--dark-factor: 0.4;
|
--dark-factor: 0.4;
|
||||||
|
|
||||||
cg-board {
|
cg-board,
|
||||||
|
.is3d cg-board::before {
|
||||||
background-color: rgba(0, 0, 0, var(--dark-factor));
|
background-color: rgba(0, 0, 0, var(--dark-factor));
|
||||||
background-blend-mode: darken;
|
background-blend-mode: darken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,20 @@
|
||||||
color: $c-brag;
|
color: $c-brag;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.faq strong {
|
#faq {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: .4em;
|
|
||||||
|
.faq {
|
||||||
|
@extend %flex-center-nowrap;
|
||||||
|
|
||||||
|
margin-bottom: 4em;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: .4em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue