Skip to content

Commit

Permalink
Merge branch 'master' into attempt-1-flipped-chapter-edit
Browse files Browse the repository at this point in the history
  • Loading branch information
johndoknjas committed Nov 8, 2024
2 parents b8b5f99 + b3ff380 commit ea7fd74
Show file tree
Hide file tree
Showing 17 changed files with 202 additions and 64 deletions.
5 changes: 2 additions & 3 deletions app/controllers/RelayRound.scala
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,8 @@ final class RelayRound(
group <- env.relay.api.withTours.get(rt.tour.id)
previews <- env.study.preview.jsonList.withoutInitialEmpty(study.id)
targetRound <- env.relay.api.officialTarget(rt.round)
yield JsonOk(
yield JsonOk:
env.relay.jsonView.withUrlAndPreviews(rt.withStudy(study), previews, group, targetRound)
)
)(studyC.privateUnauthorizedJson, studyC.privateForbiddenJson)

def pgn(ts: String, rs: String, id: RelayRoundId) = Open:
Expand Down Expand Up @@ -257,7 +256,7 @@ final class RelayRound(
)(using ctx: Context): Fu[Result] =
WithTour(id): tour =>
ctx.me
.soUse { env.relay.api.canUpdate(tour) }
.soUse(env.relay.api.canUpdate(tour))
.elseNotFound:
env.relay.api.formNavigation(tour).flatMap(f)

Expand Down
6 changes: 6 additions & 0 deletions bin/mongodb/indexes.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,9 @@ db.study_chapter_flat.createIndex(
);
db.title_request.createIndex({ userId: 1 });
db.title_request.createIndex({ 'history.0.status.n': 1, 'history.0.at': 1 });

// you may want to run these on the insight database
// if it's a different one
db.insight.createIndex({ mr: 1, p: 1, c: 1 });
db.insight.createIndex({ mr: 1, a: 1 }, { partialFilterExpression: { mr: { $exists: true } } });
db.insight.createIndex({ u: 1, d: -1 });
3 changes: 2 additions & 1 deletion modules/core/src/main/game/misc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ enum Source(val id: Int) derives Eq:
case Arena extends Source(id = 5)
case Position extends Source(id = 6)
case Import extends Source(id = 7)
case ImportLive extends Source(id = 9)
case ImportLive extends Source(id = 9) // wut?
case Simul extends Source(id = 10)
case Pool extends Source(id = 12)
case Swiss extends Source(id = 13)

object Source:
val byId = values.mapBy(_.id)
val byName = values.mapBy(_.name)
val searchable = List(Lobby, Friend, Ai, Position, Arena, Simul, Pool, Swiss)
val expirable = Set(Lobby, Arena, Pool, Swiss)
def apply(id: Int): Option[Source] = byId.get(id)
Expand Down
10 changes: 6 additions & 4 deletions modules/game/src/main/BSONHandlers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ object BSONHandlers:

given BSONHandler[GameRule] = valueMapHandler[String, GameRule](GameRule.byKey)(_.toString)

given sourceHandler: BSONHandler[Source] = valueMapHandler[Int, Source](Source.byId)(_.id)

private[game] given crazyhouseDataHandler: BSON[Crazyhouse.Data] with
import Crazyhouse.*
def reads(r: BSON.Reader) =
Expand Down Expand Up @@ -191,7 +193,7 @@ object BSONHandlers:
createdAt = createdAt,
movedAt = r.dateD(F.movedAt, createdAt),
metadata = GameMetadata(
source = r.intO(F.source).flatMap(Source.apply),
source = r.getO[Source](F.source),
pgnImport = r.getO[PgnImport](F.pgnImport),
tournamentId = r.getO[TourId](F.tournamentId),
swissId = r.getO[SwissId](F.swissId),
Expand Down Expand Up @@ -219,9 +221,9 @@ object BSONHandlers:
F.status -> o.status,
F.turns -> o.chess.ply,
F.startedAtTurn -> w.intO(o.chess.startedAtPly.value),
F.clock -> (o.chess.clock.flatMap { c =>
F.clock -> o.chess.clock.flatMap { c =>
clockBSONWrite(o.createdAt, c).toOption
}),
},
F.daysPerTurn -> o.daysPerTurn,
F.moveTimes -> o.binaryMoveTimes,
F.whiteClockHistory -> clockHistory(Color.White, o.clockHistory, o.chess.clock, o.flagged),
Expand All @@ -231,7 +233,7 @@ object BSONHandlers:
F.bookmarks -> w.intO(o.bookmarks),
F.createdAt -> w.date(o.createdAt),
F.movedAt -> w.date(o.movedAt),
F.source -> o.metadata.source.map(_.id),
F.source -> o.metadata.source,
F.pgnImport -> o.metadata.pgnImport,
F.tournamentId -> o.metadata.tournamentId,
F.swissId -> o.metadata.swissId,
Expand Down
4 changes: 4 additions & 0 deletions modules/insight/src/main/BSONHandlers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import lila.db.BSON
import lila.db.dsl.{ *, given }
import lila.rating.BSONHandlers.perfTypeIdHandler
import lila.rating.PerfType
import lila.core.game.Source
import lila.game.BSONHandlers.sourceHandler

object BSONHandlers:

Expand Down Expand Up @@ -102,6 +104,7 @@ object BSONHandlers:
ratingDiff = r.get[IntRatingDiff](ratingDiff),
analysed = r.boolD(analysed),
provisional = r.boolD(provisional),
source = r.getO[Source](source),
date = r.date(date)
)
def writes(w: BSON.Writer, e: InsightEntry) =
Expand All @@ -124,5 +127,6 @@ object BSONHandlers:
ratingDiff -> e.ratingDiff,
analysed -> w.boolO(e.analysed),
provisional -> w.boolO(e.provisional),
source -> e.source,
date -> e.date
)
22 changes: 20 additions & 2 deletions modules/insight/src/main/InsightDimension.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import lila.db.dsl.{ *, given }
import lila.insight.BSONHandlers.given
import lila.insight.InsightEntry.BSONFields as F
import lila.rating.BSONHandlers.perfTypeIdHandler
import lila.game.BSONHandlers.sourceHandler
import lila.rating.PerfType
import lila.core.game.Source

