aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/reading/component/index/BookDetail.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/reading/component/index/BookDetail.scala')
-rw-r--r--src/main/scala/reading/component/index/BookDetail.scala84
1 files changed, 68 insertions, 16 deletions
diff --git a/src/main/scala/reading/component/index/BookDetail.scala b/src/main/scala/reading/component/index/BookDetail.scala
index f532c02..e97a154 100644
--- a/src/main/scala/reading/component/index/BookDetail.scala
+++ b/src/main/scala/reading/component/index/BookDetail.scala
@@ -1,27 +1,32 @@
package reading.component.index
-import scala.util.Random
-
+import rx._
import scalacss.Defaults._
import scalacss.ScalatagsCss._
import scalatags.JsDom.all._
import reading.component.index.style.{ BookDetail => BookStyle }
import reading.component.widget.AnimateMethod
-import reading.models.{ Book, Program, Filter }
+import reading.models.{ Filter, Book, Program, Grade, Theme, GroupedTheme }
import reading.Route
+import reading.utils.RxUtils._
object BookDetail {
- val componentId = s"books${Random.nextInt}"
+ val componentId = s"books-detail"
def apply(
- filters: Seq[Filter],
+ filters: Var[Set[Filter]],
+ detail: Var[Option[Book]],
+ search: Var[String],
book: Book,
parentId: String,
onClose: => Unit
+ )(
+ implicit
+ ctx: Ctx.Owner
): Frag = {
val titleParts = if (book.parts > 1) s", ${book.parts} volumes" else ""
- val grades = book.programs.map(Program.grade(_)).distinct.sorted
+ val grades = book.programs.map(Grade.from(_)).distinct.sorted
AnimateMethod.fadeIn(componentId)
@@ -55,23 +60,33 @@ object BookDetail {
BookStyle.definitions,
grades.map { grade =>
- val programs = book.programs.filter(p => Program.grade(p) == grade).sorted
+ val programs = book.programs.filter(p => Grade.from(p) == grade).sorted
val pp = grade.prettyPrint
- definition(pp, pp, programs.map(p => s"« ${p.prettyPrint} »"))
+ val programFilters = programs.map { program =>
+ (Filter(program), filters.map(addProgram(_, program)))
+ }
+ definition(filters, detail, search, pp, pp, programFilters, p => s"« $p »")
},
if (book.themes.nonEmpty) {
- definition("thème", "thèmes", book.themes.sorted.map(_.prettyPrint))
+ val themeFilters = book.themes.sorted.map { theme =>
+ (Filter(theme), filters.map(addTheme(_, theme)))
+ }
+ definition(filters, detail, search, "thème", "thèmes", themeFilters)
},
if (book.genres.nonEmpty) {
- definition("genre", "genres", book.genres.sorted.map(_.prettyPrint))
+ val bookFilters = book.genres.sorted.map(Filter(_)).map(b => (b, filters.map(_ + b)))
+ definition(filters, detail, search, "genre", "genres", bookFilters)
},
- definition("niveau", "niveaux", Seq(book.level.prettyPrint))
+ {
+ val levelFilters = Seq(Filter(book.level)).map(b => (b, filters.map(_ + b)))
+ definition(filters, detail, search, "niveau", "niveaux", levelFilters)
+ }
),
a(
BookStyle.close,
onclick := (() => onClose),
- href := Route.url(Route.Books(filters)),
+ href := Rx(Route.url(Route.Books(filters()))),
"Fermer"
)
)
@@ -79,11 +94,48 @@ object BookDetail {
)
}
- private def definition(key: String, pluralKey: String, values: Seq[String]): Seq[Frag] = {
- val term = if (values.length > 1) pluralKey else key
+ private def definition(
+ filters: Var[Set[Filter]],
+ detail: Var[Option[Book]],
+ search: Var[String],
+ term: String,
+ pluralTerm: String,
+ definitionFilters: Seq[(Filter, Rx[Set[Filter]])],
+ format: String => String = _.capitalize
+ )(
+ implicit
+ ctx: Ctx.Owner
+ ): Seq[Frag] = {
+ val sTerm = if (definitionFilters.length > 1) pluralTerm else term
+
Seq(
- dt(BookStyle.definitionTerm, s"${term.capitalize} :"),
- dd(BookStyle.definitionDescription, values.mkString(", "))
+ dt(BookStyle.definitionTerm, s"${sTerm.capitalize} :"),
+ dd(
+ BookStyle.definitionDescription,
+ definitionFilters.map {
+ case (filter, newFilters) =>
+ a(
+ BookStyle.definitionFilter,
+ href := Rx(Route.url(Route.Books(newFilters()))),
+ onclick := (() => FilterUtils.set(filters, detail, search, newFilters.now)),
+ format(filter.name)
+ )
+ }
+ )
)
}
+
+ private def addProgram(filters: Set[Filter], program: Program): Set[Filter] = {
+ val grade = Grade.from(program)
+ val otherGrades = Grade.values.filter(_ != grade).map(Filter(_))
+ val otherPrograms = Program.values.filter(Grade.from(_) != grade).map(Filter(_))
+ filters -- otherGrades -- otherPrograms + Filter(grade) + Filter(program)
+ }
+
+ private def addTheme(filters: Set[Filter], theme: Theme): Set[Filter] = {
+ val groupedTheme = GroupedTheme.from(theme)
+ val otherGroupedThemes = GroupedTheme.values.filter(_ != groupedTheme).map(Filter(_))
+ val otherThemes = Theme.values.filter(GroupedTheme.from(_) != groupedTheme).map(Filter(_))
+ filters -- otherGroupedThemes -- otherThemes + Filter(groupedTheme) + Filter(theme)
+ }
}