diff options
Diffstat (limited to 'src/main/scala/reading/component/index/BookDetail.scala')
-rw-r--r-- | src/main/scala/reading/component/index/BookDetail.scala | 84 |
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) + } } |