-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Finished version 6 using Scala.js for the client-side.
- Loading branch information
1 parent
de2c552
commit 3814fed
Showing
13 changed files
with
272 additions
and
17 deletions.
There are no files selected for viewing
11 changes: 0 additions & 11 deletions
11
client/src/main/scala/edu/trinity/webapps/ScalaJSExample.scala
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package playscala | ||
|
||
import play.api.libs.json.JsError | ||
import org.scalajs.dom.experimental.Headers | ||
import org.scalajs.dom.experimental.Fetch | ||
import org.scalajs.dom.experimental.HttpMethod | ||
import org.scalajs.dom.experimental.RequestInit | ||
import play.api.libs.json.Json | ||
import play.api.libs.json.JsSuccess | ||
import play.api.libs.json.Writes | ||
import play.api.libs.json.Reads | ||
import scala.scalajs.js.Thenable.Implicits._ | ||
import scala.concurrent.ExecutionContext | ||
|
||
|
||
object FetchJson { | ||
def fetchPost[A, B](url: String, csrfToken: String, | ||
data: A, success: B => Unit, error: JsError => Unit)(implicit | ||
writes: Writes[A], reads: Reads[B], ec: ExecutionContext): Unit = { | ||
val headers = new Headers() | ||
headers.set("Content-Type", "application/json") | ||
headers.set("Csrf-Token", csrfToken) | ||
Fetch.fetch(url, RequestInit(method = HttpMethod.POST, | ||
headers = headers, body = Json.toJson(data).toString)) | ||
.flatMap(res => res.text()) | ||
.map { data => | ||
Json.fromJson[B](Json.parse(data)) match { | ||
case JsSuccess(b, path) => | ||
success(b) | ||
case e @ JsError(_) => | ||
error(e) | ||
} | ||
} | ||
} | ||
|
||
def fetchGet[B](url: String, success: B => Unit, error: JsError => Unit)(implicit | ||
reads: Reads[B], ec: ExecutionContext): Unit = { | ||
Fetch.fetch(url) | ||
.flatMap(res => res.text()) | ||
.map { data => | ||
Json.fromJson[B](Json.parse(data)) match { | ||
case JsSuccess(b, path) => | ||
success(b) | ||
case e @ JsError(_) => | ||
error(e) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package playscala | ||
|
||
import shared.SharedMessages | ||
import org.scalajs.dom | ||
import org.scalajs.dom.html | ||
|
||
object ScalaJSExample { | ||
|
||
def main(args: Array[String]): Unit = { | ||
println("This is in Scala.js.") | ||
if (dom.document.getElementById("scalajsShoutOut") != null) { | ||
dom.document.getElementById("scalajsShoutOut").textContent = SharedMessages.itWorks | ||
} | ||
|
||
if (dom.document.getElementById("version6") != null) { | ||
Version6.init() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package playscala | ||
|
||
import org.scalajs.dom | ||
import org.scalajs.dom.document | ||
import org.scalajs.dom.html | ||
import org.scalajs.dom.experimental.Fetch | ||
import org.scalajs.dom.experimental.Headers | ||
import org.scalajs.dom.experimental.RequestInit | ||
import org.scalajs.dom.experimental.HttpMethod | ||
import org.scalajs.dom.experimental.RequestMode | ||
import play.api.libs.json.Json | ||
import models.ReadsAndWrites._ | ||
import scala.scalajs.js.Thenable.Implicits._ | ||
import play.api.libs.json.JsSuccess | ||
import play.api.libs.json.JsError | ||
import scala.concurrent.ExecutionContext | ||
import scala.scalajs.js.annotation.JSExportTopLevel | ||
import scalajs.js | ||
import models.TaskItem | ||
|
||
object Version6 { | ||
implicit val ec = ExecutionContext.global | ||
|
||
val csrfToken = document.getElementById("csrfToken").asInstanceOf[html.Input].value | ||
val validateRoute = document.getElementById("validateRoute").asInstanceOf[html.Input].value | ||
val tasksRoute = document.getElementById("tasksRoute").asInstanceOf[html.Input].value | ||
val createRoute = document.getElementById("createRoute").asInstanceOf[html.Input].value | ||
val deleteRoute = document.getElementById("deleteRoute").asInstanceOf[html.Input].value | ||
val addRoute = document.getElementById("addRoute").asInstanceOf[html.Input].value | ||
val logoutRoute = document.getElementById("logoutRoute").asInstanceOf[html.Input].value | ||
|
||
def init(): Unit = { | ||
println("In version 6.") | ||
} | ||
|
||
@JSExportTopLevel("login") | ||
def login(): Unit = { | ||
val username = document.getElementById("loginName").asInstanceOf[html.Input].value | ||
val password = document.getElementById("loginPass").asInstanceOf[html.Input].value | ||
val data = models.UserData(username, password) | ||
FetchJson.fetchPost(validateRoute, csrfToken, data, (bool: Boolean) => { | ||
if(bool) { | ||
document.getElementById("login-section").asInstanceOf[js.Dynamic].hidden = true | ||
document.getElementById("task-section").asInstanceOf[js.Dynamic].hidden = false | ||
document.getElementById("login-message").innerHTML = "" | ||
document.getElementById("create-message").innerHTML = "" | ||
document.getElementById("loginName").asInstanceOf[html.Input].value = "" | ||
document.getElementById("loginPass").asInstanceOf[html.Input].value = "" | ||
loadTasks() | ||
} else { | ||
document.getElementById("login-message").innerHTML = "Login Failed" | ||
} | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
|
||
@JSExportTopLevel("createUser") | ||
def createUser(): Unit = { | ||
val username = document.getElementById("createName").asInstanceOf[html.Input].value | ||
val password = document.getElementById("createPass").asInstanceOf[html.Input].value | ||
val data = models.UserData(username, password) | ||
FetchJson.fetchPost(createRoute, csrfToken, data, (bool: Boolean) => { | ||
if(bool) { | ||
document.getElementById("login-section").asInstanceOf[js.Dynamic].hidden = true | ||
document.getElementById("task-section").asInstanceOf[js.Dynamic].hidden = false | ||
document.getElementById("login-message").innerHTML = "" | ||
document.getElementById("create-message").innerHTML = "" | ||
document.getElementById("createName").asInstanceOf[html.Input].value = "" | ||
document.getElementById("createPass").asInstanceOf[html.Input].value = "" | ||
loadTasks() | ||
} else { | ||
document.getElementById("create-message").innerHTML = "User Creation Failed" | ||
} | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
|
||
def loadTasks(): Unit = { | ||
val ul = document.getElementById("task-list") | ||
ul.innerHTML = "" | ||
FetchJson.fetchGet(tasksRoute, (tasks: Seq[TaskItem]) => { | ||
for (task <- tasks) { | ||
val li = document.createElement("li") | ||
val text = document.createTextNode(task.text) | ||
li.appendChild(text); | ||
li.asInstanceOf[html.LI].onclick = e => { | ||
delete(task.id) | ||
} | ||
ul.appendChild(li) | ||
} | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
|
||
def delete(id: Int): Unit = { | ||
FetchJson.fetchPost(deleteRoute, csrfToken, id, (bool: Boolean) => { | ||
if(bool) { | ||
document.getElementById("task-message").innerHTML = "" | ||
loadTasks() | ||
} else { | ||
document.getElementById("task-message").innerHTML = "Failed to delete." | ||
} | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
|
||
@JSExportTopLevel("addTask") | ||
def addTask(): Unit = { | ||
val task = document.getElementById("newTask").asInstanceOf[html.Input].value | ||
FetchJson.fetchPost(addRoute, csrfToken, task, (bool: Boolean) => { | ||
if(bool) { | ||
loadTasks() | ||
document.getElementById("newTask").asInstanceOf[html.Input].value = "" | ||
document.getElementById("task-message").innerHTML = "" | ||
} else { | ||
document.getElementById("task-message").innerHTML = "Failed to add." | ||
} | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
|
||
@JSExportTopLevel("logout") | ||
def logout(): Unit = { | ||
FetchJson.fetchGet(logoutRoute, (bool: Boolean) => { | ||
document.getElementById("login-section").asInstanceOf[js.Dynamic].hidden = false; | ||
document.getElementById("task-section").asInstanceOf[js.Dynamic].hidden = true; | ||
}, e => { | ||
println("Fetch error: " + e) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +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-105-118a551b") | ||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.0-RC1-190-ef7d8dba") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package controllers | ||
|
||
import javax.inject._ | ||
|
||
import play.api.mvc._ | ||
import play.api.i18n._ | ||
import models.TaskListInMemoryModel | ||
import play.api.libs.json._ | ||
import models._ | ||
|
||
@Singleton | ||
class TaskList6 @Inject() (cc: ControllerComponents) extends AbstractController(cc) { | ||
def load = Action { implicit request => | ||
Ok(views.html.version6Main()) | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
@()(implicit request: RequestHeader, flash: Flash) | ||
|
||
@main("Task List 6"){ | ||
<div id="contents">Version 6</div> | ||
|
||
<div id="login-section"> | ||
<h2>Login:</h2> | ||
<br> | ||
Username: <input type="text" id="loginName"> | ||
<br> | ||
Password: <input type="password" id="loginPass"> | ||
<br> | ||
<button onclick="login()">Login</button><span id="login-message"></span> | ||
|
||
<h2>Create User:</h2> | ||
<br> | ||
Username: <input type="text" id="createName"> | ||
<br> | ||
Password: <input type="password" id="createPass"> | ||
<br> | ||
<button onclick="createUser()">Create User</button><span id="create-message"></span> | ||
</div> | ||
|
||
<div id="task-section" hidden> | ||
<h2>Task List</h2> | ||
|
||
<ul id="task-list"> | ||
</ul> | ||
|
||
<input type="text" id="newTask"></input> | ||
<button onclick="addTask()">Add Task</button><span id="task-message"></span> | ||
|
||
<div> | ||
<button onclick="logout()">Logout</button> | ||
</div> | ||
</div> | ||
|
||
<input type="hidden" id="version6" value=""> | ||
<input type="hidden" id="csrfToken" value="@helper.CSRF.getToken.value"> | ||
<input type="hidden" id="validateRoute" value="@routes.TaskList5.validate()"> | ||
<input type="hidden" id="tasksRoute" value="@routes.TaskList5.taskList()"> | ||
<input type="hidden" id="createRoute" value="@routes.TaskList5.createUser()"> | ||
<input type="hidden" id="deleteRoute" value="@routes.TaskList5.delete()"> | ||
<input type="hidden" id="addRoute" value="@routes.TaskList5.addTask()"> | ||
<input type="hidden" id="logoutRoute" value="@routes.TaskList5.logout()"> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.