Skip to content

Commit

Permalink
Update towards Diode 1.0.0 and Boopickle 1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
ochrons committed Jun 20, 2016
1 parent ddf7b08 commit 80b5219
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 22 deletions.
8 changes: 5 additions & 3 deletions client/src/main/scala/spatutorial/client/SPAMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,24 @@ object SPAMain extends js.JSApp {
val routerConfig = RouterConfigDsl[Loc].buildConfig { dsl =>
import dsl._

val todoWrapper = SPACircuit.connect(_.todos)
// wrap/connect components to the circuit
(staticRoute(root, DashboardLoc) ~> renderR(ctl => SPACircuit.wrap(_.motd)(proxy => Dashboard(ctl, proxy)))
| staticRoute("#todo", TodoLoc) ~> renderR(ctl => SPACircuit.connect(_.todos)(Todo(_)))
| staticRoute("#todo", TodoLoc) ~> renderR(ctl => todoWrapper(Todo(_)))
).notFound(redirectToPage(DashboardLoc)(Redirect.Replace))
}.renderWith(layout)

val todoCountWrapper = SPACircuit.connect(_.todos.map(_.items.count(!_.completed)).toOption)
// base layout for all pages
def layout(c: RouterCtl[Loc], r: Resolution[Loc]) = {
<.div(
// here we use plain Bootstrap class names as these are specific to the top level layout defined here
<.nav(^.className := "navbar navbar-inverse navbar-fixed-top",
<.nav(^.className := "navbar navbar-fixed-top",
<.div(^.className := "container",
<.div(^.className := "navbar-header", <.span(^.className := "navbar-brand", "SPA Tutorial")),
<.div(^.className := "collapse navbar-collapse",
// connect menu to model, because it needs to update when the number of open todos changes
SPACircuit.connect(_.todos.map(_.items.count(!_.completed)).toOption)(proxy => MainMenu(c, r.page, proxy))
todoCountWrapper(proxy => MainMenu(c, r.page, proxy))
)
)
),
Expand Down
28 changes: 20 additions & 8 deletions client/src/main/scala/spatutorial/client/modules/Dashboard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package spatutorial.client.modules

import diode.data.Pot
import diode.react._
import japgolly.scalajs.react.ReactComponentB
import japgolly.scalajs.react._
import japgolly.scalajs.react.extra.router.RouterCtl
import japgolly.scalajs.react.vdom.prefix_<^._
import spatutorial.client.SPAMain.{Loc, TodoLoc}
Expand All @@ -24,19 +24,31 @@ object Dashboard {
)
)

// create the React component for Dashboard
private val component = ReactComponentB[Props]("Dashboard")
.render_P { case Props(router, proxy) =>
class Backend($: BackendScope[Props, Unit]) {
var motdWrapper: ReactComponentC.ReqProps[(ModelProxy[Pot[String]]) => ReactElement, Pot[String], _, TopNode] = _

def render(props: Props) = {
<.div(
// header, MessageOfTheDay and chart components
<.h2("Dashboard"),
// use connect from ModelProxy to give Motd only partial view to the model
proxy.connect(m => m)(Motd(_)),
motdWrapper(Motd(_)),
Chart(cp),
// create a link to the To Do view
<.div(router.link(TodoLoc)("Check your todos!"))
<.div(props.router.link(TodoLoc)("Check your todos!"))
)
}.build
}

def willMount(props: Props) = Callback {
// use connect from ModelProxy to give Motd only partial view to the model
motdWrapper = props.proxy.connect(m => m)
}
}

// create the React component for Dashboard
private val component = ReactComponentB[Props]("Dashboard")
.renderBackend[Backend]
.componentWillMount(scope => scope.backend.willMount(scope.props))
.build

def apply(router: RouterCtl[Loc], proxy: ModelProxy[Pot[String]]) = component(Props(router, proxy))
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import boopickle.Default._
import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue

// Actions
case object RefreshTodos
case object RefreshTodos extends Action

case class UpdateAllTodos(todos: Seq[TodoItem])
case class UpdateAllTodos(todos: Seq[TodoItem]) extends Action

case class UpdateTodo(item: TodoItem)
case class UpdateTodo(item: TodoItem) extends Action

case class DeleteTodo(item: TodoItem)
case class DeleteTodo(item: TodoItem) extends Action

case class UpdateMotd(potResult: Pot[String] = Empty) extends PotAction[String, UpdateMotd] {
override def next(value: Pot[String]) = UpdateMotd(value)
Expand Down Expand Up @@ -47,7 +47,7 @@ case class Todos(items: Seq[TodoItem]) {
class TodoHandler[M](modelRW: ModelRW[M, Pot[Todos]]) extends ActionHandler(modelRW) {
override def handle = {
case RefreshTodos =>
effectOnly(Effect(AjaxClient[Api].getTodos().call().map(UpdateAllTodos)))
effectOnly(Effect(AjaxClient[Api].getAllTodos().call().map(UpdateAllTodos)))
case UpdateAllTodos(todos) =>
// got new todos, update model
updated(Ready(Todos(todos)))
Expand Down Expand Up @@ -80,7 +80,7 @@ object SPACircuit extends Circuit[RootModel] with ReactConnector[RootModel] {
// initial application model
override protected def initialModel = RootModel(Empty, Empty)
// combine all handlers into one
override protected val actionHandler = foldHandlers(
override protected val actionHandler = composeHandlers(
new TodoHandler(zoomRW(_.todos)((m, v) => m.copy(todos = v))),
new MotdHandler(zoomRW(_.motd)((m, v) => m.copy(motd = v)))
)
Expand Down
4 changes: 2 additions & 2 deletions project/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ object Settings {
val scalaCSS = "0.4.1"
val log4js = "1.4.10"
val autowire = "0.2.5"
val booPickle = "1.1.2"
val diode = "0.5.1"
val booPickle = "1.2.1-SNAPSHOT"
val diode = "1.0.0-SNAPSHOT"
val uTest = "0.3.1"

val react = "15.1.0"
Expand Down
5 changes: 3 additions & 2 deletions server/src/main/scala/services/ApiService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ class ApiService extends Api {
TodoItem("4", 0x61626364, "Sneeze in front of the pope. Get blessed.", TodoNormal, completed = true)
)

override def welcomeMsg(name: String): String = s"Welcome to SPA, $name! Time is now ${new Date}"
override def welcomeMsg(name: String): String =
s"Welcome to SPA, $name! Time is now ${new Date}"

override def getTodos(): Seq[TodoItem] = {
override def getAllTodos(): Seq[TodoItem] = {
// provide some fake Todos
Thread.sleep(300)
println(s"Sending ${todos.size} Todo items")
Expand Down
2 changes: 1 addition & 1 deletion shared/src/main/scala/spatutorial/shared/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ trait Api {
def welcomeMsg(name: String): String

// get Todo items
def getTodos(): Seq[TodoItem]
def getAllTodos(): Seq[TodoItem]

// update a Todo
def updateTodo(item: TodoItem): Seq[TodoItem]
Expand Down

0 comments on commit 80b5219

Please sign in to comment.