Browse Source

first commit

master
nova 4 years ago
committed by Rohan Sircar
commit
be847a4cd3
  1. 35
      .gitignore
  2. 1
      .scalafmt.conf
  3. 1
      Procfile
  4. 1
      README.md
  5. 58
      build.sbt
  6. 92
      client/src/main/scala/com/example/playscalajsreact/ScalaJSExample.scala
  7. 29
      client/src/main/scala/com/example/playscalajsreact/model/HelloWorldComponent.scala
  8. 4004
      client/yarn.lock
  9. 1
      project/build.properties
  10. 4
      project/metals.sbt
  11. 28
      project/plugins.sbt
  12. 15
      server/app/com/example/playscalajsreact/controllers/Application.scala
  13. 9
      server/app/views/index.scala.html
  14. 19
      server/app/views/main.scala.html
  15. 6
      server/conf/application.conf
  16. 8
      server/conf/heroku.conf
  17. 10
      server/conf/routes
  18. BIN
      server/public/images/favicon.png
  19. 0
      server/public/stylesheets/main.css
  20. 27
      server/test/ApplicationSpec.scala
  21. 5
      shared/src/main/scala/com/example/playscalajsreact/shared/SharedMessages.scala

35
.gitignore

@ -0,0 +1,35 @@
logs
project/project
project/target
target
tmp
.history
dist
.idea
*.iml
/out
.idea_modules
.classpath
.project
/RUNNING_PID
.settings
.DS_Store
# hidden cross project folders
shared/.js
shared/.jvm
# temp files
.~*
*~
*.orig
# eclipse
.scala_dependencies
.buildpath
.cache
.target
bin/
.bloop
.metals

1
.scalafmt.conf

@ -0,0 +1 @@
version = "2.4.2"

1
Procfile

@ -0,0 +1 @@
web: server/target/universal/stage/bin/server -Dhttp.port=$PORT -Dconfig.file=server/conf/heroku.conf

1
README.md

@ -0,0 +1 @@
# scalajs-react-test

58
build.sbt

@ -0,0 +1,58 @@
lazy val server = (project in file("server"))
.settings(commonSettings)
.settings(
scalaJSProjects := Seq(client),
pipelineStages in Assets := Seq(scalaJSPipeline),
pipelineStages := Seq(digest, gzip),
// triggers scalaJSPipeline when using compile or continuous compilation
compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value,
libraryDependencies ++= Seq(
"com.vmunier" %% "scalajs-scripts" % "1.1.4",
guice,
specs2 % Test
),
// Compile the project before generating Eclipse files, so that generated .scala or .class files for views and routes are present
EclipseKeys.preTasks := Seq(compile in Compile)
)
.enablePlugins(PlayScala)
// .enablePlugins(SbtWeb)
.enablePlugins(WebScalaJSBundlerPlugin)
.dependsOn(sharedJvm)
lazy val client = (project in file("client"))
.settings(commonSettings)
.settings(
scalaJSUseMainModuleInitializer := true,
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "1.0.0",
"com.github.japgolly.scalajs-react" %%% "core" % "1.7.0",
"com.github.japgolly.scalajs-react" %%% "extra" % "1.7.0",
// "com.github.japgolly.scalajs-react" %%% "test" % "1.7.0",
),
scalacOptions ++= Seq("-Ymacro-annotations","-deprecation"),
useYarn := true,
stFlavour := Flavour.Japgolly,
Compile / npmDependencies ++= Seq(
"react" -> "16.13.1",
"react-dom" -> "16.13.1",
"@types/react" -> "16.9.34",
"@types/react-dom" -> "16.9.6"
)
)
.enablePlugins(ScalaJSPlugin)
.enablePlugins(ScalaJSBundlerPlugin)
.enablePlugins(ScalablyTypedConverterPlugin)
.dependsOn(sharedJs)
lazy val shared = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("shared"))
.settings(commonSettings)
.jsConfigure(_.enablePlugins(ScalaJSWeb))
lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js
lazy val commonSettings = Seq(
scalaVersion := "2.13.2",
organization := "com.example"
)

