new Join Room form that requests authcookie
getting stubbed session #1, with auth module stubbed to accept that session in. and stubbed method for streaming room state, but that's enough to start testing room calling api's for other actions next - pass in observable from parent to re-toggle subscription websocket after successful login
This commit is contained in:
@@ -59,7 +59,8 @@ object Main {
|
||||
className := "h-24 w-full flex flex-for justify-center items-center bg-green-200",
|
||||
p(className := "text-2xl", "Here be header")
|
||||
),
|
||||
RoomView.renderRoom(stateSignal),
|
||||
child <-- roomStateWSStream.isConnected.map( if (_) emptyNode else JoinRoomComponent.render()),
|
||||
child <-- roomStateWSStream.isConnected.map( if (_) RoomView.renderRoom(stateSignal) else emptyNode),
|
||||
roomStateWSStream.connect
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package industries.sunshine.planningpoker
|
||||
|
||||
import scala.scalajs.js
|
||||
import scala.scalajs.js.annotation.*
|
||||
import com.raquo.laminar.api.L.{*, given}
|
||||
import io.laminext.fetch.Fetch
|
||||
import io.laminext.fetch.circe._
|
||||
|
||||
import scala.util.Failure
|
||||
import scala.util.Success
|
||||
|
||||
|
||||
import concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
object JoinRoomComponent {
|
||||
// TODO inputs for room name, room password, nick name, nick password
|
||||
// do the get to /login route
|
||||
// display errors if any.
|
||||
// but then what? attempt to start the websocket?
|
||||
// and if websocket closed show this component,
|
||||
// if it's open - doesn't show this component, show the room.
|
||||
// i suppose it should be managed on a level up
|
||||
// or rather what? ws stream should be retried every time someone presses submit button
|
||||
// and receives 200 ok
|
||||
// so, parent page should send in observer for the successful auth. and on that observer - start \ restart the websocket
|
||||
def nameInput(data: Var[String], placeholderText: String) = input(
|
||||
className := "border-2 m-1 rounded",
|
||||
placeholder := placeholderText,
|
||||
controlled(
|
||||
value <-- data.signal,
|
||||
onInput.mapToValue --> data.writer
|
||||
)
|
||||
)
|
||||
def passInput(data: Var[String], placeholderText: String) = input(
|
||||
tpe := "password",
|
||||
className := "border-2 m-1 rounded",
|
||||
placeholder := placeholderText,
|
||||
controlled(
|
||||
value <-- data.signal,
|
||||
onInput.mapToValue --> data.writer
|
||||
)
|
||||
)
|
||||
|
||||
val roomNameVar = Var("testroom")
|
||||
val roomPassVar = Var("password")
|
||||
val nicknameVar = Var("me")
|
||||
val nicknamePass = Var("nickpass")
|
||||
|
||||
val (responsesStream, responseReceived) = EventStream.withCallback[FetchResponse[String]]
|
||||
|
||||
val submitButton = button(
|
||||
"Join room",
|
||||
onClick
|
||||
.mapTo {
|
||||
(roomNameVar.now(), roomPassVar.now(), nicknameVar.now(), nicknamePass.now())
|
||||
}
|
||||
.flatMap { case (roomName, roomPass, nickname, nicknamePass) =>
|
||||
Fetch
|
||||
.post(
|
||||
"/api/login",
|
||||
body = Requests.LogIn(
|
||||
roomName,
|
||||
nickname,
|
||||
roomPass,
|
||||
nicknamePass
|
||||
)
|
||||
)
|
||||
.text
|
||||
} --> responseReceived
|
||||
)
|
||||
|
||||
def render(): Element = {
|
||||
div(
|
||||
className := "flex flex-col h-full justify-center",
|
||||
"Logging in:",
|
||||
nameInput(roomNameVar, "Enter room name:"),
|
||||
passInput(roomPassVar, "room password"),
|
||||
nameInput(nicknameVar, "Enter your nickname:"),
|
||||
passInput(nicknamePass, "nickname pass:"),
|
||||
submitButton,
|
||||
div(
|
||||
div(
|
||||
code("received:")
|
||||
),
|
||||
div(
|
||||
cls := "flex flex-col space-y-4 p-4 max-h-96 overflow-auto bg-gray-900",
|
||||
children.command <-- responsesStream.recoverToTry.map {
|
||||
case Success(response) =>
|
||||
CollectionCommand.Append(
|
||||
div(
|
||||
div(
|
||||
cls := "flex space-x-2 items-center",
|
||||
code(cls := "text-green-500", "Status: "),
|
||||
code(cls := "text-green-300", s"${response.status} ${response.statusText}")
|
||||
),
|
||||
div(
|
||||
cls := "text-green-400 text-xs",
|
||||
code(response.data)
|
||||
)
|
||||
)
|
||||
)
|
||||
case Failure(exception) =>
|
||||
CollectionCommand.Append(
|
||||
div(
|
||||
div(
|
||||
cls := "flex space-x-2 items-center",
|
||||
code(cls := "text-red-500", "Error: "),
|
||||
code(cls := "text-red-300", exception.getMessage)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user