From 59c9e1e4bfc45f843f89da22e0190d19403b4dc6 Mon Sep 17 00:00:00 2001 From: Katrin Shechtman Date: Mon, 13 Jun 2016 01:23:45 -0400 Subject: scalajs cross project support as plugin --- examples/build-scalajs/js/src/main/scala/App.scala | 22 +++++ .../build-scalajs/js/src/main/scala/Pictures.scala | 105 +++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 examples/build-scalajs/js/src/main/scala/App.scala create mode 100644 examples/build-scalajs/js/src/main/scala/Pictures.scala (limited to 'examples/build-scalajs/js') diff --git a/examples/build-scalajs/js/src/main/scala/App.scala b/examples/build-scalajs/js/src/main/scala/App.scala new file mode 100644 index 0000000..2682936 --- /dev/null +++ b/examples/build-scalajs/js/src/main/scala/App.scala @@ -0,0 +1,22 @@ +package prototype + +import japgolly.scalajs.react.ReactDOM +import org.scalajs.dom + +import scala.scalajs.js +import scala.scalajs.js.JSApp +import scala.scalajs.js.annotation.JSExport +import scalajs.js.Dynamic.{global => g} + +/** + * Created by katrin on 2016-04-10. + */ +@JSExport("App") +object App extends JSApp { + + def main(): Unit = { + + val doc = dom.document + ReactDOM.render(Pictures.PictureComponent(), doc.getElementById("main")) + } +} diff --git a/examples/build-scalajs/js/src/main/scala/Pictures.scala b/examples/build-scalajs/js/src/main/scala/Pictures.scala new file mode 100644 index 0000000..88329ee --- /dev/null +++ b/examples/build-scalajs/js/src/main/scala/Pictures.scala @@ -0,0 +1,105 @@ +package prototype + +import japgolly.scalajs.react.{ReactComponentB, BackendScope, Callback} +import org.scalajs.dom + +import scala.scalajs._ +import japgolly.scalajs.react.vdom.all._ + +import scala.scalajs.js.JSON + +/** + * Created by katrin on 2016-04-10. + */ +object Pictures { + + case class State(pictures: List[Picture], favourites: List[Picture]) + + type PicClick = (String, Boolean) => Callback + + class Backend($: BackendScope[Unit, State]) { + + def onPicClick(id: String, favorite: Boolean) = + $.state flatMap { s => + if (favorite) { + val newPics = s.pictures.map(p => if (p.id == id) p.copy(favorite = false) else p) + val newFavs = s.favourites.filter(p => p.id != id) + $.modState(_ => State(newPics, newFavs)) + } else { + var newPic: Picture = null + val newPics = s.pictures.map(p => if (p.id == id) { + newPic = p.copy(favorite = true); newPic + } else p) + val newFavs = s.favourites.+:(newPic) + $.modState(_ => State(newPics, newFavs)) + } + } + + def render(s: State) = + div( + h1("Popular Pixabay Pics"), + pictureList((s.pictures, onPicClick)), + h1("Your favorites"), + favoriteList((s.favourites, onPicClick))) + } + + val picture = ReactComponentB[(Picture, PicClick)]("picture") + .render_P { case (p, b) => + div(if (p.favorite) cls := "picture favorite" else cls := "picture", onClick --> b(p.id, p.favorite))( + img(src := p.src, title := p.title) + ) + } + .build + + val pictureList = ReactComponentB[(List[Picture], PicClick)]("pictureList") + .render_P { case (list, b) => + div(`class` := "pictures")( + if (list.isEmpty) span("Loading Pics..") + else { + list.map(p => picture.withKey(p.id)((p, b))) + } + ) + } + .build + + val favoriteList = ReactComponentB[(List[Picture], PicClick)]("favoriteList") + .render_P { case (list, b) => + div(`class` := "favorites")( + if (list.isEmpty) span("Click an image to mark as favorite") + else { + list.map(p => picture.withKey(p.id)((p, b))) + } + ) + } + .build + + val PictureComponent = ReactComponentB[Unit]("PictureComponent") + .initialState(State(Nil, Nil)) + .renderBackend[Backend] + .componentDidMount(scope => Callback { + import scalajs.js.Dynamic.{global => g} + def isDefined(g: js.Dynamic): Boolean = + g.asInstanceOf[js.UndefOr[AnyRef]].isDefined + val url = "http://localhost:3000/data" + val xhr = new dom.XMLHttpRequest() + xhr.open("GET", url) + xhr.onload = { (e: dom.Event) => + if (xhr.status == 200) { + val result = JSON.parse(xhr.responseText) + if (isDefined(result) && isDefined(result.hits)) { + val hits = result.hits.asInstanceOf[js.Array[js.Dynamic]] + val pics = hits.toList.map(item => Picture( + item.id.toString, + item.pageURL.toString, + item.previewURL.toString, + if (item.tags != null) item.tags.asInstanceOf[js.Array[String]].mkString(",") else "")) + //if (item.caption != null) item.caption.text.toString else "")) + scope.modState(_ => State(pics, Nil)).runNow() + } + } + } + xhr.send() + }) + .buildU + +} -- cgit v1.2.3