Compare commits
3 Commits
867b2f0f20
...
a87f4f99c0
Author | SHA1 | Date |
---|---|---|
|
a87f4f99c0 | |
|
d7d4e2be9d | |
|
3158a75f5d |
|
@ -82,6 +82,6 @@ object Auth {
|
||||||
|
|
||||||
def make[F[_]: Sync](): F[Auth[F]] =
|
def make[F[_]: Sync](): F[Auth[F]] =
|
||||||
for {
|
for {
|
||||||
sessionsMap <- Ref.of[F, SessionsMap](TestModels.testSessions)
|
sessionsMap <- Ref.of[F, SessionsMap](Map.empty)
|
||||||
} yield new SimpleAuth(sessionsMap)
|
} yield new SimpleAuth(sessionsMap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room,
|
||||||
val newRoom = Room(
|
val newRoom = Room(
|
||||||
roomId,
|
roomId,
|
||||||
players = List(ownerPlayer),
|
players = List(ownerPlayer),
|
||||||
owner = ownerPlayer.id,
|
owner = ownerPlayer.name,
|
||||||
password = roomPassword,
|
password = roomPassword,
|
||||||
allowedCards = List("XS", "S", "M", "L", "XL"), // TODO accept from front
|
allowedCards = List("XS", "S", "M", "L", "XL"), // TODO accept from front
|
||||||
round = RoundState.Voting(Map.empty),
|
round = RoundState.Voting(Map.empty),
|
||||||
|
@ -122,7 +122,11 @@ class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room,
|
||||||
*/
|
*/
|
||||||
override def leaveRoom(roomID: RoomID, playerID: PlayerID): F[Unit] = updateRoom(
|
override def leaveRoom(roomID: RoomID, playerID: PlayerID): F[Unit] = updateRoom(
|
||||||
roomID,
|
roomID,
|
||||||
room => room.copy(players = room.players.filterNot(_.id == playerID))
|
room =>
|
||||||
|
room.copy(
|
||||||
|
players = room.players.filterNot(_.id == playerID),
|
||||||
|
round = room.round.removePlayer(playerID)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
override def deleteRoom(roomID: RoomID): F[Unit] = {
|
override def deleteRoom(roomID: RoomID): F[Unit] = {
|
||||||
|
@ -159,7 +163,7 @@ class InMemoryRoomService[F[_]: Concurrent](stateRef: Ref[F, Map[RoomID, (Room,
|
||||||
room.players.find(_.name == nickName) match {
|
room.players.find(_.name == nickName) match {
|
||||||
case Some(player) => player.id -> room
|
case Some(player) => player.id -> room
|
||||||
case None => // player is not present, but potentially was previously
|
case None => // player is not present, but potentially was previously
|
||||||
val addingPlayer = Player.create(nickPassword)
|
val addingPlayer = Player.create(nickName)
|
||||||
val roomWithPlayer = room.copy(players = addingPlayer :: room.players)
|
val roomWithPlayer = room.copy(players = addingPlayer :: room.players)
|
||||||
room.playersPasswords.get(nickName) match {
|
room.playersPasswords.get(nickName) match {
|
||||||
case Some(_) => addingPlayer.id -> roomWithPlayer
|
case Some(_) => addingPlayer.id -> roomWithPlayer
|
||||||
|
|
|
@ -59,7 +59,7 @@ object Models {
|
||||||
final case class Room(
|
final case class Room(
|
||||||
id: RoomID,
|
id: RoomID,
|
||||||
players: List[Player],
|
players: List[Player],
|
||||||
owner: PlayerID, // TODO switch to nickname
|
owner: String, // TODO switch to nickname
|
||||||
password: String,
|
password: String,
|
||||||
allowedCards: List[String],
|
allowedCards: List[String],
|
||||||
round: RoundState,
|
round: RoundState,
|
||||||
|
@ -74,7 +74,7 @@ object Models {
|
||||||
me.id,
|
me.id,
|
||||||
allowedCards,
|
allowedCards,
|
||||||
round.toViewFor(playerId),
|
round.toViewFor(playerId),
|
||||||
playerId == owner
|
me.name == owner
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -83,18 +83,23 @@ object Models {
|
||||||
// no need to send to the front end, no deed to derive codec, cool
|
// no need to send to the front end, no deed to derive codec, cool
|
||||||
sealed trait RoundState {
|
sealed trait RoundState {
|
||||||
def toViewFor(player: PlayerID): RoundStateView
|
def toViewFor(player: PlayerID): RoundStateView
|
||||||
|
def removePlayer(id: PlayerID): RoundState
|
||||||
}
|
}
|
||||||
object RoundState {
|
object RoundState {
|
||||||
final case class Voting(votes: Map[PlayerID, String]) extends RoundState {
|
final case class Voting(votes: Map[PlayerID, String]) extends RoundState {
|
||||||
def toViewFor(playerId: PlayerID): RoundStateView.Voting = RoundStateView.Voting(
|
override def toViewFor(playerId: PlayerID): RoundStateView.Voting = RoundStateView.Voting(
|
||||||
myCard = votes.get(playerId),
|
myCard = votes.get(playerId),
|
||||||
alreadyVoted = votes.filterKeys(id => id != playerId).keys.toList
|
alreadyVoted = votes.filterKeys(id => id != playerId).keys.toList
|
||||||
)
|
)
|
||||||
|
override def removePlayer(id: PlayerID): RoundState.Voting =
|
||||||
|
RoundState.Voting(votes.filterKeys(_ != id).toMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class Viewing(votes: Map[PlayerID, String]) extends RoundState {
|
final case class Viewing(votes: Map[PlayerID, String]) extends RoundState {
|
||||||
def toViewFor(player: PlayerID): RoundStateView.Viewing =
|
override def toViewFor(player: PlayerID): RoundStateView.Viewing =
|
||||||
RoundStateView.Viewing(votes.toList)
|
RoundStateView.Viewing(votes.toList)
|
||||||
|
override def removePlayer(id: PlayerID): RoundState.Viewing =
|
||||||
|
RoundState.Viewing(votes.filterKeys(_ != id).toMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,21 @@ object TestModels {
|
||||||
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 testRoomBackend = Room(
|
// val testRoomBackend = Room(
|
||||||
id = RoomID("testroom"),
|
// id = RoomID("testroom"),
|
||||||
players = List(me, birdy, pony, horsey),
|
// players = List(me, birdy, pony, horsey),
|
||||||
owner = me.id,
|
// owner = me.id,
|
||||||
password = "password",
|
// password = "password",
|
||||||
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")
|
// Map(me.id -> "xs", pony.id -> "l", birdy.id -> "s", horsey.id -> "m")
|
||||||
),
|
// ),
|
||||||
playersPasswords = Map("me" -> "nickpassword") // nickname into password
|
// playersPasswords = Map("me" -> "nickpassword") // nickname into password
|
||||||
)
|
// )
|
||||||
|
|
||||||
val testSessionId = 1L
|
// val testSessionId = 1L
|
||||||
val testSessions = Map(testSessionId -> (testRoomBackend.id, me.id))
|
// val testSessions = Map(testSessionId -> (testRoomBackend.id, me.id))
|
||||||
val testRooms = Map(testRoomBackend.id -> testRoomBackend)
|
// val testRooms = Map(testRoomBackend.id -> testRoomBackend)
|
||||||
|
|
||||||
val testChangesList = List(
|
val testChangesList = List(
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
|
|
|
@ -34,8 +34,8 @@ object TableView {
|
||||||
|
|
||||||
trait CardState
|
trait CardState
|
||||||
case class NoCard(name: String) extends CardState
|
case class NoCard(name: String) extends CardState
|
||||||
case object CardBack extends CardState
|
case class CardBack(name: String) extends CardState
|
||||||
case class Open(value: String) extends CardState
|
case class Open(name: String, value: String) extends CardState
|
||||||
|
|
||||||
def getPlayerCardType(
|
def getPlayerCardType(
|
||||||
id: PlayerID,
|
id: PlayerID,
|
||||||
|
@ -46,36 +46,46 @@ object TableView {
|
||||||
state match {
|
state match {
|
||||||
case isOpen: RoundStateView.Voting =>
|
case isOpen: RoundStateView.Voting =>
|
||||||
if (myId == id) {
|
if (myId == id) {
|
||||||
isOpen.myCard.fold(NoCard(name))(vote => Open(vote))
|
isOpen.myCard.fold(NoCard(name))(vote => Open(name, vote))
|
||||||
} else isOpen.alreadyVoted.find(_ == id).fold(NoCard(name))(_ => CardBack)
|
} else isOpen.alreadyVoted.find(_ == id).fold(NoCard(name))(_ => CardBack(name))
|
||||||
case isClosed: RoundStateView.Viewing =>
|
case isClosed: RoundStateView.Viewing =>
|
||||||
isClosed.votes
|
isClosed.votes
|
||||||
.find(_._1 == 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(name, "error")
|
||||||
} { case (_, vote) => Open(vote) }
|
} { case (_, vote) => Open(name, vote) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
className := "w-20 h-40 m-1 rounded flex justify-center items-center m-3",
|
className := "w-20 h-40 m-1 rounded flex flex-col justify-center items-center m-3",
|
||||||
className <-- cardTypeStyle,
|
className <-- cardTypeStyle,
|
||||||
|
// the diagonal card value \ place text
|
||||||
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(name) => name
|
||||||
case Open(vote) => vote
|
case Open(_, vote) => vote
|
||||||
|
}
|
||||||
|
),
|
||||||
|
// name under viewing the votes
|
||||||
|
div(
|
||||||
|
className := "text-xl",
|
||||||
|
child.text <-- state.map {
|
||||||
|
case Open(name, _) => name
|
||||||
|
case _ => ""
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue