broadcast tier system - MIGRATION NEEDED - closes #9938

pull/9941/head
Thibault Duplessis 2021-10-07 10:09:02 +02:00
parent 4f48e2bd1c
commit b123acf9bc
8 changed files with 71 additions and 19 deletions

View File

@ -35,7 +35,7 @@ object tour {
),
st.section(
active.map { tr =>
div(cls := "relay-widget relay-widget--active", dataIcon := "")(
div(cls := s"relay-widget relay-widget--active ${tierClass(tr.tour)}", dataIcon := "")(
a(cls := "overlay", href := tr.path),
div(
h2(tr.tour.name),
@ -54,7 +54,7 @@ object tour {
),
st.section(cls := "infinite-scroll")(
pager.currentPageResults map { rt =>
div(cls := "relay-widget paginated", dataIcon := "")(
div(cls := s"relay-widget ${tierClass(rt.tour)} paginated", dataIcon := "")(
a(cls := "overlay", href := rt.path),
div(
h2(rt.tour.name),
@ -70,4 +70,5 @@ object tour {
)
}
private def tierClass(tour: RelayTour) = s"tour-tier--${tour.tier | RelayTour.Tier.NORMAL}"
}

View File

@ -62,11 +62,11 @@ object tourForm {
).some
)(form3.textarea(_)(rows := 10)),
if (isGranted(_.Relay))
form3.checkbox(
form("official"),
raw("Official Lichess broadcast"),
form3.group(
form("tier"),
raw("Official Lichess broadcast tier"),
help = raw("Feature on /broadcast - for admins only").some
)
else form3.hidden(form("official"))
)(form3.select(_, RelayTour.Tier.options))
else form3.hidden(form("tier"))
)
}

View File

@ -0,0 +1,7 @@
db.relay_tour.update({ official: true }, { $set: { tier: NumberInt(3) }, $unset: { official: true } }, { multi: 1 });
db.relay_tour.dropIndex('active_1_official_1_syncedAt_-1');
db.relay_tour.createIndex(
{ active: 1, tier: 1 },
{ partialFilterExpression: { active: true, tier: { $exists: true } } }
);
db.relay_tour.createIndex({ syncedAt: -1 }, { partialFilterExpression: { tier: { $exists: true } } });

View File

@ -85,6 +85,7 @@ final class RelayApi(
.aggregateList(20) { framework =>
import framework._
Match(tourRepo.selectors.official ++ tourRepo.selectors.active) -> List(
Sort(Descending("tier")),
PipelineOperator(
$doc(
"$lookup" -> $doc(

View File

@ -11,9 +11,9 @@ case class RelayTour(
markup: Option[String] = None,
ownerId: User.ID,
createdAt: DateTime,
official: Boolean,
active: Boolean, // a round is scheduled or ongoing
syncedAt: Option[DateTime] // last time a round was synced
tier: Option[RelayTour.Tier], // if present, it's an official broadcast
active: Boolean, // a round is scheduled or ongoing
syncedAt: Option[DateTime] // last time a round was synced
) {
def id = _id
@ -23,6 +23,8 @@ case class RelayTour(
}
def withRounds(rounds: List[RelayRound]) = RelayTour.WithRounds(this, rounds)
def official = tier.isDefined
}
object RelayTour {
@ -31,6 +33,23 @@ object RelayTour {
case class Id(value: String) extends AnyVal with StringValue
type Tier = Int
object Tier {
val NORMAL = 3
val HIGH = 4
val BEST = 5
val options = List(
"" -> "Non official",
NORMAL.toString -> "Official: normal tier",
HIGH.toString -> "Official: high tier",
BEST.toString -> "Official: best tier"
)
def name(tier: Tier) = options.collectFirst {
case (t, n) if t == tier => n
} | "???"
}
case class WithRounds(tour: RelayTour, rounds: List[RelayRound])
case class ActiveWithNextRound(tour: RelayTour, round: RelayRound) extends RelayRound.AndTour {

View File

@ -21,7 +21,7 @@ final class RelayTourForm {
"name" -> cleanText(minLength = 3, maxLength = 80),
"description" -> cleanText(minLength = 3, maxLength = 400),
"markup" -> optional(cleanText(maxLength = 20_000)),
"official" -> optional(boolean)
"tier" -> optional(number(min = RelayTour.Tier.NORMAL, max = RelayTour.Tier.BEST))
)(Data.apply)(Data.unapply)
)
@ -36,7 +36,7 @@ object RelayTourForm {
name: String,
description: String,
markup: Option[String],
official: Option[Boolean]
tier: Option[RelayTour.Tier]
) {
def update(tour: RelayTour, user: User) =
@ -44,7 +44,7 @@ object RelayTourForm {
name = name,
description = description,
markup = markup,
official = ~official && Granter(_.Relay)(user)
tier = tier ifTrue Granter(_.Relay)(user)
)
def make(user: User) =
@ -54,7 +54,7 @@ object RelayTourForm {
description = description,
markup = markup,
ownerId = user.id,
official = ~official && Granter(_.Relay)(user),
tier = tier ifTrue Granter(_.Relay)(user),
active = false,
createdAt = DateTime.now,
syncedAt = none
@ -68,7 +68,7 @@ object RelayTourForm {
name = tour.name,
description = tour.description,
markup = tour.markup,
official = tour.official option true
tier = tour.tier
)
}
}

View File

@ -19,7 +19,7 @@ final private class RelayTourRepo(val coll: Coll)(implicit ec: scala.concurrent.
def lookup(local: String) = $lookup.simple(coll, "tour", local, "_id")
private[relay] object selectors {
val official = $doc("official" -> true)
val official = $doc("tier" $exists true)
val active = $doc("active" -> true)
val inactive = $doc("active" -> false)
}

View File

@ -2,7 +2,7 @@
@extend %flex-center-nowrap, %break-word;
border-bottom: $border;
padding: 2em var(--box-padding);
padding: 2em var(--box-padding) 2em 0;
position: relative;
@include transition;
@ -10,13 +10,19 @@
&::before {
color: $c-font-dimmer;
font-size: 5em;
margin-right: 0.4em;
width: 12rem;
text-align: center;
@include transition;
@include breakpoint($mq-not-xx-small) {
}
@include breakpoint($mq-not-xx-small) {
&::before {
display: none;
}
padding-left: var(--box-padding);
}
&--active::before {
color: mix($c-link, $c-bg-box, 80%);
}
@ -55,4 +61,22 @@
text-align: right;
}
}
&.tour-tier {
&--3 {
&::before {
font-size: 3.5em;
}
h2 {
@include fluid-size('font-size', 13px, 23px);
}
}
&--5 {
@extend %box-neat;
border: 3px solid $c-border;
&.relay-widget--active {
border-color: $c-primary;
}
}
}
}