adding alpha create room capability
This commit is contained in:
parent
e1364c9b9b
commit
62d63546c4
|
@ -22,9 +22,12 @@ object MyHttpService {
|
|||
val authedRoomRoutes: AuthedRoutes[(PlayerID, RoomID), IO] =
|
||||
AuthedRoutes.of {
|
||||
case GET -> Root / "subscribe" as (playerId, roomId) => {
|
||||
val initial = Stream.evals(roomService.getRoom(roomId))
|
||||
val subscription = roomService.subscribe(roomId)
|
||||
|
||||
val send: Stream[IO, WebSocketFrame] =
|
||||
roomService
|
||||
.subscribe(roomId)
|
||||
(initial ++ subscription)
|
||||
.evalTap(state => IO(println(s">> sending room state $state to $playerId")))
|
||||
.map(state => WebSocketFrame.Text(state.getViewFor(playerId).asJson.noSpaces))
|
||||
|
||||
val receive: Pipe[IO, WebSocketFrame, Unit] = _.evalMap {
|
||||
|
@ -69,13 +72,32 @@ object MyHttpService {
|
|||
playerId <- EitherT(roomService.joinRoom(roomId, nickName, nickPassword, roomPassword))
|
||||
authCookie <- EitherT.liftF(auth.joinRoom(roomId, playerId))
|
||||
_ <- EitherT.liftF(IO(println(s"> logging in $nickName to $roomName")))
|
||||
resp <- EitherT.liftF(Ok().flatTap(resp => IO(resp.addCookie(authCookie))))
|
||||
resp = Response(Status.Ok).addCookie(authCookie)
|
||||
} yield resp
|
||||
|
||||
val response = responseOrError.leftSemiflatMap(error => Forbidden(error.toString())).merge
|
||||
|
||||
response
|
||||
}
|
||||
case req @ POST -> Root / "create-room" => {
|
||||
val responseOrError = for {
|
||||
data <- EitherT.right(req.as[Requests.LogIn])
|
||||
Requests.LogIn(roomName, nickName, roomPassword, nickPassword) = data
|
||||
room <- EitherT(roomService.createRoom(roomName, nickName, nickPassword, roomPassword))
|
||||
owner = room.players.head // TODO add check
|
||||
authCookie <- EitherT.liftF(auth.joinRoom(room.id, owner.id))
|
||||
_ <- EitherT.liftF(
|
||||
IO(println(s"> logging in $nickName to new room $room | $authCookie"))
|
||||
)
|
||||
resp = Response(Status.Ok).addCookie(authCookie)
|
||||
_ <- EitherT.liftF(IO(println(s"> about to reply $resp ${resp.cookies}")))
|
||||
} yield resp
|
||||
|
||||
val response = responseOrError.leftSemiflatMap(error => Forbidden(error.toString())).merge
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(authenticationRoute <+> authMiddleware(authedRoomRoutes)).orNotFound
|
||||
|
|
|
@ -15,7 +15,12 @@ enum RoomError {
|
|||
}
|
||||
|
||||
trait RoomService[F[_]] {
|
||||
def createRoom(newRoom: Room): F[Either[RoomError, Room]]
|
||||
def createRoom(
|
||||
roomName: String,
|
||||
nickName: String,
|
||||
nickPassword: String,
|
||||
roomPassword: String
|
||||
): F[Either[RoomError, Room]]
|
||||
def updateRoom(roomId: RoomID, roomUpd: Room => Room): F[Unit]
|
||||
def joinRoom(
|
||||
id: RoomID,
|
||||
|
@ -35,19 +40,37 @@ trait RoomService[F[_]] {
|
|||
class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room, Topic[F, Room])]])
|
||||
extends RoomService[F] {
|
||||
|
||||
override def createRoom(newRoom: Room): F[Either[RoomError, Room]] = {
|
||||
// TODO accept allowed cards and separate request
|
||||
override def createRoom(
|
||||
roomName: String,
|
||||
nickName: String,
|
||||
nickPassword: String,
|
||||
roomPassword: String
|
||||
): F[Either[RoomError, Room]] = {
|
||||
for {
|
||||
updatesTopic <- Topic[F, Room]
|
||||
room <- stateRef.modify { rooms =>
|
||||
rooms.get(newRoom.id) match {
|
||||
val roomId = RoomID(roomName)
|
||||
rooms.get(roomId) match {
|
||||
case Some(_) =>
|
||||
rooms -> RoomError.RoomAlreadyExists(newRoom.id.name).asLeft[Room]
|
||||
rooms -> RoomError.RoomAlreadyExists(roomName).asLeft[Room]
|
||||
case None =>
|
||||
(rooms.updated(newRoom.id, (newRoom, updatesTopic))) -> newRoom.asRight[RoomError]
|
||||
val ownerPlayer = Player.create(nickName)
|
||||
val newRoom = Room(
|
||||
roomId,
|
||||
players = List(ownerPlayer),
|
||||
owner = ownerPlayer.id,
|
||||
password = roomPassword,
|
||||
allowedCards = List("XS", "S", "M", "L", "XL"), // TODO accept from front
|
||||
round = RoundState.Voting(Map.empty),
|
||||
playersPasswords = Map(nickName -> nickPassword)
|
||||
)
|
||||
rooms.updated(newRoom.id, (newRoom, updatesTopic)) -> newRoom.asRight[RoomError]
|
||||
}
|
||||
}
|
||||
} yield room
|
||||
}
|
||||
|
||||
override def updateRoom(roomId: RoomID, roomUpd: Room => Room): F[Unit] = {
|
||||
for {
|
||||
// modify is function to update state and compute auxillary value to return, here - topic
|
||||
|
@ -82,8 +105,8 @@ class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room,
|
|||
roomID,
|
||||
room =>
|
||||
room.round match {
|
||||
case RoundState.Viewing(votes) => room.copy(round = RoundState.Viewing(votes))
|
||||
case RoundState.Voting(_) => room.copy(round = RoundState.Voting(Map.empty))
|
||||
case RoundState.Viewing(_) => room
|
||||
case RoundState.Voting(votes) => room.copy(round = RoundState.Viewing(votes))
|
||||
}
|
||||
)
|
||||
override def startNewPoll(roomID: RoomID, playerID: PlayerID): F[Unit] = updateRoom(
|
||||
|
@ -91,7 +114,7 @@ class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room,
|
|||
room =>
|
||||
room.round match {
|
||||
case RoundState.Viewing(_) => room.copy(round = RoundState.Voting(Map.empty))
|
||||
case RoundState.Voting(votes) => room.copy(round = RoundState.Viewing(votes))
|
||||
case RoundState.Voting(votes) => room
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -76,6 +76,32 @@ object JoinRoomComponent {
|
|||
}
|
||||
} --> responseReceived
|
||||
)
|
||||
val newRoomButton = button(
|
||||
"Create new room",
|
||||
onClick
|
||||
.mapTo {
|
||||
(roomNameVar.now(), roomPassVar.now(), nicknameVar.now(), nicknamePass.now())
|
||||
}
|
||||
.flatMap { case (roomName, roomPass, nickname, nicknamePass) =>
|
||||
Fetch
|
||||
.post(
|
||||
"/api/create-room",
|
||||
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",
|
||||
|
@ -85,6 +111,7 @@ object JoinRoomComponent {
|
|||
nameInput(nicknameVar, "Enter your nickname:"),
|
||||
passInput(nicknamePass, "nickname pass:"),
|
||||
submitButton,
|
||||
newRoomButton,
|
||||
div(
|
||||
div(
|
||||
code("received:")
|
||||
|
|
Loading…
Reference in New Issue