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]] def render(loggedIn: Observer[Boolean]): Element = { 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.map { response => if (response.ok) { loggedIn.onNext(true) response } else response } } --> responseReceived ) 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) ) ) ) } ) ) ) } }