only load the required study chapters

pull/5287/head^2
Thibault Duplessis 2019-07-08 19:35:27 -04:00
parent 71db1aff8b
commit 8eb0531f89
6 changed files with 28 additions and 21 deletions

View File

@ -26,7 +26,7 @@ object Coach extends LilaController {
WithVisibleCoach(c) {
Env.study.api.publicByIds {
c.coach.profile.studyIds.map(_.value).map(lila.study.Study.Id.apply)
} flatMap Env.study.pager.withChaptersAndLiking(ctx.me) flatMap { studies =>
} flatMap Env.study.pager.withChaptersAndLiking(ctx.me, 4) flatMap { studies =>
api.reviews.approvedByCoach(c.coach) flatMap { reviews =>
ctx.me.?? { api.reviews.mine(_, c.coach) } map { myReview =>
lila.mon.coach.pageView.profile(c.coach.id.value)()

View File

@ -53,7 +53,7 @@ object bits {
),
div(cls := "body")(
ol(cls := "chapters")(
s.chapters.take(4).map { name =>
s.chapters.map { name =>
li(cls := "text", dataIcon := "K")(name.value)
}
),

View File

@ -130,23 +130,26 @@ final class ChapterRepo(coll: Coll) {
}
}
private[study] def idNamesByStudyIds(studyIds: Seq[Study.Id]): Fu[Map[Study.Id, Vector[Chapter.IdName]]] =
private[study] def idNamesByStudyIds(studyIds: Seq[Study.Id], nbChaptersPerStudy: Int): Fu[Map[Study.Id, Vector[Chapter.IdName]]] =
coll.find(
$doc("studyId" $in studyIds),
$doc("studyId" -> true, "_id" -> true, "name" -> true)
).sort($sort asc "order").list[Bdoc]().map { docs =>
docs.foldLeft(Map.empty[Study.Id, Vector[Chapter.IdName]]) {
case (hash, doc) => {
for {
studyId <- doc.getAs[Study.Id]("studyId")
id <- doc.getAs[Chapter.Id]("_id")
name <- doc.getAs[Chapter.Name]("name")
idName = Chapter.IdName(id, name)
} yield hash + (studyId -> (hash.get(studyId) match {
case None => Vector(idName)
case Some(names) => names :+ idName
}))
} | hash
case (hash, doc) =>
doc.getAs[Study.Id]("studyId").fold(hash) { studyId =>
hash get studyId match {
case Some(chapters) if chapters.size >= nbChaptersPerStudy => hash
case maybe =>
val chapters = ~maybe
val newChapter = for {
id <- doc.getAs[Chapter.Id]("_id")
name <- doc.getAs[Chapter.Name]("name")
} yield Chapter.IdName(id, name)
val newChapters = newChapter.fold(chapters)(chapters :+ _)
hash + (studyId -> newChapters)
}
}
}
}

View File

@ -690,7 +690,7 @@ final class StudyApi(
def resetAllRanks = studyRepo.resetAllRanks
def chapterIdNames(studyIds: List[Study.Id]): Fu[Map[Study.Id, Vector[Chapter.IdName]]] =
chapterRepo.idNamesByStudyIds(studyIds)
chapterRepo.idNamesByStudyIds(studyIds, Study.maxChapters)
def chapterMetadatas = chapterRepo.orderedMetadataByStudy _

View File

@ -11,6 +11,8 @@ final class StudyPager(
maxPerPage: lila.common.MaxPerPage
) {
private val defaultNbChaptersPerStudy = 4
import BSONHandlers._
import studyRepo.{ selectPublic, selectPrivateOrUnlisted, selectMemberId, selectOwnerId, selectLiker }
@ -65,7 +67,7 @@ final class StudyPager(
case Order.Updated => $sort desc "updatedAt"
case Order.Popular => $sort desc "likes"
}
) mapFutureList withChaptersAndLiking(me)
) mapFutureList withChaptersAndLiking(me, defaultNbChaptersPerStudy)
Paginator(
adapter = nbResults.fold(adapter) { nb =>
new CachedAdapter(adapter, nb)
@ -75,8 +77,8 @@ final class StudyPager(
)
}
def withChapters(studies: Seq[Study]): Fu[Seq[Study.WithChapters]] =
chapterRepo idNamesByStudyIds studies.map(_.id) map { chapters =>
def withChapters(studies: Seq[Study], nbChaptersPerStudy: Int): Fu[Seq[Study.WithChapters]] =
chapterRepo.idNamesByStudyIds(studies.map(_.id), nbChaptersPerStudy) map { chapters =>
studies.map { study =>
Study.WithChapters(study, ~(chapters get study.id map {
_ map (_.name)
@ -92,8 +94,8 @@ final class StudyPager(
}
}
def withChaptersAndLiking(me: Option[User])(studies: Seq[Study]): Fu[Seq[Study.WithChaptersAndLiked]] =
withChapters(studies) flatMap withLiking(me)
def withChaptersAndLiking(me: Option[User], nbChaptersPerStudy: Int)(studies: Seq[Study]): Fu[Seq[Study.WithChaptersAndLiked]] =
withChapters(studies, nbChaptersPerStudy) flatMap withLiking(me)
}
sealed abstract class Order(val key: String, val name: String)

View File

@ -41,7 +41,9 @@ final class Env(
def query = Query(text, me.map(_.id))
def nbResults = api count query
def slice(offset: Int, length: Int) = api.search(query, From(offset), Size(length))
} mapFutureList studyEnv.pager.withChapters mapFutureList studyEnv.pager.withLiking(me),
} mapFutureList {
studyEnv.pager.withChapters(_, Study.maxChapters)
} mapFutureList studyEnv.pager.withLiking(me),
currentPage = page,
maxPerPage = lila.common.MaxPerPage(MaxPerPage)
)