scalafmt all
This commit is contained in:
parent
0a721b135f
commit
2244f38348
|
@ -1,2 +1,3 @@
|
||||||
runner.dialect = scala3
|
runner.dialect = scala3
|
||||||
version = 3.7.3
|
version = 3.7.3
|
||||||
|
maxColumn = 100
|
||||||
|
|
|
@ -14,15 +14,14 @@ trait Auth[F[_]] {
|
||||||
|
|
||||||
/** for middleware that converts sessionId into PlayerId
|
/** for middleware that converts sessionId into PlayerId
|
||||||
*/
|
*/
|
||||||
def authUser
|
def authUser: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[F], (PlayerID, RoomID)]
|
||||||
: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[F], (PlayerID, RoomID)]
|
|
||||||
|
|
||||||
/** Get sessionId for accessing a room
|
/** Get sessionId for accessing a room
|
||||||
* @param roomPassword
|
* @param roomPassword
|
||||||
* \- requirement to get access to the room
|
* \- requirement to get access to the room
|
||||||
*
|
*
|
||||||
* check that room exists, password is valid call to add user to the players
|
* check that room exists, password is valid call to add user to the players create session
|
||||||
* create session mapping and return cookie
|
* mapping and return cookie
|
||||||
*/
|
*/
|
||||||
def joinRoom(
|
def joinRoom(
|
||||||
roomName: String,
|
roomName: String,
|
||||||
|
@ -75,9 +74,8 @@ object Auth {
|
||||||
???
|
???
|
||||||
}
|
}
|
||||||
|
|
||||||
override def authUser: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[
|
override def authUser
|
||||||
F
|
: Kleisli[[A] =>> cats.data.OptionT[F, A], Request[F], (PlayerID, RoomID)] = {
|
||||||
], (PlayerID, RoomID)] = {
|
|
||||||
// check authcookie presence, exchange it for playerID ad roomID
|
// check authcookie presence, exchange it for playerID ad roomID
|
||||||
???
|
???
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,11 @@ object MyHttpService {
|
||||||
AuthedRoutes.of {
|
AuthedRoutes.of {
|
||||||
case GET -> Root / "subscribe" as (playerId, roomId) => {
|
case GET -> Root / "subscribe" as (playerId, roomId) => {
|
||||||
val send: Stream[IO, WebSocketFrame] =
|
val send: Stream[IO, WebSocketFrame] =
|
||||||
Stream
|
Stream
|
||||||
.emits(TestModels.testChangesList)
|
.emits(TestModels.testChangesList)
|
||||||
.covary[IO].metered(1.second).map(state => WebSocketFrame.Text(state.asJson.noSpaces))
|
.covary[IO]
|
||||||
|
.metered(1.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))
|
||||||
|
@ -64,7 +66,7 @@ object MyHttpService {
|
||||||
Forbidden(error)
|
Forbidden(error)
|
||||||
case Right(authCookie) => {
|
case Right(authCookie) => {
|
||||||
IO(println(s"> logging in ${data.nickname} to ${data.roomName}")) >>
|
IO(println(s"> logging in ${data.nickname} to ${data.roomName}")) >>
|
||||||
Ok().map(_.addCookie(authCookie))
|
Ok().map(_.addCookie(authCookie))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} yield resp
|
} yield resp
|
||||||
|
|
|
@ -15,8 +15,7 @@ trait RoomService[F[_]] {
|
||||||
def getRoom(roomID: RoomID): F[Option[Room]]
|
def getRoom(roomID: RoomID): F[Option[Room]]
|
||||||
}
|
}
|
||||||
|
|
||||||
class InMemoryRoomService[F[_]: Sync](stateRef: Ref[F, Map[RoomID, Room]])
|
class InMemoryRoomService[F[_]: Sync](stateRef: Ref[F, Map[RoomID, Room]]) extends RoomService[F] {
|
||||||
extends RoomService[F] {
|
|
||||||
override def createRoom(newRoom: Room): F[Either[RoomError, Room]] = {
|
override def createRoom(newRoom: Room): F[Either[RoomError, Room]] = {
|
||||||
stateRef.modify { rooms =>
|
stateRef.modify { rooms =>
|
||||||
rooms.get(newRoom.id) match {
|
rooms.get(newRoom.id) match {
|
||||||
|
|
|
@ -55,7 +55,7 @@ lazy val backend = project
|
||||||
libraryDependencies += "co.fs2" %% "fs2-core" % "3.6.1",
|
libraryDependencies += "co.fs2" %% "fs2-core" % "3.6.1",
|
||||||
libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0",
|
libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0",
|
||||||
libraryDependencies += "org.typelevel" %% "cats-effect" % "3.4.9",
|
libraryDependencies += "org.typelevel" %% "cats-effect" % "3.4.9",
|
||||||
assembly / mainClass := Some("industries.sunshine.planningpoker.BackendApp"),
|
assembly / mainClass := Some("industries.sunshine.planningpoker.BackendApp")
|
||||||
)
|
)
|
||||||
.dependsOn(common.jvm)
|
.dependsOn(common.jvm)
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ lazy val commonJS = common.js.settings(
|
||||||
// scalaJS specific settings
|
// scalaJS specific settings
|
||||||
scalaJSLinkerConfig ~= {
|
scalaJSLinkerConfig ~= {
|
||||||
_.withModuleKind(ModuleKind.ESModule)
|
_.withModuleKind(ModuleKind.ESModule)
|
||||||
.withModuleSplitStyle(ModuleSplitStyle.SmallModulesFor(List("industries.sunshine.planningpoker")))
|
.withModuleSplitStyle(
|
||||||
|
ModuleSplitStyle.SmallModulesFor(List("industries.sunshine.planningpoker"))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,8 +37,8 @@ object Models {
|
||||||
|
|
||||||
enum RoundState derives Codec.AsObject:
|
enum RoundState derives Codec.AsObject:
|
||||||
|
|
||||||
/** view state for round before votes are open player can know their vote
|
/** view state for round before votes are open player can know their vote and who of the other
|
||||||
* and who of the other players have voted
|
* players have voted
|
||||||
*/
|
*/
|
||||||
case Voting(
|
case Voting(
|
||||||
myCard: Option[String],
|
myCard: Option[String],
|
||||||
|
|
|
@ -4,5 +4,6 @@ import io.circe.generic.semiauto._
|
||||||
import io.circe._
|
import io.circe._
|
||||||
|
|
||||||
object Requests {
|
object Requests {
|
||||||
final case class LogIn(roomName: String, nickname: String, password: String) derives Codec.AsObject
|
final case class LogIn(roomName: String, nickname: String, password: String)
|
||||||
|
derives Codec.AsObject
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,104 +3,104 @@ package industries.sunshine.planningpoker
|
||||||
import industries.sunshine.planningpoker.common.Models.*
|
import industries.sunshine.planningpoker.common.Models.*
|
||||||
|
|
||||||
object TestModels {
|
object TestModels {
|
||||||
val me = Player("wormy", PlayerID(1))
|
val me = Player("wormy", PlayerID(1))
|
||||||
val pony = Player("pony", PlayerID(10))
|
val pony = Player("pony", PlayerID(10))
|
||||||
val birdy = Player("birdy", PlayerID(11))
|
val birdy = Player("birdy", PlayerID(11))
|
||||||
val horsey = Player("horsey", PlayerID(12))
|
val horsey = Player("horsey", PlayerID(12))
|
||||||
|
|
||||||
val testRoom = {
|
val testRoom = {
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, birdy, pony),
|
players = List(me, birdy, pony),
|
||||||
me = me.id,
|
me = me.id,
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
round = RoundState.Voting(myCard = Some("s"), alreadyVoted = List(me, pony)),
|
round = RoundState.Voting(myCard = Some("s"), alreadyVoted = List(me, pony)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
)
|
|
||||||
}
|
|
||||||
val testOpenedRoom = {
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony, horsey),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Viewing(
|
|
||||||
List(me.id -> "xs", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
|
|
||||||
),
|
|
||||||
canCloseRound = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val testChangesList = List(
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, pony),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = None, alreadyVoted = List(birdy)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony, horsey),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony, horsey),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy, horsey)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony, horsey),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy, horsey, pony)),
|
|
||||||
canCloseRound = true
|
|
||||||
),
|
|
||||||
RoomStateView(
|
|
||||||
players = List(me, birdy, pony, horsey),
|
|
||||||
me = me.id,
|
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
|
||||||
round = RoundState.Viewing(
|
|
||||||
List(me.id -> "m", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
|
|
||||||
),
|
|
||||||
canCloseRound = true
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
val testOpenedRoom = {
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony, horsey),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Viewing(
|
||||||
|
List(me.id -> "xs", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
|
||||||
|
),
|
||||||
|
canCloseRound = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val testChangesList = List(
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, pony),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = None, alreadyVoted = List(birdy)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony, horsey),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony, horsey),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy, horsey)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony, horsey),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Voting(myCard = Some("m"), alreadyVoted = List(birdy, horsey, pony)),
|
||||||
|
canCloseRound = true
|
||||||
|
),
|
||||||
|
RoomStateView(
|
||||||
|
players = List(me, birdy, pony, horsey),
|
||||||
|
me = me.id,
|
||||||
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
|
round = RoundState.Viewing(
|
||||||
|
List(me.id -> "m", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
|
||||||
|
),
|
||||||
|
canCloseRound = true
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ 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.WebSocket.path("/api/subscribe").json[RoomStateView, Unit]
|
val roomStateWSStream = io.laminext.websocket.WebSocket
|
||||||
|
.path("/api/subscribe")
|
||||||
|
.json[RoomStateView, Unit]
|
||||||
.build(
|
.build(
|
||||||
managed = true,
|
managed = true,
|
||||||
autoReconnect = false,
|
autoReconnect = false,
|
||||||
|
|
|
@ -13,17 +13,16 @@ object TableView {
|
||||||
// so, it's more efficient to share an observable, than to create multiple copies...
|
// so, it's more efficient to share an observable, than to create multiple copies...
|
||||||
def renderTable(roundSignal: Signal[RoomStateView]): Element = {
|
def renderTable(roundSignal: Signal[RoomStateView]): Element = {
|
||||||
val playerIdToCardTypeSignal =
|
val playerIdToCardTypeSignal =
|
||||||
roundSignal.combineWith(Main.appStateSignal.map(_.myId)).map((state, myIdOpt) =>
|
roundSignal
|
||||||
state.players.map(p =>
|
.combineWith(Main.appStateSignal.map(_.myId))
|
||||||
p.id -> getPlayerCardType(p.id, state.round, p.name, myIdOpt)
|
.map((state, myIdOpt) =>
|
||||||
|
state.players.map(p => p.id -> getPlayerCardType(p.id, state.round, p.name, myIdOpt))
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
div(
|
div(
|
||||||
className := "w-full h-full border-2 border-amber-700 flex flex-row justify-center items-center bg-green-100",
|
className := "w-full h-full border-2 border-amber-700 flex flex-row justify-center items-center bg-green-100",
|
||||||
children <-- playerIdToCardTypeSignal.split(_._1) {
|
children <-- playerIdToCardTypeSignal.split(_._1) { (id, initial, cardTypeSignal) =>
|
||||||
(id, initial, cardTypeSignal) =>
|
renderPlayerCard(cardTypeSignal.map(_._2))
|
||||||
renderPlayerCard(cardTypeSignal.map(_._2))
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -57,8 +56,8 @@ object TableView {
|
||||||
def renderPlayerCard(state: Signal[CardState]): Element = {
|
def renderPlayerCard(state: Signal[CardState]): Element = {
|
||||||
val cardTypeStyle = state.map {
|
val cardTypeStyle = state.map {
|
||||||
case NoCard(_) => "bg-green-100 text-black border-2 border-black"
|
case NoCard(_) => "bg-green-100 text-black border-2 border-black"
|
||||||
case CardBack => "bg-green-500 border-4 border-green-700"
|
case CardBack => "bg-green-500 border-4 border-green-700"
|
||||||
case Open(_) => "text-black bg-gray-50 border-black border-2"
|
case Open(_) => "text-black bg-gray-50 border-black border-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
div(
|
div(
|
||||||
|
@ -67,11 +66,11 @@ object TableView {
|
||||||
div(
|
div(
|
||||||
className := "-rotate-45 text-xl",
|
className := "-rotate-45 text-xl",
|
||||||
child.text <-- state.map {
|
child.text <-- state.map {
|
||||||
case NoCard(name) => name
|
case NoCard(name) => name
|
||||||
case CardBack => ""
|
case CardBack => ""
|
||||||
case Open(vote) => vote
|
case Open(vote) => vote
|
||||||
}
|
}
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue