persistent, shareable practice chapter URLs

pull/2588/head
Thibault Duplessis 2017-01-28 10:51:51 +01:00
parent e28b563d3e
commit ecd1e3f644
7 changed files with 37 additions and 15 deletions

View File

@ -24,14 +24,20 @@ object Practice extends LilaController {
}
def show(sectionId: String, studySlug: String, studyId: String) = Open { implicit ctx =>
OptionFuResult(env.api.getStudyWithFirstOngoingChapter(ctx.me, studyId)) { us =>
analysisJson(us) map {
case (analysisJson, studyJson) => Ok(html.practice.show(us, lila.practice.JsonView.JsData(
study = studyJson,
analysis = analysisJson,
practice = lila.practice.JsonView(us))))
}
} map NoCache
OptionFuResult(env.api.getStudyWithFirstOngoingChapter(ctx.me, studyId))(showUserPractice)
}
def showChapter(sectionId: String, studySlug: String, studyId: String, chapterId: String) = Open { implicit ctx =>
OptionFuResult(env.api.getStudyWithChapter(ctx.me, studyId, chapterId))(showUserPractice)
}
private def showUserPractice(us: lila.practice.UserStudy)(implicit ctx: Context) = analysisJson(us) map {
case (analysisJson, studyJson) => NoCache(Ok(
html.practice.show(us, lila.practice.JsonView.JsData(
study = studyJson,
analysis = analysisJson,
practice = lila.practice.JsonView(us)))
))
}
def chapter(studyId: String, chapterId: String) = Open { implicit ctx =>
@ -45,7 +51,7 @@ object Practice extends LilaController {
}
private def analysisJson(us: UserStudy)(implicit ctx: Context): Fu[(JsObject, JsObject)] = us match {
case UserStudy(_, _, chapters, WithChapter(study, chapter)) =>
case UserStudy(_, _, chapters, WithChapter(study, chapter), _) =>
val pov = UserAnalysis.makePov(chapter.root.fen.value.some, chapter.setup.variant)
Env.round.jsonView.userAnalysisJson(pov, ctx.pref, chapter.setup.orientation, owner = false) zip
studyEnv.jsonView(study, chapters, chapter, ctx.me) map {

View File

@ -160,6 +160,7 @@ GET /features controllers.Plan.features
# Practice
GET /practice controllers.Practice.index
GET /practice/:sectionId/:studySlug/:studyId controllers.Practice.show(sectionId: String, studySlug: String, studyId: String)
GET /practice/:sectionId/:studySlug/:studyId/:chapterId controllers.Practice.showChapter(sectionId: String, studySlug: String, studyId: String, chapterId: String)
POST /practice/complete/:chapterId/:moves controllers.Practice.complete(chapterId: String, moves: Int)
GET /practice/$studyId<\w{8}>/$chapterId<\w{8}> controllers.Practice.chapter(studyId: String, chapterId: String)
GET /practice/config controllers.Practice.config

View File

@ -26,6 +26,7 @@ object JsonView {
def apply(us: UserStudy) = Json.obj(
"study" -> us.practiceStudy,
"url" -> us.url,
"completion" -> JsObject {
us.practiceStudy.chapters.flatMap { c =>
us.practice.progress.chapters collectFirst {

View File

@ -40,8 +40,8 @@ final class PracticeApi(
study = rawSc.study.rewindTo(rawSc.chapter).withoutMembers,
chapter = rawSc.chapter.withoutChildren)
practiceStudy <- up.structure study sc.study.id
if up.structure hasStudy sc.study.id
} yield UserStudy(up, practiceStudy, chapters, sc)
section <- up.structure findSection sc.study.id
} yield UserStudy(up, practiceStudy, chapters, sc, section)
object config {
def get = configStore.get map (_ | PracticeConfig.empty)

View File

@ -13,6 +13,15 @@ case class PracticeStructure(
s.id -> s
}.toMap
lazy val sectionsByStudyIds: Map[Study.Id, PracticeSection] =
sections.flatMap { sec =>
sec.studies.map { stu =>
stu.id -> sec
}
}.toMap
def findSection(id: Study.Id): Option[PracticeSection] = sectionsByStudyIds get id
def hasStudy(id: Study.Id) = studiesByIds contains id
}

View File

@ -17,10 +17,14 @@ case class UserPractice(
}
case class UserStudy(
practice: UserPractice,
practiceStudy: PracticeStudy,
chapters: List[Chapter.Metadata],
study: Study.WithChapter)
practice: UserPractice,
practiceStudy: PracticeStudy,
chapters: List[Chapter.Metadata],
study: Study.WithChapter,
section: PracticeSection) {
def url = s"/practice/${section.id}/${practiceStudy.slug}/${study.study.id}"
}
case class Completion(done: Int, total: Int) {

View File

@ -32,6 +32,7 @@ module.exports = function(root, studyData, data) {
nbMoves(0);
won(false);
comment(makeComment(root.tree.root));
history.replaceState(null, studyData.chapter.name, data.url + '/' + studyData.chapter.id);
};
onLoad();