From e317debf1a5d639c9a5fde0f0353a7b3b7ae86a0 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sun, 13 Nov 2016 14:02:14 -0800 Subject: Basic composite app with uPickle --- .gitignore | 7 +++- app/Filters.scala | 24 ------------ app/controllers/HomeController.scala | 24 ------------ app/views/index.scala.html | 5 --- app/views/main.scala.html | 25 ------------- build.sbt | 40 ++++++++++++++------ client/src/main/scala/chat/Main.scala | 26 +++++++++++++ conf/application.conf | 1 - conf/logback.xml | 41 --------------------- conf/messages | 1 - conf/routes | 10 ----- project/plugins.sbt | 4 ++ project/scaffold.sbt | 3 -- public/images/favicon.png | Bin 687 -> 0 bytes public/javascripts/main.js | 0 public/stylesheets/main.css | 0 server/app/controllers/HomeController.scala | 28 ++++++++++++++ server/app/views/index.scala.html | 9 +++++ server/app/views/main.scala.html | 24 ++++++++++++ server/conf/application.conf | 1 + server/conf/logback.xml | 41 +++++++++++++++++++++ server/conf/messages | 1 + server/conf/routes | 11 ++++++ server/public/images/favicon.png | Bin 0 -> 687 bytes server/public/javascripts/main.js | 0 server/public/stylesheets/main.css | 0 server/test/controllers/HomeControllerSpec.scala | 45 +++++++++++++++++++++++ shared/src/main/scala/chat/Messages.scala | 3 ++ test/controllers/HomeControllerSpec.scala | 45 ----------------------- 29 files changed, 228 insertions(+), 191 deletions(-) delete mode 100644 app/Filters.scala delete mode 100644 app/controllers/HomeController.scala delete mode 100644 app/views/index.scala.html delete mode 100644 app/views/main.scala.html create mode 100644 client/src/main/scala/chat/Main.scala delete mode 100644 conf/application.conf delete mode 100644 conf/logback.xml delete mode 100644 conf/messages delete mode 100644 conf/routes delete mode 100644 project/scaffold.sbt delete mode 100644 public/images/favicon.png delete mode 100644 public/javascripts/main.js delete mode 100644 public/stylesheets/main.css create mode 100644 server/app/controllers/HomeController.scala create mode 100644 server/app/views/index.scala.html create mode 100644 server/app/views/main.scala.html create mode 100644 server/conf/application.conf create mode 100644 server/conf/logback.xml create mode 100644 server/conf/messages create mode 100644 server/conf/routes create mode 100644 server/public/images/favicon.png create mode 100644 server/public/javascripts/main.js create mode 100644 server/public/stylesheets/main.css create mode 100644 server/test/controllers/HomeControllerSpec.scala create mode 100644 shared/src/main/scala/chat/Messages.scala delete mode 100644 test/controllers/HomeControllerSpec.scala diff --git a/.gitignore b/.gitignore index eb372fc..30dd67d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,13 @@ logs -target +target/ /.idea /.idea_modules /.classpath /.project /.settings +/.ensime +/.ensime_cache/ /RUNNING_PID + +/shared/.js/ +/shared/.jvm/ diff --git a/app/Filters.scala b/app/Filters.scala deleted file mode 100644 index 81a2e15..0000000 --- a/app/Filters.scala +++ /dev/null @@ -1,24 +0,0 @@ -import javax.inject.Inject - -import play.api.http.DefaultHttpFilters - -import play.filters.csrf.CSRFFilter -import play.filters.headers.SecurityHeadersFilter -import play.filters.hosts.AllowedHostsFilter - -/** - * Add the following filters by default to all projects - * - * https://www.playframework.com/documentation/latest/ScalaCsrf - * https://www.playframework.com/documentation/latest/AllowedHostsFilter - * https://www.playframework.com/documentation/latest/SecurityHeaders - */ -class Filters @Inject() ( - csrfFilter: CSRFFilter, - allowedHostsFilter: AllowedHostsFilter, - securityHeadersFilter: SecurityHeadersFilter -) extends DefaultHttpFilters( - csrfFilter, - allowedHostsFilter, - securityHeadersFilter -) \ No newline at end of file diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala deleted file mode 100644 index 2032080..0000000 --- a/app/controllers/HomeController.scala +++ /dev/null @@ -1,24 +0,0 @@ -package controllers - -import javax.inject._ -import play.api._ -import play.api.mvc._ - -/** - * This controller creates an `Action` to handle HTTP requests to the - * application's home page. - */ -@Singleton -class HomeController @Inject() extends Controller { - - /** - * Create an Action to render an HTML page. - * - * The configuration in the `routes` file means that this method - * will be called when the application receives a `GET` request with - * a path of `/`. - */ - def index = Action { implicit request => - Ok(views.html.index()) - } -} diff --git a/app/views/index.scala.html b/app/views/index.scala.html deleted file mode 100644 index 68d37fb..0000000 --- a/app/views/index.scala.html +++ /dev/null @@ -1,5 +0,0 @@ -@() - -@main("Welcome to Play") { -

Welcome to Play!

-} diff --git a/app/views/main.scala.html b/app/views/main.scala.html deleted file mode 100644 index 808a8b8..0000000 --- a/app/views/main.scala.html +++ /dev/null @@ -1,25 +0,0 @@ -@* - * This template is called from the `index` template. This template - * handles the rendering of the page header and body tags. It takes - * two arguments, a `String` for the title of the page and an `Html` - * object to insert into the body of the page. - *@ -@(title: String)(content: Html) - - - - - @* Here's where we render the page title `String`. *@ - @title - - - - - - @* And here's where we render the `Html` object containing - * the page content. *@ - @content - - - - diff --git a/build.sbt b/build.sbt index 3a529fe..3d43cd6 100644 --- a/build.sbt +++ b/build.sbt @@ -1,17 +1,35 @@ -name := """play-scalajs-chat""" -organization := "com.lihaoyi" - version := "1.0-SNAPSHOT" +organization in ThisBuild := "com.lihaoyi" +scalaVersion in ThisBuild := "2.11.8" -lazy val root = (project in file(".")).enablePlugins(PlayScala) +lazy val server = (project in file("server")) + .enablePlugins(PlayScala) + .settings( + scalaJSProjects := Seq(client), + pipelineStages in Assets := Seq(scalaJSPipeline), + // triggers scalaJSPipeline when using compile or continuous compilation + compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value, + libraryDependencies += "com.lihaoyi" %%% "upickle" % "0.4.3" + ) + .dependsOn(sharedJvm) -scalaVersion := "2.11.8" +lazy val client = (project in file("client")) + .enablePlugins(ScalaJSPlugin, ScalaJSWeb) + .settings( + persistLauncher := true, + persistLauncher in Test := false, + libraryDependencies ++= Seq( + "org.scala-js" %%% "scalajs-dom" % "0.9.1", + "com.lihaoyi" %%% "upickle" % "0.4.3" + ) + ) + .dependsOn(sharedJs) -libraryDependencies += filters -libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test +lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared")) + .jsConfigure(_ enablePlugins ScalaJSWeb) -// Adds additional packages into Twirl -//TwirlKeys.templateImports += "com.lihaoyi.controllers._" +lazy val sharedJvm = shared.jvm +lazy val sharedJs = shared.js -// Adds additional packages into conf/routes -// play.sbt.routes.RoutesKeys.routesImport += "com.lihaoyi.binders._" +// loads the server project at sbt startup +onLoad in Global := (Command.process("project server", _: State)) compose (onLoad in Global).value diff --git a/client/src/main/scala/chat/Main.scala b/client/src/main/scala/chat/Main.scala new file mode 100644 index 0000000..c68e0d9 --- /dev/null +++ b/client/src/main/scala/chat/Main.scala @@ -0,0 +1,26 @@ +package chat + +import scala.scalajs.js + +import org.scalajs.dom +import scala.util.{ Failure, Success } +import scala.scalajs.concurrent.JSExecutionContext.Implicits.queue +import upickle.default._ + +object Main extends js.JSApp { + + def main(): Unit = { + val root = dom.document.getElementById("root") + + dom.ext.Ajax.get("/message").onComplete { + case Success(msg) if 200 <= msg.status && msg.status < 300 => + root.textContent = "OK, " + read[Message](msg.responseText).data + case Success(msg) => + root.textContent = msg.responseText + case Failure(err) => + root.textContent = "ERROR: " + err + } + //dom.document.getElementById("scalajsShoutOut").textContent = SharedMessages.itWorks + } + +} diff --git a/conf/application.conf b/conf/application.conf deleted file mode 100644 index cb94680..0000000 --- a/conf/application.conf +++ /dev/null @@ -1 +0,0 @@ -# https://www.playframework.com/documentation/latest/Configuration diff --git a/conf/logback.xml b/conf/logback.xml deleted file mode 100644 index 9df7f6e..0000000 --- a/conf/logback.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - ${application.home:-.}/logs/application.log - - %date [%level] from %logger in %thread - %message%n%xException - - - - - - %coloredLevel %logger{15} - %message%n%xException{10} - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/conf/messages b/conf/messages deleted file mode 100644 index 0226738..0000000 --- a/conf/messages +++ /dev/null @@ -1 +0,0 @@ -# https://www.playframework.com/documentation/latest/ScalaI18N diff --git a/conf/routes b/conf/routes deleted file mode 100644 index 2ac6b33..0000000 --- a/conf/routes +++ /dev/null @@ -1,10 +0,0 @@ -# Routes -# This file defines all application routes (Higher priority routes first) -# https://www.playframework.com/documentation/latest/ScalaRouting -# ~~~~ - -# An example controller showing a sample home page -GET / controllers.HomeController.index - -# Map static resources from the /public folder to the /assets URL path -GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/project/plugins.sbt b/project/plugins.sbt index b772558..d44581f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,6 @@ // The Play plugin addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9") + +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.13") + +addSbtPlugin("com.vmunier" % "sbt-web-scalajs" % "1.0.3") diff --git a/project/scaffold.sbt b/project/scaffold.sbt deleted file mode 100644 index 91355f7..0000000 --- a/project/scaffold.sbt +++ /dev/null @@ -1,3 +0,0 @@ -// Defines scaffolding (found under .g8 folder) -// sbt "g8Scaffold form" -addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.7.1") diff --git a/public/images/favicon.png b/public/images/favicon.png deleted file mode 100644 index c7d92d2..0000000 Binary files a/public/images/favicon.png and /dev/null differ diff --git a/public/javascripts/main.js b/public/javascripts/main.js deleted file mode 100644 index e69de29..0000000 diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css deleted file mode 100644 index e69de29..0000000 diff --git a/server/app/controllers/HomeController.scala b/server/app/controllers/HomeController.scala new file mode 100644 index 0000000..13bc8dc --- /dev/null +++ b/server/app/controllers/HomeController.scala @@ -0,0 +1,28 @@ +package controllers + +import play.api._ +import play.api.mvc._ +import upickle.default._ + +/** + * This controller creates an `Action` to handle HTTP requests to the + * application's home page. + */ +class HomeController extends Controller { + + /** + * Create an Action to render an HTML page. + * + * The configuration in the `routes` file means that this method + * will be called when the application receives a `GET` request with + * a path of `/`. + */ + def index = Action { implicit request => + Ok(views.html.index()) + } + + def message = Action { implicit request => + Ok(write(chat.Message("hello"))) + } + +} diff --git a/server/app/views/index.scala.html b/server/app/views/index.scala.html new file mode 100644 index 0000000..911bdaf --- /dev/null +++ b/server/app/views/index.scala.html @@ -0,0 +1,9 @@ +@() + +@main("Welcome to Play") { +
placeholder
+ + +} diff --git a/server/app/views/main.scala.html b/server/app/views/main.scala.html new file mode 100644 index 0000000..0e9906e --- /dev/null +++ b/server/app/views/main.scala.html @@ -0,0 +1,24 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + + + + + @* Here's where we render the page title `String`. *@ + @title + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + + + diff --git a/server/conf/application.conf b/server/conf/application.conf new file mode 100644 index 0000000..cb94680 --- /dev/null +++ b/server/conf/application.conf @@ -0,0 +1 @@ +# https://www.playframework.com/documentation/latest/Configuration diff --git a/server/conf/logback.xml b/server/conf/logback.xml new file mode 100644 index 0000000..9df7f6e --- /dev/null +++ b/server/conf/logback.xml @@ -0,0 +1,41 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/conf/messages b/server/conf/messages new file mode 100644 index 0000000..0226738 --- /dev/null +++ b/server/conf/messages @@ -0,0 +1 @@ +# https://www.playframework.com/documentation/latest/ScalaI18N diff --git a/server/conf/routes b/server/conf/routes new file mode 100644 index 0000000..ca64d25 --- /dev/null +++ b/server/conf/routes @@ -0,0 +1,11 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# https://www.playframework.com/documentation/latest/ScalaRouting +# ~~~~ + +# An example controller showing a sample home page +GET / controllers.HomeController.index +GET /message controllers.HomeController.message + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/server/public/images/favicon.png b/server/public/images/favicon.png new file mode 100644 index 0000000..c7d92d2 Binary files /dev/null and b/server/public/images/favicon.png differ diff --git a/server/public/javascripts/main.js b/server/public/javascripts/main.js new file mode 100644 index 0000000..e69de29 diff --git a/server/public/stylesheets/main.css b/server/public/stylesheets/main.css new file mode 100644 index 0000000..e69de29 diff --git a/server/test/controllers/HomeControllerSpec.scala b/server/test/controllers/HomeControllerSpec.scala new file mode 100644 index 0000000..836e3ef --- /dev/null +++ b/server/test/controllers/HomeControllerSpec.scala @@ -0,0 +1,45 @@ +package controllers + +import org.scalatestplus.play._ +import play.api.test._ +import play.api.test.Helpers._ + +/** + * Add your spec here. + * You can mock out a whole application including requests, plugins etc. + * + * For more information, see https://www.playframework.com/documentation/latest/ScalaTestingWithScalaTest + */ +class HomeControllerSpec extends PlaySpec with OneAppPerTest { + + "HomeController GET" should { + + "render the index page from a new instance of controller" in { + val controller = new HomeController + val home = controller.index().apply(FakeRequest()) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the application" in { + val controller = app.injector.instanceOf[HomeController] + val home = controller.index().apply(FakeRequest()) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the router" in { + // Need to specify Host header to get through AllowedHostsFilter + val request = FakeRequest(GET, "/").withHeaders("Host" -> "localhost") + val home = route(app, request).get + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + } +} diff --git a/shared/src/main/scala/chat/Messages.scala b/shared/src/main/scala/chat/Messages.scala new file mode 100644 index 0000000..deff8eb --- /dev/null +++ b/shared/src/main/scala/chat/Messages.scala @@ -0,0 +1,3 @@ +package chat + +case class Message(data: String) diff --git a/test/controllers/HomeControllerSpec.scala b/test/controllers/HomeControllerSpec.scala deleted file mode 100644 index 836e3ef..0000000 --- a/test/controllers/HomeControllerSpec.scala +++ /dev/null @@ -1,45 +0,0 @@ -package controllers - -import org.scalatestplus.play._ -import play.api.test._ -import play.api.test.Helpers._ - -/** - * Add your spec here. - * You can mock out a whole application including requests, plugins etc. - * - * For more information, see https://www.playframework.com/documentation/latest/ScalaTestingWithScalaTest - */ -class HomeControllerSpec extends PlaySpec with OneAppPerTest { - - "HomeController GET" should { - - "render the index page from a new instance of controller" in { - val controller = new HomeController - val home = controller.index().apply(FakeRequest()) - - status(home) mustBe OK - contentType(home) mustBe Some("text/html") - contentAsString(home) must include ("Welcome to Play") - } - - "render the index page from the application" in { - val controller = app.injector.instanceOf[HomeController] - val home = controller.index().apply(FakeRequest()) - - status(home) mustBe OK - contentType(home) mustBe Some("text/html") - contentAsString(home) must include ("Welcome to Play") - } - - "render the index page from the router" in { - // Need to specify Host header to get through AllowedHostsFilter - val request = FakeRequest(GET, "/").withHeaders("Host" -> "localhost") - val home = route(app, request).get - - status(home) mustBe OK - contentType(home) mustBe Some("text/html") - contentAsString(home) must include ("Welcome to Play") - } - } -} -- cgit v1.2.3