aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2017-02-26 16:29:25 +0100
committerJoris2017-02-26 16:29:25 +0100
commit0567fff028f2f8db6fe5034ce92d52f62469ae1f (patch)
treeb492af93a15ecd35fe3373de7706e0436ef049b7
parentaa662810a98e0cfe7ea98cadb87a55c8571f10db (diff)
Use anchor instead of div or button for filters and details tags
-rw-r--r--README.md5
-rw-r--r--src/main/scala/reading/Route.scala7
-rw-r--r--src/main/scala/reading/component/index/BookDetail.scala13
-rw-r--r--src/main/scala/reading/component/index/Books.scala15
-rw-r--r--src/main/scala/reading/component/index/Filters.scala11
-rw-r--r--src/main/scala/reading/component/index/Menu.scala45
-rw-r--r--src/main/scala/reading/component/index/style/Books.scala2
-rw-r--r--src/main/scala/reading/component/index/style/Menu.scala17
-rw-r--r--src/main/scala/reading/component/style/Global.scala5
-rw-r--r--src/main/scala/reading/component/widget/Input.scala2
-rw-r--r--src/main/scala/reading/component/widget/style/Input.scala10
11 files changed, 84 insertions, 48 deletions
diff --git a/README.md b/README.md
index a19499d..2e62924 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,5 @@ Dev environment:
TODO
----
-- Resumes for every book
-- Click on filter on a book detail must do something
-- Links attached to filters and book details
+- Add a resume to every book.
+- Filter when the user click on a theme / genre / program on book detail.
diff --git a/src/main/scala/reading/Route.scala b/src/main/scala/reading/Route.scala
index 76a9431..f098468 100644
--- a/src/main/scala/reading/Route.scala
+++ b/src/main/scala/reading/Route.scala
@@ -1,6 +1,6 @@
package reading
-import org.scalajs.dom.window
+import org.scalajs.dom.{ window, MouseEvent }
import org.scalajs.dom.raw.PopStateEvent
import scala.scalajs.js.URIUtils
@@ -19,6 +19,11 @@ object Route {
current() = parse(window.location.hash)
}
+ // Prevent page changes when clicking with the mouse left button
+ window.onclick = { (event: MouseEvent) =>
+ if (event.button == 0) event.preventDefault()
+ }
+
def parse(hash: String): Route =
pathAndParams(hash) match {
case ("books" :: Nil, params) => {
diff --git a/src/main/scala/reading/component/index/BookDetail.scala b/src/main/scala/reading/component/index/BookDetail.scala
index 24f48b3..f532c02 100644
--- a/src/main/scala/reading/component/index/BookDetail.scala
+++ b/src/main/scala/reading/component/index/BookDetail.scala
@@ -8,12 +8,18 @@ import scalatags.JsDom.all._
import reading.component.index.style.{ BookDetail => BookStyle }
import reading.component.widget.AnimateMethod
-import reading.models.{ Book, Program }
+import reading.models.{ Book, Program, Filter }
+import reading.Route
object BookDetail {
val componentId = s"books${Random.nextInt}"
- def apply(book: Book, parentId: String, onClose: => Unit): Frag = {
+ def apply(
+ filters: Seq[Filter],
+ book: Book,
+ parentId: String,
+ onClose: => Unit
+ ): Frag = {
val titleParts = if (book.parts > 1) s", ${book.parts} volumes" else ""
val grades = book.programs.map(Program.grade(_)).distinct.sorted
@@ -62,9 +68,10 @@ object BookDetail {
definition("niveau", "niveaux", Seq(book.level.prettyPrint))
),
- button(
+ a(
BookStyle.close,
onclick := (() => onClose),
+ href := Route.url(Route.Books(filters)),
"Fermer"
)
)
diff --git a/src/main/scala/reading/component/index/Books.scala b/src/main/scala/reading/component/index/Books.scala
index b5e172b..f15e2dc 100644
--- a/src/main/scala/reading/component/index/Books.scala
+++ b/src/main/scala/reading/component/index/Books.scala
@@ -50,17 +50,20 @@ object Books {
searchedBooks().sorted.map { book =>
div(
BooksStyle.book,
- img(
- BooksStyle.cover,
- src := s"cover/${book.title}.jpg",
- alt := s"${book.title}, ${book.author}",
+ a(
+ href := Rx(Route.url(Route.Books(filters = filters(), detail = Some(book)))),
onclick := (() => {
Route.push(Route.Books(filters.now, Some(book)))
AnimateMethod.fadeOut(
id = componentId,
onEnd = detail() = Some(book)
)
- })
+ }),
+ img(
+ BooksStyle.cover,
+ src := s"cover/${book.title}.jpg",
+ alt := s"${book.title}, ${book.author}"
+ )
)
)
}
@@ -72,7 +75,7 @@ object Books {
Rx {
detail() match {
case Some(book) =>
- BookDetail(book, componentId, onClose = closeDetail(filters, detail))
+ BookDetail(filters.now, book, componentId, onClose = closeDetail(filters, detail))
case None =>
span("")
}
diff --git a/src/main/scala/reading/component/index/Filters.scala b/src/main/scala/reading/component/index/Filters.scala
index 3aa26e8..935e501 100644
--- a/src/main/scala/reading/component/index/Filters.scala
+++ b/src/main/scala/reading/component/index/Filters.scala
@@ -2,14 +2,15 @@ package reading.component.index
import rx._
-import scalatags.JsDom.all._
import scalacss.Defaults._
import scalacss.ScalatagsCss._
+import scalatags.JsDom.all._
import reading.component.index.style.{ Filters => FiltersStyle }
-import reading.component.widget.Cross
import reading.component.style.{ Color => C }
+import reading.component.widget.Cross
import reading.models.{ Filter, Book }
+import reading.Route
import reading.utils.RxUtils._
object Filters {
@@ -43,16 +44,18 @@ object Filters {
div(
FiltersStyle.values,
- div(
+ a(
FiltersStyle.clear,
onclick := (() => FilterUtils.removeAll(filters, detail, search)),
+ href := Route.url(Route.Books()),
"Effacer les filtres"
),
filters().sortBy(_.name).map { filter =>
- div(
+ a(
FiltersStyle.filter,
onclick := (() => FilterUtils.remove(filters, detail, search, filter)),
+ href := Rx(Route.url(Route.Books(Filter.remove(filters(), filter)))),
span(FiltersStyle.name, filter.name.capitalize),
Cross(15.px, C.gray.value)
)
diff --git a/src/main/scala/reading/component/index/Menu.scala b/src/main/scala/reading/component/index/Menu.scala
index cfeb6d4..0ea6ca4 100644
--- a/src/main/scala/reading/component/index/Menu.scala
+++ b/src/main/scala/reading/component/index/Menu.scala
@@ -8,6 +8,7 @@ import scalatags.JsDom.all._
import reading.component.index.style.{ Menu => MenuStyle }
import reading.models._
+import reading.Route
import reading.utils.RxUtils._
object Menu {
@@ -88,9 +89,12 @@ object Menu {
span("")
else
div(
- div(
+ a(
MenuStyle.filterTitle,
parentFilter.map { filter =>
+ href := Route.url(Route.Books(filters = Filter.remove(filters(), filter)))
+ }.getOrElse(""),
+ parentFilter.map { filter =>
onclick := (() => FilterUtils.remove(filters, detail, search, filter))
}.getOrElse(""),
if (parentFilter.isDefined) MenuStyle.activeFilter else "",
@@ -104,10 +108,14 @@ object Menu {
filtersWithCount().map {
case (filter, count) => {
val isActive = Filter.contains(filters(), filter)
+ val route = Route.Books(
+ filters = if (isActive) Filter.remove(filters(), filter) else filter +: filters()
+ )
- button(
+ a(
MenuStyle.filter,
if (isActive) MenuStyle.activeFilter else "",
+ href := Rx(Route.url(route)),
onclick := (() =>
if (isActive)
FilterUtils.remove(filters, detail, search, filter)
@@ -135,25 +143,22 @@ object Menu {
implicit
ctx: Ctx.Owner
): Frag =
- Rx {
- div(
- MenuStyle.footer,
+ div(
+ MenuStyle.footer,
- if (filters().nonEmpty)
- div(
- MenuStyle.clear,
- onclick := (() => if (filters.now.nonEmpty) FilterUtils.removeAll(filters, detail, search)),
- "Effacer"
- )
- else
- span(""),
+ a(
+ MenuStyle.clear,
+ Rx(if (filters().nonEmpty) MenuStyle.clearActive else MenuStyle.empty),
+ href := Route.url(Route.Books()),
+ onclick := (() => if (filters.now.nonEmpty) FilterUtils.removeAll(filters, detail, search)),
+ "Effacer"
+ ),
- div(
- MenuStyle.returnToBooks,
- onclick := (() => showFiltersMenu() = false),
- "Afficher",
- span(MenuStyle.bookCount, books().length)
- )
+ div(
+ MenuStyle.returnToBooks,
+ onclick := (() => showFiltersMenu() = false),
+ "Afficher",
+ Rx(span(MenuStyle.bookCount, books().length))
)
- }
+ )
}
diff --git a/src/main/scala/reading/component/index/style/Books.scala b/src/main/scala/reading/component/index/style/Books.scala
index f7c1ffc..a1f0374 100644
--- a/src/main/scala/reading/component/index/style/Books.scala
+++ b/src/main/scala/reading/component/index/style/Books.scala
@@ -41,6 +41,8 @@ object Books extends StyleSheet.Inline {
display.inlineBlock,
backgroundColor(C.gray.lighten(90).value),
cursor.pointer,
+ transition := "transform 0.2s ease-in-out",
+ &.hover(transform := "scale(1.1)"),
Media.desktop(
height(250.px),
maxWidth(200.px)
diff --git a/src/main/scala/reading/component/index/style/Menu.scala b/src/main/scala/reading/component/index/style/Menu.scala
index 09f529c..d824a1a 100644
--- a/src/main/scala/reading/component/index/style/Menu.scala
+++ b/src/main/scala/reading/component/index/style/Menu.scala
@@ -101,20 +101,26 @@ object Menu extends StyleSheet.Inline {
Media.desktop(display.none),
Media.mobile(
display.flex,
- width(100.%%),
height(60.px)
)
)
val clear = style(
Commons.footerButton,
- border(2.px, solid, C.gray.value)
+ border(2.px, solid, C.gray.value),
+ opacity(0.3)
+ )
+
+ val clearActive = style(
+ opacity(1),
+ cursor.pointer
)
val returnToBooks = style(
Commons.footerButton,
backgroundColor(C.stiletto.value),
- color(C.white.value)
+ color(C.white.value),
+ cursor.pointer
)
val bookCount = style(
@@ -136,14 +142,13 @@ object Commons extends StyleSheet.Inline {
val footerButton = style(
display.flex,
- flexGrow(1),
+ width(50.%%),
justifyContent.center,
alignItems.center,
height(50.px),
margin(5.px),
textTransform.uppercase,
fontSize(14.px),
- fontWeight.bold,
- cursor.pointer
+ fontWeight.bold
)
}
diff --git a/src/main/scala/reading/component/style/Global.scala b/src/main/scala/reading/component/style/Global.scala
index b7bf38c..9551424 100644
--- a/src/main/scala/reading/component/style/Global.scala
+++ b/src/main/scala/reading/component/style/Global.scala
@@ -18,10 +18,7 @@ object Global extends StyleSheet.Standalone {
)
"a" - (
- color(C.eastBay.value),
- &.hover(
- textDecoration := "underline"
- )
+ color(inherit)
)
"*, *:before, *:after" - (
diff --git a/src/main/scala/reading/component/widget/Input.scala b/src/main/scala/reading/component/widget/Input.scala
index 1a1157e..9855c5f 100644
--- a/src/main/scala/reading/component/widget/Input.scala
+++ b/src/main/scala/reading/component/widget/Input.scala
@@ -12,6 +12,7 @@ import rx._
import reading.component.style.{ Color => C }
import reading.component.widget.style.{ Input => InputStyle }
+import reading.utils.RxUtils._
object Input {
def apply(
@@ -47,6 +48,7 @@ object Input {
inputBox,
span(
InputStyle.clear,
+ Rx(if (query().nonEmpty) InputStyle.showClear else InputStyle.empty),
onclick := (() => query() = ""),
Cross(15.px, C.gray.value)
)
diff --git a/src/main/scala/reading/component/widget/style/Input.scala b/src/main/scala/reading/component/widget/style/Input.scala
index 9453640..a9d61dc 100644
--- a/src/main/scala/reading/component/widget/style/Input.scala
+++ b/src/main/scala/reading/component/widget/style/Input.scala
@@ -26,6 +26,14 @@ object Input extends StyleSheet.Inline {
display.flex,
height(100.%%),
alignItems.center,
- cursor.pointer
+ cursor.pointer,
+ opacity(0),
+ transition := "opacity 0.2s ease-in-out"
)
+
+ val showClear = style(
+ opacity(1)
+ )
+
+ val empty = style()
}