enum InsightDimension[A](
val key: String,
Expand Down Expand Up @@ -231,6 +233,15 @@ enum InsightDimension[A](
"Time left on the player clock, accounting for increment. 100% = full clock, 0% = flagging."
)

case GameSource
extends InsightDimension[Source](
"source",
"Game source",
F.source,
InsightPosition.Game,
"How the game was created."
)

object InsightDimension:

def requiresStableRating(d: InsightDimension[?]) = d match
Expand Down Expand Up @@ -260,6 +271,10 @@ object InsightDimension:
case ClockPercentRange => lila.insight.ClockPercentRange.all.toList
case Blur => lila.insight.Blur.values.toIndexedSeq
case TimeVariance => lila.insight.TimeVariance.values.toIndexedSeq
case GameSource =>
Source.values.toIndexedSeq.filter:
case Source.Ai | Source.Import | Source.ImportLive => false
case _ => true

def valueByKey[X](d: InsightDimension[X], key: String): Option[X] = d match
case Period => key.toIntOption.map(lila.insight.Period.apply)
Expand All @@ -284,6 +299,7 @@ object InsightDimension:
case ClockPercentRange => key.toIntOption.flatMap(lila.insight.ClockPercentRange.byPercent.get)
case Blur => lila.insight.Blur(key == "true").some
case TimeVariance => key.toFloatOption.map(lila.insight.TimeVariance.byId)
case GameSource => Source.byName.get(key)

def valueToJson[X](d: InsightDimension[X])(v: X)(using Translate): JsObject =
Json.obj(
Expand All @@ -292,7 +308,7 @@ object InsightDimension:
)

def valueKey[X](d: InsightDimension[X])(v: X): String =
(d match
d.match
case Date => v.toString
case Period => v.days.toString
case Perf => v.key
Expand All @@ -315,7 +331,8 @@ object InsightDimension:
case ClockPercentRange => v.bottom.toInt
case Blur => v.id
case TimeVariance => v.id
).toString
case GameSource => v.name
.toString

def valueJson[X](d: InsightDimension[X])(v: X)(using Translate): JsValue =
d match
Expand All @@ -341,6 +358,7 @@ object InsightDimension:
case ClockPercentRange => JsString(v.name)
case Blur => JsString(v.name)
case TimeVariance => JsString(v.name)
case GameSource => JsString(v.toString)

def filtersOf[X](d: InsightDimension[X], selected: List[X]): Bdoc =

Expand Down
3 changes: 3 additions & 0 deletions modules/insight/src/main/InsightEntry.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lila.insight

import lila.common.SimpleOpening
import lila.core.game.Source

case class InsightEntry(
id: String, // gameId + w/b
Expand All @@ -20,6 +21,7 @@ case class InsightEntry(
ratingDiff: IntRatingDiff,
analysed: Boolean,
provisional: Boolean,
source: Option[Source],
date: Instant
)

Expand Down Expand Up @@ -48,4 +50,5 @@ case object InsightEntry:
val ratingDiff = "rd"
val analysed = "a"
val provisional = "pr"
val source = "so"
val date = "d"
40 changes: 17 additions & 23 deletions modules/insight/src/main/InsightIndexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ final private class InsightIndexer(
)

def all(user: User): Funit =
workQueue {
storage.fetchLast(user.id).flatMap {
_.fold(fromScratch(user)) { e =>
computeFrom(user, e.date.plusSeconds(1))
}
}
}
workQueue:
storage
.fetchLast(user.id)
.flatMap:
_.fold(fromScratch(user)): e =>
computeFrom(user, e.date.plusSeconds(1))

def update(game: Game, userId: UserId, previous: InsightEntry): Funit =
povToEntry(game, userId, previous.provisional).flatMap {
Expand All @@ -39,11 +38,8 @@ final private class InsightIndexer(
}

private def fromScratch(user: User): Funit =
fetchFirstGame(user).flatMap {
_.so { g =>
computeFrom(user, g.createdAt)
}
}
fetchFirstGame(user).flatMapz: g =>
computeFrom(user, g.createdAt)

private def gameQuery(user: User) =
Query.user(user.id) ++
Expand All @@ -58,25 +54,23 @@ final private class InsightIndexer(
private def fetchFirstGame(user: User): Fu[Option[Game]] =
if user.count.rated == 0 then fuccess(none)
else
{
(user.count.rated >= maxGames).so(
(user.count.rated >= maxGames)
.so:
gameRepo.coll
.find(gameQuery(user))
.sort(Query.sortCreated)
.skip(maxGames - 1)
.one[Game](ReadPref.sec)
)
}.orElse(
gameRepo.coll
.find(gameQuery(user))
.sort(Query.sortChronological)
.one[Game](ReadPref.sec)
)
.orElse:
gameRepo.coll
.find(gameQuery(user))
.sort(Query.sortChronological)
.one[Game](ReadPref.sec)

private def computeFrom(user: User, from: Instant): Funit =
storage
.nbByPerf(user.id)
.flatMap { nbs =>
.flatMap: nbs =>
var nbByPerf = nbs
def toEntry(game: Game): Fu[Option[InsightEntry]] =
val nb = nbByPerf.getOrElse(game.perfKey, 0) + 1
Expand All @@ -94,4 +88,4 @@ final private class InsightIndexer(
.grouped(100.atMost(maxGames))
.map(storage.bulkInsert)
.runWith(Sink.ignore)
} void
.void
2 changes: 2 additions & 0 deletions modules/insight/src/main/JsonQuestion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ case class JsonQuestion(
case ClockPercentRange.key => build(ClockPercentRange)
case Blur.key => build(Blur)
case TimeVariance.key => build(TimeVariance)
case GameSource.key => build(GameSource)
case _ => none
}
.filterNot(_.isEmpty)
Expand Down Expand Up @@ -75,6 +76,7 @@ case class JsonQuestion(
case AccuracyPercentRange.key => build(AccuracyPercentRange)
case Blur.key => build(Blur)
case TimeVariance.key => build(TimeVariance)
case GameSource.key => build(GameSource)
case _ => none
yield question

Expand Down
3 changes: 2 additions & 1 deletion modules/insight/src/main/JsonView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ final class JsonView:
dimWrites.writes(D.Period),
dimWrites.writes(D.Perf),
dimWrites.writes(D.Color),
dimWrites.writes(D.OpponentStrength)
dimWrites.writes(D.OpponentStrength),
dimWrites.writes(D.GameSource)
)
),
Categ(
Expand Down
1 change: 1 addition & 0 deletions modules/insight/src/main/PovToEntry.scala
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ final private class PovToEntry(
ratingDiff = ~pov.player.ratingDiff,
analysed = analysis.isDefined,
provisional = provisional,
source = game.source,
date = game.createdAt
)

Expand Down
20 changes: 12 additions & 8 deletions ui/analyse/css/study/relay/_embed.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ body {
@media (min-width: at-least($small)) {
---main-margin: 1vw;
---block-gap: 15px;
overflow-y: hidden;
}

overflow-y: hidden;
}

/* game view */
Expand All @@ -29,15 +28,20 @@ main.analyse.is-relay:not(.has-relay-tour) {
'board gauge side'
'board gauge tools'
'board . controls';
.main-board {
/* space for the top player bar */
margin-top: calc((100vh - var(---col2-uniboard-width)) / 2);
}
}

.main-board {
/* space for the top player bar */
margin-top: calc((100vh - var(---col2-uniboard-width)) / 2);
cg-resize {
display: none;
@include mq-is-col1 {
.main-board {
/* space for the top player bar */
margin-top: $player-height;
}
}
cg-resize {
display: none;
}
.analyse__controls .features {
flex: 0 0 2.5rem;
}
Expand Down
Loading

0 comments on commit ea7fd74

Please sign in to comment.