92
client/src/main/scala/com/example/playscalajsreact/ScalaJSExample.scala

@ -0,0 +1,92 @@
package com.example.playscalajsreact
import com.example.playscalajsreact.shared.SharedMessages
import org.scalajs.dom
import japgolly.scalajs.react._
import japgolly.scalajs.react.vdom.html_<^._
import japgolly.scalajs.react.extra._
import com.example.playscalajsreact.model.HelloWorldSJSRComponent
import japgolly.scalajs.react.extra.router._
import japgolly.scalajs.react.extra.router.StaticDsl.Route
object ScalaJSExample {
def main(args: Array[String]): Unit = {
sealed trait Page
case object Home extends Page
case object Hello extends Page
case class Person(user: String) extends Page
case class ID(id: Int) extends Page
case class Menu(name: String, route: Page)
val mainMenu = Vector(
Menu("Home", Home),
Menu("Hello", Hello)
)
def layout(c: RouterCtl[Page], r: Resolution[Page]) =
<.ul(
// c.link(Home)("Home"),
// c.link(Hello)("Hello"),
mainMenu.toTagMod { item =>
{
<.li(
^.key := item.name,
item.name,
c setOnClick item.route
)
}
},
r.render()
)
val x = <.ol(
^.id := "my-list",
^.lang := "en",
^.margin := 8.px,
<.li("Item 1"),
<.li("Item 2"),
HelloWorldSJSRComponent("Hello", 18)
)
val routerConfig = RouterConfigDsl[Page].buildConfig { dsl =>
import dsl._
import japgolly.scalajs.react.vdom.Implicits._
case class Item(category: String, itemId: java.util.UUID) extends Page
// val r =
// ("category" / string("[a-z]+") / "item" / int.caseClassDebug[ID])
// FIXME uncomment this block to get an error - Companion object not found for class Product
// case class Product(category: Int, item: Int) extends Page
// val r: Route[Product] = ("cat" / int / "item" / int).caseClass[Product]
// val testRoute =
// ("user" / string("[a-z0-9]{1,20}") / "age" / int).pmap {
// case (a, b) => {}
// }
(emptyRule
| staticRoute(root, Home) ~> render(x)
// FIXME uncomment this block to get an error - Companion object not found for class Person
// | dynamicRouteCT("user" / string("[a-z0-9]{1,20}").caseClass[Person]) ~> dynRender(
// (page: Person) => {
// HelloWorldSJSRComponent(page.user, 0)
// }
// )
| staticRoute("#hello", Hello) ~> render(<.div("TODO"))
| staticRedirect("#hey") ~> redirectToPage(Hello)(SetRouteVia.HistoryReplace))
.notFound(redirectToPage(Home)(SetRouteVia.HistoryReplace))
.renderWith(layout)
}
// x.renderIntoDOM(dom.document.getElementById("app"))
val router = Router(BaseUrl.fromWindowOrigin / "index.html", routerConfig)
router().renderIntoDOM(dom.document.getElementById("app"))
dom.document.getElementById("scalajsShoutOut").textContent =
SharedMessages.itWorks
}
}

29
client/src/main/scala/com/example/playscalajsreact/model/HelloWorldComponent.scala

@ -0,0 +1,29 @@
package com.example.playscalajsreact.model
// import slinky.core.annotations.react
// import slinky.core.StatelessComponent
// import slinky.web.html.h1
import japgolly.scalajs.react._
// @react class HelloWorldComponentSlinky extends StatelessComponent {
// case class Props(name: String, age: Int)
// def render = {
// h1(s"Hello ${props.name} ${props.age}")
// }
// }
object HelloWorldSJSRComponent {
import japgolly.scalajs.react.vdom.html_<^._
case class Props(name: String, age: Int)
private val component = ScalaComponent
.builder[Props]("HelloWorldComponent")
.render_P(p => {
<.p(p.name + p.age)
})
.build
def apply(name: String, age: Int) = {
component(Props(name, age))
}
}

4004
client/yarn.lock
File diff suppressed because it is too large
View File

1
project/build.properties

@ -0,0 +1 @@
sbt.version=1.3.8

4
project/metals.sbt

