mirror of
https://github.com/lichess-org/lila.git
synced 2026-05-26 13:51:00 +00:00
108 lines
3.6 KiB
Scala
108 lines
3.6 KiB
Scala
package controllers
|
|
|
|
import scala.annotation.nowarn
|
|
import play.api.libs.json.*
|
|
|
|
import lila.app.{ *, given }
|
|
import lila.practice.JsonView.given
|
|
import lila.practice.{ PracticeSection, PracticeStudy, UserStudy }
|
|
import lila.study.Study.WithChapter
|
|
import lila.tree.Node.partitionTreeWriter
|
|
|
|
final class Practice(
|
|
env: Env,
|
|
userAnalysisC: => UserAnalysis
|
|
) extends LilaController(env):
|
|
|
|
private val api = env.practice.api
|
|
|
|
def index = OpenOrScoped(_.Web.Mobile):
|
|
negotiate(
|
|
html =
|
|
pageHit
|
|
Ok.async(api.get(ctx.me).map(views.practice.index)).map(_.noCache)
|
|
,
|
|
json = api.get(ctx.me).map(lila.practice.JsonView.api).map(JsonOk)
|
|
)
|
|
|
|
def show(
|
|
@nowarn sectionId: String,
|
|
@nowarn studySlug: String,
|
|
studyId: StudyId
|
|
) = Open:
|
|
Found(api.getStudyWithFirstOngoingChapter(ctx.me, studyId))(showUserPractice)
|
|
|
|
def showChapter(
|
|
@nowarn sectionId: String,
|
|
@nowarn studySlug: String,
|
|
studyId: StudyId,
|
|
chapterId: StudyChapterId
|
|
) = Open:
|
|
Found(api.getStudyWithChapter(ctx.me, studyId, chapterId))(showUserPractice)
|
|
|
|
def showSection(sectionId: String) =
|
|
redirectTo(sectionId)(_.studies.headOption)
|
|
|
|
def showStudySlug(sectionId: String, studySlug: String) =
|
|
redirectTo(sectionId)(_.studies.find(_.slug == studySlug))
|
|
|
|
private def redirectTo(sectionId: String)(select: PracticeSection => Option[PracticeStudy]) = Open:
|
|
api.structure.get.flatMap: struct =>
|
|
Found(struct.sections.find(_.id == sectionId)): section =>
|
|
select(section).so: study =>
|
|
Redirect(routes.Practice.show(section.id, study.slug, study.id))
|
|
|
|
private def showUserPractice(us: lila.practice.UserStudy)(using Context) =
|
|
Ok.async:
|
|
analysisJson(us).map: (analysisJson, studyJson) =>
|
|
views.practice
|
|
.show(
|
|
us,
|
|
lila.practice.JsonView.JsData(
|
|
study = studyJson,
|
|
analysis = analysisJson,
|
|
practice = lila.practice.JsonView(us)
|
|
)
|
|
)
|
|
.map:
|
|
_.noCache.enforceCrossSiteIsolation.withCanonical(s"${us.url}/${us.study.chapter.id}")
|
|
|
|
def chapter(studyId: StudyId, chapterId: StudyChapterId) = Open:
|
|
Found(api.getStudyWithChapter(ctx.me, studyId, chapterId)): us =>
|
|
analysisJson(us).map: (analysisJson, studyJson) =>
|
|
JsonOk(
|
|
Json.obj(
|
|
"study" -> studyJson,
|
|
"analysis" -> analysisJson
|
|
)
|
|
).noCache
|
|
|
|
private def analysisJson(us: UserStudy)(using Context): Fu[(JsObject, JsObject)] = us match
|
|
case UserStudy(_, _, chapters, WithChapter(study, chapter), _) =>
|
|
for
|
|
studyJson <- env.study.jsonView.full(study, chapter, chapters.some, withMembers = false)
|
|
initialFen = chapter.root.fen.some
|
|
pov = userAnalysisC.makePov(initialFen, chapter.setup.variant)
|
|
baseData = env.round.jsonView
|
|
.userAnalysisJson(
|
|
pov,
|
|
ctx.pref,
|
|
initialFen,
|
|
chapter.setup.orientation,
|
|
owner = false
|
|
)
|
|
analysis = baseData ++ Json.obj(
|
|
"treeParts" -> partitionTreeWriter(chapter.root, lichobile = false),
|
|
"practiceGoal" -> lila.practice.PracticeGoal(chapter)
|
|
)
|
|
analysisJson <- env.analyse.externalEngine.withExternalEngines(analysis)
|
|
yield (analysisJson, studyJson)
|
|
|
|
def complete(chapterId: StudyChapterId, nbMoves: Int) = AuthOrScoped(_.Web.Mobile) { ctx ?=> me ?=>
|
|
api.progress.setNbMoves(me, chapterId, lila.practice.PracticeProgress.NbMoves(nbMoves)).inject(NoContent)
|
|
}
|
|
|
|
def reset = AuthBody { _ ?=> me ?=>
|
|
api.progress.reset(me).inject(Redirect(routes.Practice.index))
|
|
}
|