Compare commits

..

2 Commits

Author SHA1 Message Date
efim 77b34a2ca7 change Map to List in model, scalajs didn't decode 2023-04-23 23:15:59 +04:00
efim f3e51a4750 fixing websocket, it was misspelled port
wow. just wow
2023-04-23 23:01:51 +04:00
5 changed files with 9 additions and 34 deletions

View File

@ -26,7 +26,7 @@ object MyHttpService {
val send: Stream[IO, WebSocketFrame] = val send: Stream[IO, WebSocketFrame] =
Stream Stream
.emits(TestModels.testChangesList) .emits(TestModels.testChangesList)
.covary[IO].metered(5.second).map(state => WebSocketFrame.Text(state.asJson.noSpaces)) .covary[IO].metered(2.second).map(state => WebSocketFrame.Text(state.asJson.noSpaces))
val receive: Pipe[IO, WebSocketFrame, Unit] = _.evalMap { val receive: Pipe[IO, WebSocketFrame, Unit] = _.evalMap {
case WebSocketFrame.Text(text, _) => Sync[IO].delay(println(text)) case WebSocketFrame.Text(text, _) => Sync[IO].delay(println(text))

View File

@ -22,10 +22,6 @@ object Models {
} }
object RoomStateView { object RoomStateView {
given Encoder[Map[PlayerID, String]] = Encoder.encodeMap[PlayerID, String]
given Decoder[Map[PlayerID, String]] = Decoder.decodeMap[PlayerID, String]
given Codec[Map[PlayerID, String]] = Codec.from(summon[Decoder[Map[PlayerID, String]]], summon[Encoder[Map[PlayerID, String]]])
val empty = RoomStateView( val empty = RoomStateView(
List.empty, PlayerID(0), List.empty, RoundState.Voting(None, List.empty), false List.empty, PlayerID(0), List.empty, RoundState.Voting(None, List.empty), false
) )
@ -45,16 +41,9 @@ object Models {
/** view state for round after opening the votes /** view state for round after opening the votes
*/ */
case Viewing( case Viewing(
votes: Map[PlayerID, String] votes: List[(PlayerID, String)]
) )
final case class PlayerID(id: Long) derives Codec.AsObject final case class PlayerID(id: Long) derives Codec.AsObject
object PlayerID {
given KeyEncoder[PlayerID] with
def apply(key: PlayerID): String = key.toString
given KeyDecoder[PlayerID] with
def apply(key: String): Option[PlayerID] = key.toLongOption.map(PlayerID.apply(_))
}
final case class Player(name: String, id: PlayerID) derives Codec.AsObject final case class Player(name: String, id: PlayerID) derives Codec.AsObject

View File

@ -23,7 +23,7 @@ object TestModels {
me = me.id, me = me.id,
allowedCards = List("xs", "s", "m", "l", "xl"), allowedCards = List("xs", "s", "m", "l", "xl"),
round = RoundState.Viewing( round = RoundState.Viewing(
Map(me.id -> "xs", pony.id -> "l", birdy.id -> "s", horsey.id -> "m") List(me.id -> "xs", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
), ),
canCloseRound = true canCloseRound = true
) )
@ -98,7 +98,7 @@ object TestModels {
me = me.id, me = me.id,
allowedCards = List("xs", "s", "m", "l", "xl"), allowedCards = List("xs", "s", "m", "l", "xl"),
round = RoundState.Viewing( round = RoundState.Viewing(
Map(me.id -> "m", pony.id -> "l", birdy.id -> "s", horsey.id -> "m") List(me.id -> "m", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
), ),
canCloseRound = true canCloseRound = true
) )

View File

@ -30,9 +30,7 @@ object Main {
import io.laminext.websocket.circe.WebSocket._ import io.laminext.websocket.circe.WebSocket._
import io.laminext.websocket.circe.webSocketReceiveBuilderSyntax import io.laminext.websocket.circe.webSocketReceiveBuilderSyntax
val roomStateWSStream = io.laminext.websocket.circe.WebSocket val roomStateWSStream = io.laminext.websocket.WebSocket.path("/api/subscribe").json[RoomStateView, Unit]
.url("ws://0.0.0.0:5153/api/subscribe")
.json[RoomStateView, Unit]
.build( .build(
managed = true, managed = true,
autoReconnect = false, autoReconnect = false,
@ -44,7 +42,7 @@ object Main {
val stateStream = roomStateWSStream.received val stateStream = roomStateWSStream.received
// and what's the difference between EventStream and Signal??? // and what's the difference between EventStream and Signal???
val stateSignal = val stateSignal =
stateStream.startWith(TestModels.testRoom, cacheInitialValue = true) stateStream.startWith(RoomStateView.empty)
// NOTE let's try with fetch \ rest // NOTE let's try with fetch \ rest
// import io.laminext.fetch.Fetch // import io.laminext.fetch.Fetch
@ -56,23 +54,11 @@ object Main {
def appElement(): Element = { def appElement(): Element = {
div( div(
className := "w-screen h-screen flex flex-col justify-center items-center", className := "w-screen h-screen flex flex-col justify-center items-center",
div(
className := "bg-yellow-400",
child.text <-- roomStateWSStream.events
.map { ev =>
{
val a = ev.toString()
g.console.warn(s"got state $a")
a
}
}
.startWith("BEFORE WS")
),
div( div(
className := "h-24 w-full flex flex-for justify-center items-center bg-green-200", className := "h-24 w-full flex flex-for justify-center items-center bg-green-200",
p(className := "text-2xl", "Here be header") p(className := "text-2xl", "Here be header")
), ),
RoomView.renderRoom(staticStateSignal), RoomView.renderRoom(stateSignal),
roomStateWSStream.connect roomStateWSStream.connect
) )
} }

View File

@ -46,11 +46,11 @@ object TableView {
} else isOpen.alreadyVoted.find(_.id == id).fold(NoCard(name))(_ => CardBack) } else isOpen.alreadyVoted.find(_.id == id).fold(NoCard(name))(_ => CardBack)
case isClosed: RoundState.Viewing => case isClosed: RoundState.Viewing =>
isClosed.votes isClosed.votes
.get(id) .find(_._1 == id)
.fold { .fold {
g.console.error(s"missing vote for player $name") g.console.error(s"missing vote for player $name")
Open("error") Open("error")
} { vote => Open(vote) } } { case (_, vote) => Open(vote) }
} }
} }