From 6b7074fde5feb7d1dfe543ffa45f79dd0daa45fe Mon Sep 17 00:00:00 2001 From: Joris Date: Sat, 21 Jan 2017 14:29:56 +0100 Subject: Show only book covers in search page and show detail when clicking on its --- src/main/scala/reading/Books.scala | 12 ++--- src/main/scala/reading/component/Index.scala | 10 ++-- src/main/scala/reading/component/index/Book.scala | 48 +++++++++++++++++ src/main/scala/reading/component/index/Books.scala | 61 +++++++--------------- .../scala/reading/component/index/Filters.scala | 4 +- .../scala/reading/component/index/style/Book.scala | 42 +++++++++++++++ .../reading/component/index/style/Books.scala | 46 ++-------------- .../reading/component/index/style/Filters.scala | 17 +++--- src/main/scala/reading/component/style/Color.scala | 2 + src/main/scala/reading/component/style/Index.scala | 2 +- .../scala/reading/component/widget/Cross.scala | 6 ++- .../scala/reading/component/widget/Popup.scala | 45 ++++++++++++++++ .../reading/component/widget/style/Cross.scala | 4 +- .../reading/component/widget/style/Popup.scala | 50 ++++++++++++++++++ src/main/scala/reading/models/Genre.scala | 4 +- 15 files changed, 246 insertions(+), 107 deletions(-) create mode 100644 src/main/scala/reading/component/index/Book.scala create mode 100644 src/main/scala/reading/component/index/style/Book.scala create mode 100644 src/main/scala/reading/component/widget/Popup.scala create mode 100644 src/main/scala/reading/component/widget/style/Popup.scala (limited to 'src/main/scala') diff --git a/src/main/scala/reading/Books.scala b/src/main/scala/reading/Books.scala index bb8f32b..65c893f 100644 --- a/src/main/scala/reading/Books.scala +++ b/src/main/scala/reading/Books.scala @@ -181,7 +181,7 @@ object Books { ), Book( - title = "les carnets de Cerise", + title = "Les carnets de Cerise", author = "Joris CHAMBLAIN et Aurélie NEYRET", year = "2012-2016", parts = 4, @@ -363,7 +363,7 @@ object Books { Book( title = "Les Dix petits nègres", - author = "Agatha Christie", + author = "Agatha CHRISTIE", year = "1939", period = Some(Siecle20), genres = Seq(Policier), @@ -374,7 +374,7 @@ object Books { Book( title = "Le Crime de l'Orient-Express", - author = "Agatha Christie", + author = "Agatha CHRISTIE", year = "1934", period = Some(Siecle20), genres = Seq(Policier), @@ -385,7 +385,7 @@ object Books { Book( title = "Cinq petits cochons", - author = "Agatha Christie", + author = "Agatha CHRISTIE", year = "1942", period = Some(Siecle20), genres = Seq(Policier), @@ -396,7 +396,7 @@ object Books { Book( title = "Un Cadavre dans la bibliothèque", - author = "Agatha Christie", + author = "Agatha CHRISTIE", year = "1942", period = Some(Siecle20), genres = Seq(Policier), @@ -407,7 +407,7 @@ object Books { Book( title = "Le Meurtre de Roger Ackroyd", - author = "Agatha Christie", + author = "Agatha CHRISTIE", year = "1926", period = Some(Siecle20), genres = Seq(Policier), diff --git a/src/main/scala/reading/component/Index.scala b/src/main/scala/reading/component/Index.scala index 6061956..8c2fdd6 100644 --- a/src/main/scala/reading/component/Index.scala +++ b/src/main/scala/reading/component/Index.scala @@ -11,7 +11,7 @@ import reading.Books import reading.component.style.{ Index => IndexStyle } import reading.component.index.{ FiltersMenu, Filters, Books => BooksComponent } import reading.models.{ Book, Filter } -import reading.utils.RxAttr +import reading.utils.RxTag object Index { def apply(initialFilters: Seq[Filter]): HtmlTag = { @@ -19,14 +19,16 @@ object Index { val books: Rx[Seq[Book]] = Rx { if (filters().isEmpty) Books() else Book.filter(Books(), filters()) } + val count: Rx[Int] = Rx(books().length) div( IndexStyle.render, - button( + div( IndexStyle.header, - RxAttr(onclick, Rx(() => filters() = Nil)), - "Conseils de lecture" + RxTag { implicit context => + span(s"Conseils de lecture, ${count()} livre${if (count() > 1) "s" else ""}") + } ), div( diff --git a/src/main/scala/reading/component/index/Book.scala b/src/main/scala/reading/component/index/Book.scala new file mode 100644 index 0000000..ffa3c6b --- /dev/null +++ b/src/main/scala/reading/component/index/Book.scala @@ -0,0 +1,48 @@ +package reading.component.index + +import scalatags.JsDom.all._ +import scalacss.Defaults._ +import scalacss.ScalatagsCss._ + +import reading.component.index.style.{ Book => BookStyle } +import reading.models.{ Program, Book => BookModel } + +object Book { + def apply(book: BookModel): HtmlTag = + div( + BookStyle.render, + BookStyle.detail, + + img( + BookStyle.cover, + src := s"cover/${book.title}.jpg" + ), + + div( + div(BookStyle.title, book.title), + div(BookStyle.author, s", ${book.author}"), + if (book.programs.nonEmpty) { + div( + item("classe", book.programs.map(Program.grade(_).prettyPrint).distinct.sorted.mkString(", ")), + item("programme", book.programs.map(p => "« " ++ p.prettyPrint ++ " »").sorted.mkString(", ")) + ) + }, + if (book.themes.nonEmpty) { + item("thème", book.themes.sorted.map(_.prettyPrint).mkString(", ")) + }, + if (book.genres.nonEmpty) { + item("genre", book.genres.sorted.map(_.prettyPrint).mkString(", ")) + }, + book.period.map { period => + item("période", period.prettyPrint) + } + ) + ) + + private def item(key: String, value: String): Frag = + div( + BookStyle.item, + span(BookStyle.itemKey, key), + span(BookStyle.itemValue, value) + ) +} diff --git a/src/main/scala/reading/component/index/Books.scala b/src/main/scala/reading/component/index/Books.scala index ed6265b..50a05a9 100644 --- a/src/main/scala/reading/component/index/Books.scala +++ b/src/main/scala/reading/component/index/Books.scala @@ -1,70 +1,49 @@ package reading.component.index import rx._ +import Ctx.Owner.Unsafe._ import scalatags.JsDom.all._ import scalacss.Defaults._ import scalacss.ScalatagsCss._ import reading.component.index.style.{ Books => BooksStyle } -import reading.models.{ Book, Program } -import reading.utils.RxTag +import reading.component.widget.Popup +import reading.models.{ Book => BookModel } +import reading.utils.{ RxTag, RxAttr } object Books { - def apply(books: Rx[Seq[Book]]): Frag = + def apply(books: Rx[Seq[BookModel]]): Frag = { + val focus: Var[Option[BookModel]] = Var(None) + div( BooksStyle.render, RxTag { implicit context => div( - div( - BooksStyle.count, - s"${books().length} livres" - ), - div( BooksStyle.books, books().sorted.map { book => div( BooksStyle.book, - div(BooksStyle.title, book.title), - div(BooksStyle.author, s", ${book.author}"), - div( - BooksStyle.detail, - img( - BooksStyle.cover, - src := s"cover/${book.title}.jpg" - ), - div( - if (book.programs.nonEmpty) { - div( - item("classe", book.programs.map(Program.grade(_).prettyPrint).distinct.sorted.mkString(", ")), - item("programme", book.programs.map(p => "« " ++ p.prettyPrint ++ " »").sorted.mkString(", ")) - ) - }, - if (book.themes.nonEmpty) { - item("thème", book.themes.sorted.map(_.prettyPrint).mkString(", ")) - }, - if (book.genres.nonEmpty) { - item("genre", book.genres.sorted.map(_.prettyPrint).mkString(", ")) - }, - book.period.map { period => - item("période", period.prettyPrint) - } - ) + img( + BooksStyle.cover, + src := s"cover/${book.title}.jpg", + RxAttr(onclick, Rx(() => focus() = Some(book))) ) ) } - ) + ), + + RxTag { implicit context => + focus() match { + case Some(book) => Popup(onClose = focus() = None)(Book(book)) + case None => span("") + } + } ) } ) - - def item(key: String, value: String): Frag = - div( - BooksStyle.item, - span(BooksStyle.itemKey, key), - span(BooksStyle.itemValue, value) - ) + } } diff --git a/src/main/scala/reading/component/index/Filters.scala b/src/main/scala/reading/component/index/Filters.scala index 08ec835..569bd86 100644 --- a/src/main/scala/reading/component/index/Filters.scala +++ b/src/main/scala/reading/component/index/Filters.scala @@ -32,8 +32,8 @@ object Filters { filters() = newFilters Route.push(Route.Books(newFilters)) })), - span(FiltersStyle.name, filter.name), - Cross(15.px, Col.white) + span(FiltersStyle.name, filter.name.capitalize), + Cross(15.px, Col.black) ) } ) diff --git a/src/main/scala/reading/component/index/style/Book.scala b/src/main/scala/reading/component/index/style/Book.scala new file mode 100644 index 0000000..9f242eb --- /dev/null +++ b/src/main/scala/reading/component/index/style/Book.scala @@ -0,0 +1,42 @@ +package reading.component.index.style + +import scalacss.Defaults._ + +import reading.component.style.Col + +object Book extends StyleSheet.Inline { + import dsl._ + + val title = style( + display.inlineBlock, + fontSize(18.px), + fontWeight.bold, + marginBottom(20.px), + color(Col.congoBrown) + ) + + val author = style( + display.inlineBlock + ) + + val detail = style( + display.flex + ) + + val cover = style( + height(300.px), + marginRight(30.px) + ) + + val item = style( + lineHeight(25.px), + marginBottom(4.px) + ) + + val itemKey = style( + fontWeight.bold, + marginRight(10.px) + ) + + val itemValue = style() +} diff --git a/src/main/scala/reading/component/index/style/Books.scala b/src/main/scala/reading/component/index/style/Books.scala index 97c1479..34a7a83 100644 --- a/src/main/scala/reading/component/index/style/Books.scala +++ b/src/main/scala/reading/component/index/style/Books.scala @@ -2,8 +2,6 @@ package reading.component.index.style import scalacss.Defaults._ -import reading.component.style.Col - object Books extends StyleSheet.Inline { import dsl._ @@ -12,50 +10,14 @@ object Books extends StyleSheet.Inline { flexWrap.wrap ) - val count = style( - marginBottom(30.px) - ) - val book = style( - media.minWidth(1300.px)( - width(50.%%) - ), - media.maxWidth(1300.px)( - width(100.%%) - ), + width(250.px), paddingBottom(60.px), - paddingRight(60.px) - ) - - val title = style( - display.inlineBlock, - fontWeight.bold, - marginBottom(20.px), - color(Col.congoBrown) - ) - - val author = style( - display.inlineBlock - ) - - val detail = style( - display.flex + textAlign.center ) val cover = style( - height(150.px), - marginRight(40.px) - ) - - val item = style( - lineHeight(25.px), - marginBottom(4.px) + height(250.px), + cursor.pointer ) - - val itemKey = style( - fontWeight.bold, - marginRight(10.px) - ) - - val itemValue = style() } diff --git a/src/main/scala/reading/component/index/style/Filters.scala b/src/main/scala/reading/component/index/style/Filters.scala index 5ca9dfe..cb1ceb4 100644 --- a/src/main/scala/reading/component/index/style/Filters.scala +++ b/src/main/scala/reading/component/index/style/Filters.scala @@ -15,15 +15,20 @@ object Filters extends StyleSheet.Inline { val filter = style( display.flex, alignItems.center, - backgroundColor(Col.gray), - color(Col.white), - padding(10.px), - marginRight(10.px), + padding(15.px), + marginRight(20.px), borderRadius(2.px), - &.hover(cursor.pointer) + &.hover(cursor.pointer), + border(1.px, solid, Col.alto), + fontSize(18.px) ) val name = style( - marginRight(5.px) + marginRight(10.px) + ) + + val cross = style( + width(15.px), + height(15.px) ) } diff --git a/src/main/scala/reading/component/style/Color.scala b/src/main/scala/reading/component/style/Color.scala index 13fd5f2..85498de 100644 --- a/src/main/scala/reading/component/style/Color.scala +++ b/src/main/scala/reading/component/style/Color.scala @@ -9,6 +9,8 @@ object Col extends StyleSheet.Inline { val black = c"#000000" val white = c"#FFFFFF" val gray = c"#7E7E7E" + val alto = c"#D4D1D1" val eastBay = c"#505080" val congoBrown = c"#57363E" + val stiletto = c"#9C3336" } diff --git a/src/main/scala/reading/component/style/Index.scala b/src/main/scala/reading/component/style/Index.scala index 355acb0..8f31683 100644 --- a/src/main/scala/reading/component/style/Index.scala +++ b/src/main/scala/reading/component/style/Index.scala @@ -9,7 +9,7 @@ object Index extends StyleSheet.Inline { fontSize(40.px), color(Col.congoBrown), textAlign.center, - margin(10.px, auto), + margin(10.px, auto, 30.px), padding(20.px), &.hover( textDecoration := "none" diff --git a/src/main/scala/reading/component/widget/Cross.scala b/src/main/scala/reading/component/widget/Cross.scala index cfbb29d..c9e3054 100644 --- a/src/main/scala/reading/component/widget/Cross.scala +++ b/src/main/scala/reading/component/widget/Cross.scala @@ -14,7 +14,9 @@ object Cross { CrossStyle.cross, width := size, height := size, - div(CrossStyle.line1, backgroundColor := color.value), - div(CrossStyle.line2, backgroundColor := color.value) + div( + div(CrossStyle.line1, backgroundColor := color.value), + div(CrossStyle.line2, backgroundColor := color.value) + ) ) } diff --git a/src/main/scala/reading/component/widget/Popup.scala b/src/main/scala/reading/component/widget/Popup.scala new file mode 100644 index 0000000..8e40d36 --- /dev/null +++ b/src/main/scala/reading/component/widget/Popup.scala @@ -0,0 +1,45 @@ +package reading.component.widget + +import org.scalajs.dom + +import rx._ +import Ctx.Owner.Unsafe._ + +import scalatags.JsDom.all._ +import scalacss.Defaults._ +import scalacss.ScalatagsCss._ + +import reading.component.widget.style.{ Popup => PopupStyle } +import reading.component.style.Col +import reading.utils.{ RxAttr } + +object Popup { + def apply(onClose: => Unit)(content: HtmlTag): HtmlTag = { + dom.document.body.style.overflowY = "hidden" + + div( + PopupStyle.render, + PopupStyle.popup, + + div( + PopupStyle.curtain, + RxAttr(onclick, Rx(() => close(onClose))) + ), + + div( + PopupStyle.content, + content, + div( + PopupStyle.cross, + RxAttr(onclick, Rx(() => close(onClose))), + Cross(20.px, Col.stiletto) + ) + ) + ) + } + + private def close(onClose: => Unit): Unit = { + dom.document.body.style.overflowY = "scroll" + onClose + } +} diff --git a/src/main/scala/reading/component/widget/style/Cross.scala b/src/main/scala/reading/component/widget/style/Cross.scala index 1d96958..485e1e9 100644 --- a/src/main/scala/reading/component/widget/style/Cross.scala +++ b/src/main/scala/reading/component/widget/style/Cross.scala @@ -6,7 +6,9 @@ object Cross extends StyleSheet.Inline { import dsl._ val cross = style( - position.relative + position.relative, + width(100.%%), + height(100.%%) ) val line1 = style( diff --git a/src/main/scala/reading/component/widget/style/Popup.scala b/src/main/scala/reading/component/widget/style/Popup.scala new file mode 100644 index 0000000..422e3bd --- /dev/null +++ b/src/main/scala/reading/component/widget/style/Popup.scala @@ -0,0 +1,50 @@ +package reading.component.widget.style + +import scalacss.Defaults._ + +import reading.component.style.Col + +object Popup extends StyleSheet.Inline { + import dsl._ + + val popup = style( + display.flex, + justifyContent.center, + alignItems.center, + position.fixed, + width(100.%%), + height(100.%%), + top(0.px), + right(0.px), + bottom(0.px), + left(0.px) + ) + + val curtain = style( + width(100.%%), + height(100.%%), + position.absolute, + top(0.px), + left(0.px), + backgroundColor(Col.black), + opacity(0.5), + cursor.pointer + ) + + val content = style( + position.relative, + width(50.%%), + backgroundColor(Col.white), + padding(30.px), + borderRadius(5.px) + ) + + val cross = style( + position.absolute, + top(30.px), + right(30.px), + width(20.px), + height(20.px), + cursor.pointer + ) +} diff --git a/src/main/scala/reading/models/Genre.scala b/src/main/scala/reading/models/Genre.scala index 51d2394..db08d24 100644 --- a/src/main/scala/reading/models/Genre.scala +++ b/src/main/scala/reading/models/Genre.scala @@ -16,8 +16,8 @@ sealed trait Genre extends EnumEntry with Ordered[Genre] { case Fantastique => "fantastique" case Fantasy => "fantasy" case Merveilleux => "merveilleux" - case SF => "SF" - case BD => "BD" + case SF => "science fiction" + case BD => "bande dessinée" case RomanAventure => "roman d'aventure" case Comique => "comique" case Dystopie => "dystopie" -- cgit v1.2.3