Skip to content

Commit

Permalink
dasher refactor and board theme improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
schlawg committed Apr 15, 2024
1 parent 7dae93d commit 27e2937
Show file tree
Hide file tree
Showing 1,327 changed files with 5,580 additions and 6,024 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
id: ab
- run: pnpm link "$GITHUB_WORKSPACE/ab"
if: steps.ab.outcome == 'success'
- run: ./ui/build --no-install -ps
- run: ./ui/build --no-install -p
- run: cd ui && pnpm run test && cd -
- run: mkdir assets && mv public assets/ && cp bin/download-lifat LICENSE COPYING.md README.md assets/ && git log -n 1 --pretty=oneline > assets/commit.txt
- run: cd assets && tar --zstd -cvpf ../assets.tar.zst . && cd -
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
project/.bloop/
conf/application.conf
conf/version.conf
conf/manifest.*

logs
project/metals.sbt
Expand All @@ -21,6 +22,7 @@ data/
dist/
node_modules/
local/
gen/
ui/common/**/*.js
ui/common/**/*.d.ts
ui/chess/**/*.js
Expand Down
1 change: 0 additions & 1 deletion .ignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# search ignores
vendor
translation/dest
ui/*/css/build
public/font
public/sound
public/piece
Expand Down
103 changes: 103 additions & 0 deletions app/AssetManifest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package lila.app

import play.api.{ Environment, Mode }
import play.api.libs.ws.StandaloneWSClient
import play.api.libs.ws.JsonBodyReadables.*
import play.api.libs.json.{ JsObject, Json, JsValue, JsString }
import java.nio.file.{ Files, Path, Paths }
import java.time.Instant

import lila.core.config.NetConfig

case class SplitAsset(name: String, imports: List[String])
case class AssetMaps(js: Map[String, SplitAsset], css: Map[String, String])

final class AssetManifest(environment: Environment, net: NetConfig)(using ws: StandaloneWSClient)(using
Executor
):

private var lastModified: Instant = Instant.MIN
private var maps: AssetMaps = AssetMaps(Map.empty, Map.empty)
private val defaultFilename = s"manifest.${if net.minifiedAssets then "prod" else "dev"}.json"
private val keyRe = """^(?!common\.)(\S+)\.([A-Z0-9]{8})\.(?:js|css)""".r

def js(key: String): Option[SplitAsset] = maps.js.get(key)
def css(key: String): Option[String] = maps.css.get(key)
def deps(keys: List[String]): List[String] = keys.flatMap { key => js(key).so(_.imports) }.distinct
def lastUpdate: Instant = lastModified

def update(filename: String = defaultFilename): Unit =
if environment.mode == Mode.Prod || net.externalManifest then
fetchManifestJson(filename).foreach:
case Some(manifestJson) =>
maps = readMaps(manifestJson)
lastModified = Instant.now
case _ => ()
else
val pathname = environment.getFile(s"public/compiled/$filename").toPath
try
val current = Files.getLastModifiedTime(pathname).toInstant
if current.isAfter(lastModified) then
maps = readMaps(Json.parse(Files.newInputStream(pathname)))
lastModified = current
catch
case _: Throwable =>
lila.log("assetManifest").warn(s"Error reading $pathname")

update()

private def keyOf(fullName: String): String =
fullName match
case keyRe(k, _) => k
case _ => fullName

private def closure(
name: String,
jsMap: Map[String, SplitAsset],
visited: Set[String] = Set.empty
): List[String] =
val k = keyOf(name)
jsMap.get(k) match
case Some(asset) if !visited.contains(k) =>
asset.imports.flatMap: importName =>
importName :: closure(importName, jsMap, visited + name)
case _ => Nil

private def readMaps(manifest: JsValue) =
val js = (manifest \ "js")
.as[JsObject]
.value
.map { (k, value) =>
val name = (value \ "hash").asOpt[String].fold(s"$k.js")(h => s"$k.$h.js")
val imports = (value \ "imports").asOpt[List[String]].getOrElse(Nil)
(k, SplitAsset(name, imports))
}
.toMap
AssetMaps(
js.map { (k, asset) =>
k -> (if asset.imports.nonEmpty then asset.copy(imports = closure(asset.name, js).distinct)
else asset)
},
(manifest \ "css")
.as[JsObject]
.value
.map { case (k, asset) =>
val hash = (asset \ "hash").as[String]
(k, s"$k.$hash.css")
}
.toMap
)

private def fetchManifestJson(filename: String) =
val resource = s"${net.assetBaseUrlInternal}/assets/compiled/$filename"
ws.url(resource)
.get()
.map:
case res if res.status == 200 => res.body[JsValue].some
case res =>
lila.log("assetManifest").warn(s"${res.status} fetching $resource")
none
.recoverWith:
case e: Exception =>
lila.log("assetManifest").warn(s"fetching $resource", e)
fuccess(none)
4 changes: 3 additions & 1 deletion app/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ final class Env(
SessionCookieBaker
):
val net: NetConfig = config.get[NetConfig]("net")
val manifest = AssetManifest(environment, net)

export net.{ domain, baseUrl, assetBaseUrlInternal }

given Mode = environment.mode
Expand Down Expand Up @@ -67,7 +69,6 @@ final class Env(
val pool: lila.pool.Env = wire[lila.pool.Env]
val lobby: lila.lobby.Env = wire[lila.lobby.Env]
val setup: lila.setup.Env = wire[lila.setup.Env]
val importer: lila.importer.Env = wire[lila.importer.Env]
val simul: lila.simul.Env = wire[lila.simul.Env]
val appeal: lila.appeal.Env = wire[lila.appeal.Env]
val timeline: lila.timeline.Env = wire[lila.timeline.Env]
Expand Down Expand Up @@ -139,6 +140,7 @@ given ConfigLoader[NetConfig] = ConfigLoader(config =>
assetBaseUrl = get[AssetBaseUrl]("asset.base_url"),
assetBaseUrlInternal = get[AssetBaseUrlInternal]("asset.base_url_internal"),
minifiedAssets = get[Boolean]("asset.minified"),
externalManifest = get[Boolean]("asset.external_manifest"),
stageBanner = get[Boolean]("stage.banner"),
siteName = get[String]("site.name"),
socketDomains = get[List[String]]("socket.domains"),
Expand Down
2 changes: 1 addition & 1 deletion app/LilaComponents.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ final class LilaComponents(
lila.log("boot").info(s"Loaded lila modules in ${c.showDuration}")
c.result

val httpFilters = Seq(lila.web.HttpFilter(env.net, lila.security.Mobile.LichessMobileUa.parse))
val httpFilters = Seq(lila.web.HttpFilter(env.web, env.net, lila.security.Mobile.LichessMobileUa.parse))

override lazy val httpErrorHandler =
lila.app.http.ErrorHandler(
Expand Down
4 changes: 1 addition & 3 deletions app/controllers/Dasher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ final class Dasher(env: Env)(using ws: StandaloneWSClient) extends LilaControlle
)
.add("gallery", gallery),
"board" -> Json.obj(
"is3d" -> ctx.pref.is3d
),
"theme" -> Json.obj(
"is3d" -> ctx.pref.is3d,
"d2" -> Json.obj(
"current" -> ctx.pref.currentTheme.name,
"list" -> lila.pref.Theme.all.map(_.name)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/Dev.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@ final class Dev(env: Env) extends LilaController(env):
}

private def runCommand(command: String)(using Me): Fu[String] =
if command == "change asset version" || command == "change assets version" then env.manifest.update()
env.mod.logApi.cli(command) >>
env.api.cli(command.split(" ").toList)
16 changes: 8 additions & 8 deletions app/controllers/Importer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import lila.app.{ *, given }
import lila.common.HTTPRequest
import lila.core.net.IpAddress
import lila.game.GameExt.analysable
import lila.game.importer.ImporterForm

final class Importer(env: Env) extends LilaController(env):

Expand All @@ -24,13 +25,13 @@ final class Importer(env: Env) extends LilaController(env):

def importGame = OpenBody:
val pgn = reqBody.queryString.get("pgn").flatMap(_.headOption).getOrElse("")
val data = lila.importer.ImportData(PgnStr(pgn), None)
Ok.page(html.game.importGame(env.importer.forms.importForm.fill(data)))
val data = lila.core.game.ImportData(PgnStr(pgn), None)
Ok.page(html.game.importGame(ImporterForm.form.fill(data)))

def sendGame = OpenOrScopedBody(parse.anyContent)()(doSendGame)
def apiSendGame = AnonOrScopedBody(parse.anyContent)()(doSendGame)
private def doSendGame(using ctx: BodyContext[Any]) =
env.importer.forms.importForm
ImporterForm.form
.bindFromRequest()
.fold(
err =>
Expand All @@ -40,19 +41,18 @@ final class Importer(env: Env) extends LilaController(env):
),
data =>
ImportRateLimitPerIP(ctx.ip, rateLimited, cost = if ctx.isAuth then 1 else 2):
env.importer
.importer(data)
.flatMap { game =>
env.game.importer
.importAsGame(data)
.flatMap: game =>
ctx.me.so(env.game.cached.clearNbImportedByCache(_)).inject(Right(game))
}
.recover { case _: Exception =>
Left("The PGN contains illegal and/or ambiguous moves.")
}
.flatMap {
case Right(game) =>
negotiate(
html = ctx.me
.filter(_ => data.analyse.isDefined && game.analysable)
.filter(_ => data.analyse.isDefined && lila.game.GameExt.analysable(game))
.soUse { me ?=>
env.fishnet
.analyser(
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/Plan.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ final class Plan(env: Env) extends LilaController(env):
bestIds = bestIds,
pricing = pricing
)
yield Ok(page)
yield Ok(page).withHeaders(crossOriginPolicy.unsafe*)

private def indexStripePatron(patron: lila.plan.Patron, customer: StripeCustomer)(using
ctx: Context,
Expand All @@ -84,6 +84,7 @@ final class Plan(env: Env) extends LilaController(env):
res <- info match
case Some(info: CustomerInfo.Monthly) =>
Ok.page(html.plan.indexStripe(me, patron, info, env.plan.stripePublicKey, pricing, gifts))

case Some(CustomerInfo.OneTime(cus)) =>
renderIndex(cus.email.map { EmailAddress(_) }, patron.some)
case None =>
Expand All @@ -98,6 +99,8 @@ final class Plan(env: Env) extends LilaController(env):
) =
Ok.pageAsync:
env.plan.api.giftsFrom(me).map { html.plan.indexPayPal(me, patron, sub, _) }
.map:
_.withHeaders(crossOriginPolicy.unsafe*)

private def myCurrency(using ctx: Context): Currency =
get("currency")
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/Pref.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ final class Pref(env: Env) extends LilaController(env):
v =>
ctx.me
.so(api.setPref(_, change.update(v)))
.inject(env.security.lilaCookie.session(name, v.toString)(using ctx.req))
.inject(
env.security.lilaCookie.session(name, v.toString)(using
ctx.req
)
)
.map: cookie =>
Ok(()).withCookies(cookie)
)
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/RelayRound.scala
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ final class RelayRound(
page <- renderPage:
html.relay.show(rt.withStudy(sc.study), data, chat, sVersion, crossSiteIsolation)
_ = if HTTPRequest.isHuman(req) then lila.mon.http.path(rt.tour.path).increment()
yield if crossSiteIsolation then Ok(page).enforceCrossSiteIsolation else Ok(page)
yield
if crossSiteIsolation then Ok(page).enforceCrossSiteIsolation
else Ok(page).withHeaders(crossOriginPolicy.unsafe*)
)(
studyC.privateUnauthorizedFu(oldSc.study),
studyC.privateForbiddenFu(oldSc.study)
Expand Down
5 changes: 2 additions & 3 deletions app/controllers/UserAnalysis.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import lila.common.HTTPRequest

import lila.tree.ExportOptions
import lila.core.id.GameFullId
import lila.game.GameExt.synthetic

final class UserAnalysis(
env: Env,
Expand Down Expand Up @@ -74,8 +73,8 @@ final class UserAnalysis(

private[controllers] def makePov(from: Situation.AndFullMoveNumber): Pov =
Pov(
lila.game.Game
.make(
lila.core.game
.newGame(
chess = chess.Game(
situation = from.situation,
ply = from.ply
Expand Down
Loading

0 comments on commit 27e2937

Please sign in to comment.