models: separate backend room model
not viewable on front end, since doesn't have json codecs, yay!
This commit is contained in:
parent
da9b96de84
commit
ed6d30ec42
|
@ -20,30 +20,27 @@ object Models {
|
||||||
players: List[Player],
|
players: List[Player],
|
||||||
me: PlayerID,
|
me: PlayerID,
|
||||||
allowedCards: List[String],
|
allowedCards: List[String],
|
||||||
round: RoundState,
|
round: RoundStateView,
|
||||||
canCloseRound: Boolean = false
|
canCloseRound: Boolean = false
|
||||||
) derives Codec.AsObject {
|
) derives Codec.AsObject
|
||||||
def playersCount: Int = players.size
|
|
||||||
}
|
|
||||||
|
|
||||||
object RoomStateView {
|
object RoomStateView {
|
||||||
val empty = RoomStateView(
|
val empty = RoomStateView(
|
||||||
List.empty,
|
List.empty,
|
||||||
PlayerID(0),
|
PlayerID(0),
|
||||||
List.empty,
|
List.empty,
|
||||||
RoundState.Voting(None, List.empty),
|
RoundStateView.Voting(None, List.empty),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RoundState derives Codec.AsObject:
|
enum RoundStateView derives Codec.AsObject:
|
||||||
|
|
||||||
/** view state for round before votes are open player can know their vote and who of the other
|
/** view state for round before votes are open player can know their vote and who of the other
|
||||||
* players have voted
|
* players have voted
|
||||||
*/
|
*/
|
||||||
case Voting(
|
case Voting(
|
||||||
myCard: Option[String],
|
myCard: Option[String],
|
||||||
alreadyVoted: List[Player]
|
alreadyVoted: List[PlayerID]
|
||||||
)
|
)
|
||||||
|
|
||||||
/** view state for round after opening the votes
|
/** view state for round after opening the votes
|
||||||
|
@ -51,15 +48,14 @@ object Models {
|
||||||
case Viewing(
|
case Viewing(
|
||||||
votes: List[(PlayerID, String)]
|
votes: List[(PlayerID, String)]
|
||||||
)
|
)
|
||||||
final case class PlayerID(id: Long) derives Codec.AsObject
|
|
||||||
|
|
||||||
|
final case class PlayerID(id: Long) derives Codec.AsObject
|
||||||
final case class Player(name: String, id: PlayerID) derives Codec.AsObject
|
final case class Player(name: String, id: PlayerID) derives Codec.AsObject
|
||||||
object Player {
|
object Player {
|
||||||
def create(name: String) = Player(name, PlayerID(Random.nextLong))
|
def create(name: String) = Player(name, PlayerID(Random.nextLong))
|
||||||
}
|
}
|
||||||
|
|
||||||
final case class RoomID(name: String) derives Codec.AsObject
|
final case class RoomID(name: String) derives Codec.AsObject
|
||||||
|
|
||||||
final case class Room(
|
final case class Room(
|
||||||
id: RoomID,
|
id: RoomID,
|
||||||
players: List[Player],
|
players: List[Player],
|
||||||
|
@ -69,7 +65,7 @@ object Models {
|
||||||
round: RoundState,
|
round: RoundState,
|
||||||
playersPasswords: Map[String, String] = Map.empty // nickname into password
|
playersPasswords: Map[String, String] = Map.empty // nickname into password
|
||||||
) {
|
) {
|
||||||
def toViewFor(playerId: PlayerID): RoomStateView = {
|
def getViewFor(playerId: PlayerID): RoomStateView = {
|
||||||
players
|
players
|
||||||
.find(_.id == playerId)
|
.find(_.id == playerId)
|
||||||
.fold(ifEmpty = RoomStateView.empty)((me: Player) =>
|
.fold(ifEmpty = RoomStateView.empty)((me: Player) =>
|
||||||
|
@ -77,27 +73,28 @@ object Models {
|
||||||
players,
|
players,
|
||||||
me.id,
|
me.id,
|
||||||
allowedCards,
|
allowedCards,
|
||||||
round,
|
round.toViewFor(playerId),
|
||||||
playerId == owner
|
playerId == owner
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object Room {
|
|
||||||
val testRoom = Room(
|
// no need to send to the front end, no deed to derive codec, cool
|
||||||
id = RoomID("testroom"),
|
sealed trait RoundState {
|
||||||
players = List(
|
def toViewFor(player: PlayerID): RoundStateView
|
||||||
Player("me", PlayerID(1L)),
|
}
|
||||||
Player("horsey", PlayerID(444L)),
|
object RoundState {
|
||||||
Player("froggy", PlayerID(555L)),
|
final case class Voting(votes: Map[PlayerID, String]) extends RoundState {
|
||||||
Player("owley", PlayerID(777L))
|
def toViewFor(playerId: PlayerID): RoundStateView.Voting = RoundStateView.Voting(
|
||||||
),
|
myCard = votes.get(playerId),
|
||||||
owner = PlayerID(1L),
|
alreadyVoted = votes.filterKeys(id => id != playerId).keys.toList
|
||||||
password = "password",
|
|
||||||
allowedCards = List("S", "M", "L"),
|
|
||||||
// TODO - this needs to be a different hting
|
|
||||||
round = RoundState.Voting(None, List.empty)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class Viewing(votes: Map[PlayerID, String]) extends RoundState {
|
||||||
|
def toViewFor(player: PlayerID): RoundStateView.Viewing =
|
||||||
|
RoundStateView.Viewing(votes.toList)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ object TestModels {
|
||||||
password = "password",
|
password = "password",
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
round = RoundState.Viewing(
|
round = RoundState.Viewing(
|
||||||
List(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
|
||||||
)
|
)
|
||||||
|
@ -29,70 +29,71 @@ object TestModels {
|
||||||
players = List(me),
|
players = List(me),
|
||||||
me = me.id,
|
me = me.id,
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
round = RoundState.Voting(myCard = None, alreadyVoted = List.empty),
|
round = RoundStateView.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, pony),
|
players = List(me, 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 = None, alreadyVoted = List.empty),
|
round = RoundStateView.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
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 = None, alreadyVoted = List.empty),
|
round = RoundStateView.Voting(myCard = None, alreadyVoted = List.empty),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
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 = None, alreadyVoted = List(birdy)),
|
round = RoundStateView.Voting(myCard = None, alreadyVoted = List(birdy.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
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("m"), alreadyVoted = List(birdy)),
|
round = RoundStateView.Voting(myCard = Some("m"), alreadyVoted = List(birdy.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
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("m"), alreadyVoted = List(birdy)),
|
round = RoundStateView.Voting(myCard = Some("m"), alreadyVoted = List(birdy.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, birdy, pony, horsey),
|
players = List(me, birdy, pony, horsey),
|
||||||
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("m"), alreadyVoted = List(birdy)),
|
round = RoundStateView.Voting(myCard = Some("m"), alreadyVoted = List(birdy.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, birdy, pony, horsey),
|
players = List(me, birdy, pony, horsey),
|
||||||
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("m"), alreadyVoted = List(birdy, horsey)),
|
round = RoundStateView.Voting(myCard = Some("m"), alreadyVoted = List(birdy.id, horsey.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, birdy, pony, horsey),
|
players = List(me, birdy, pony, horsey),
|
||||||
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("m"), alreadyVoted = List(birdy, horsey, pony)),
|
round = RoundStateView
|
||||||
|
.Voting(myCard = Some("m"), alreadyVoted = List(birdy.id, horsey.id, pony.id)),
|
||||||
canCloseRound = true
|
canCloseRound = true
|
||||||
),
|
),
|
||||||
RoomStateView(
|
RoomStateView(
|
||||||
players = List(me, birdy, pony, horsey),
|
players = List(me, birdy, pony, horsey),
|
||||||
me = me.id,
|
me = me.id,
|
||||||
allowedCards = List("xs", "s", "m", "l", "xl"),
|
allowedCards = List("xs", "s", "m", "l", "xl"),
|
||||||
round = RoundState.Viewing(
|
round = RoundStateView.Viewing(
|
||||||
List(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
|
||||||
|
|
|
@ -32,9 +32,9 @@ object OwnHandControls {
|
||||||
|
|
||||||
private def myUnselectedCards(state: RoomStateView): List[String] = {
|
private def myUnselectedCards(state: RoomStateView): List[String] = {
|
||||||
state.round match {
|
state.round match {
|
||||||
case RoundState.Voting(myCard, _) =>
|
case RoundStateView.Voting(myCard, _) =>
|
||||||
state.allowedCards.filterNot(value => myCard.contains(value))
|
state.allowedCards.filterNot(value => myCard.contains(value))
|
||||||
case RoundState.Viewing(votes) =>
|
case RoundStateView.Viewing(votes) =>
|
||||||
state.allowedCards.filterNot(value => votes.toMap.get(state.me).contains(value))
|
state.allowedCards.filterNot(value => votes.toMap.get(state.me).contains(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,19 @@ package industries.sunshine.planningpoker
|
||||||
|
|
||||||
import scala.scalajs.js
|
import scala.scalajs.js
|
||||||
import com.raquo.laminar.api.L.{*, given}
|
import com.raquo.laminar.api.L.{*, given}
|
||||||
import industries.sunshine.planningpoker.common.Models.RoundState
|
import industries.sunshine.planningpoker.common.Models.RoundStateView
|
||||||
import com.raquo.airstream.core.Signal
|
import com.raquo.airstream.core.Signal
|
||||||
import industries.sunshine.planningpoker.common.Models.RoundState
|
|
||||||
import industries.sunshine.planningpoker.common.Models.RoundState
|
|
||||||
import io.laminext.fetch.Fetch
|
import io.laminext.fetch.Fetch
|
||||||
import scala.scalajs.js.Dynamic.{global => g}
|
import scala.scalajs.js.Dynamic.{global => g}
|
||||||
|
|
||||||
import concurrent.ExecutionContext.Implicits.global
|
import concurrent.ExecutionContext.Implicits.global
|
||||||
|
|
||||||
object TableControls {
|
object TableControls {
|
||||||
def render(roundSignal: Signal[RoundState]): Element = {
|
def render(roundSignal: Signal[RoundStateView]): Element = {
|
||||||
div(
|
div(
|
||||||
child <-- roundSignal.map {
|
child <-- roundSignal.map {
|
||||||
case RoundState.Viewing(_) => newPollButton()
|
case RoundStateView.Viewing(_) => newPollButton()
|
||||||
case RoundState.Voting(_, _) => endPollButton()
|
case RoundStateView.Voting(_, _) => endPollButton()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,16 +39,16 @@ object TableView {
|
||||||
|
|
||||||
def getPlayerCardType(
|
def getPlayerCardType(
|
||||||
id: PlayerID,
|
id: PlayerID,
|
||||||
state: RoundState,
|
state: RoundStateView,
|
||||||
name: String,
|
name: String,
|
||||||
myId: PlayerID
|
myId: PlayerID
|
||||||
): CardState = {
|
): CardState = {
|
||||||
state match {
|
state match {
|
||||||
case isOpen: RoundState.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(vote))
|
||||||
} else isOpen.alreadyVoted.find(_.id == id).fold(NoCard(name))(_ => CardBack)
|
} else isOpen.alreadyVoted.find(_ == id).fold(NoCard(name))(_ => CardBack)
|
||||||
case isClosed: RoundState.Viewing =>
|
case isClosed: RoundStateView.Viewing =>
|
||||||
isClosed.votes
|
isClosed.votes
|
||||||
.find(_._1 == id)
|
.find(_._1 == id)
|
||||||
.fold {
|
.fold {
|
||||||
|
|
Loading…
Reference in New Issue