@ -0,0 +1,4 @@
// DO NOT EDIT! This file is auto-generated.
// This file enables sbt-bloop to create bloop config files.
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.0-RC1-229-b7c15aa9")

28
project/plugins.sbt

@ -0,0 +1,28 @@
// Comment to get more information during initialization
logLevel := Level.Warn
// Resolvers
resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/"
resolvers += Resolver.bintrayRepo("oyvindberg", "converter")
// for Scala.js 1.x.x
addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta13")
// Sbt plugins
// Use Scala.js v1.x
addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.0.11")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.0.1")
// addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.18.0")
addSbtPlugin("ch.epfl.scala" % "sbt-web-scalajs-bundler" % "0.18.0")
// If you prefer using Scala.js v0.6.x, uncomment the following plugins instead:
// addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.1.0-0.6")
// addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.33")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.2")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.4")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")

15
server/app/com/example/playscalajsreact/controllers/Application.scala

@ -0,0 +1,15 @@
package com.example.playscalajsreact.controllers
import javax.inject._
import com.example.playscalajsreact.shared.SharedMessages
import play.api.mvc._
@Singleton
class Application @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
def index = Action {
Ok(views.html.index(SharedMessages.itWorks))
}
}

9
server/app/views/index.scala.html

@ -0,0 +1,9 @@
@(message: String)
@main("Play with Scala.js") {
<h2>Play and Scala.js share a same message</h2>
<ul>
<li>Play shouts out: <em>@message</em></li>
<li>Scala.js shouts out: <em id="scalajsShoutOut"></em></li>
</ul>
}

19
server/app/views/main.scala.html

@ -0,0 +1,19 @@
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
<!-- <script src="../../../client/target/scala-2.13/client-jsdeps.js"></script> -->
</head>
<body>
<div id="app"></div>
@content
@scalajs.html.scripts("client", routes.Assets.versioned(_).toString, name => getClass.getResource(s"/public/$name") != null)
<!-- <script src="client-fastopt-bundle.js" defer></script> -->
</body>
</html>

6
server/conf/application.conf

@ -0,0 +1,6 @@
play.i18n.langs=["en"]
play.assets {
path = "/public"
urlPrefix = "/assets"
}

8
server/conf/heroku.conf

@ -0,0 +1,8 @@
include "application"
play.http.secret.key="kUNSMzxg/<?qU1I_l?:2KXhV?5_ma=g7d2UsH;`wHc?fJKYj24YyT]KtCk8I2ZTL"
play.filters.hosts {
# Allow requests to herokuapp.com and its subdomains.
allowed += ".herokuapp.com"
}

10
server/conf/routes

@ -0,0 +1,10 @@
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / com.example.playscalajsreact.controllers.Application.index
# Prefix must match `play.assets.urlPrefix`
GET /assets/*file controllers.Assets.at(file)
GET /versionedAssets/*file controllers.Assets.versioned(path="/public", file: Asset)

BIN
server/public/images/favicon.png

After

Width: 16  |  Height: 16  |  Size: 687 B

0
server/public/stylesheets/main.css

27
server/test/ApplicationSpec.scala

@ -0,0 +1,27 @@
import org.junit.runner._
import org.specs2.runner._
import play.api.test._
/**
* Add your spec here.
* You can mock out a whole application including requests, plugins etc.
* For more information, consult the wiki.
*/
@RunWith(classOf[JUnitRunner])
class ApplicationSpec() extends PlaySpecification {
"Application" should {
"send 404 on a bad request" in new WithApplication {
route(app, FakeRequest(GET, "/boum")) must beSome.which (status(_) == NOT_FOUND)
}
"render the index page" in new WithApplication {
val home = route(app, FakeRequest(GET, "/")).get
status(home) must equalTo(OK)
contentType(home) must beSome.which(_ == "text/html")
contentAsString(home) must contain ("shouts out")
}
}
}

5
shared/src/main/scala/com/example/playscalajsreact/shared/SharedMessages.scala

@ -0,0 +1,5 @@
package com.example.playscalajsreact.shared
object SharedMessages {
def itWorks = "It works!"
}
Loading…
Cancel
Save