package com.example.playscalajsreact.component import com.example.playscalajsreact.model.MyGlobalState import japgolly.scalajs.react.vdom.VdomElement import japgolly.scalajs.react._ import japgolly.scalajs.react.vdom.html_<^._ import com.example.playscalajsreact.route.AppRouter import com.example.playscalajsreact.model.User import japgolly.scalajs.react.extra.StateSnapshot // import com.softwaremill.quicklens._ import com.example.playscalajsreact.model._ object Top { final class Backend($ : BackendScope[Unit, Data]) { private val setStateFn = StateSnapshot.withReuse.prepareVia($) def render(state: Data): VdomElement = { val ss = setStateFn(state) // Middle.Props("Demo", ss).render Middle(Middle.Props("Demo", ss)) } } val Comp = ScalaComponent .builder[Unit] .initialState(Data(123, "hello")) .renderBackend[Backend] .build } object Top2 { import japgolly.scalajs.react.vdom.all._ import japgolly.scalajs.react.MonocleReact._ final class Backend($ : BackendScope[Unit, MyGlobalState]) { private val setStateFn = StateSnapshot.withReuse.prepareVia($) def render(state: MyGlobalState): VdomElement = { // val ss = StateSnapshot.zoomL(MyGlobalState.user)(state).setStateVia($) // val ss2 = ss.xmapState(u => Snappy.State(u))(_.user) // div(Snappy.Props(ss2).render) val ss = setStateFn(state) div( // Middle2.Props("Middle2", ss).render, AppRouter.router(AppRouter.Props(ss)), "Value: ", state.user.map(_.username) ) } } val Top2Component = ScalaComponent .builder[Unit]("Top2") .initialState(MyGlobalState(Some(User("testuser")))) // .initialState(MyGlobalState.empty) .renderBackend[Backend] .build def apply(): VdomElement = Top2Component() } object Middle2 { import japgolly.scalajs.react.MonocleReact._ import monocle.macros.syntax.lens._ import monocle.std.option._ import monocle.macros.GenIso import cats.implicits._ // val navigateToUsername = GenIso[MyGlobalState, Option[User]] // .composePrism(GenIso[User, String].asPrism.below[Option]) val navigateToUsername = MyGlobalState.user.composePrism(GenIso[User, String].asPrism.below[Option]) final case class Props(name: String, ss: StateSnapshot[MyGlobalState]) { @inline def render: VdomElement = Comp(this) } implicit def reusability: Reusability[Props] = Reusability.derive final class Backend($ : BackendScope[Props, Unit]) { // Method 2: StateSnapshot.withReuse.zoomL.prepareViaProps // Notice that we're using a normal lens here instead of a Reusable[lens] private val ssStrFn = StateSnapshot.withReuse.zoomL(MyGlobalState.user).prepareViaProps($)(_.ss) def render(p: Props): VdomElement = { val x = p.ss.zoomStateO(navigateToUsername) val y = x.map(_.xmapState(_ => 1)(_ => None)) // Method 1: ss.withReuse.zoomStateL // val ssI: StateSnapshot[Int] = p.ss.zoomStateL(Data.reusableLens.int) // Method 2: StateSnapshot.withReuse.zoomL.prepareViaProps // val ssS: StateSnapshot[String] = // ssStrFn(p.ss.value) val ss4 = p.ss.zoomStateL(MyGlobalState.user) // val ss5 = p.ss.zoomStateO(navigateToUsername.asOptional) // val ss6 = // ss5.map(_.xmapState(_.map(n => User(n)))(_.map(u => u.username))) // ss5.foreach(_.modState(e => e)) // val x = p.ss.value.lens(_.user.getOrElse(User.empty).username) // p.ss.zoomStateO() val ss2 = ss4.xmapState(u => Snappy.State(u))(_.user) <.div( <.h3(p.name), <.div("Snappy", Snappy.Props(ss2).render) ) } } val Comp = ScalaComponent .builder[Props] .renderBackend[Backend] // .configure(Reusability.shouldComponentUpdate) .build def apply(_props: Props): VdomElement = { Comp(_props) } } object Snappy { final case class Props(state: StateSnapshot[State]) { @inline def render: VdomElement = Component(this) } //implicit val reusabilityProps: Reusability[Props] = // Reusability.derive final case class State(user: Option[User]) object State { def empty = State(user = None) //implicit val reusability: Reusability[State] = // Reusability.derive } final class Backend($ : BackendScope[Props, Unit]) { import com.softwaremill.quicklens._ def render(p: Props): VdomNode = { val s = p.state.value <.div("Test", s.user.map(u => { <.div( "Username", u.username, ^.onClick --> p.state.modState( _.modify(_.user.each.username).using(_ + "c") ) ) })) } } val Component = ScalaComponent .builder[Props]("Snappy") .renderBackend[Backend] //.configure(Reusability.shouldComponentUpdate) .build }