new ugly rendering of other players and table

This commit is contained in:
efim 2023-04-21 22:58:08 +04:00
parent 527e12dbd8
commit acbda22a5d
3 changed files with 69 additions and 5 deletions

View File

@ -48,7 +48,7 @@ final case class OpenRound(
/** view state for round after opening the votes
*/
final case class ClosedRound(
votes: Map[Player, String]
votes: Map[PlayerID, String]
) extends RoundState
final class PlayerID

View File

@ -19,8 +19,9 @@ object RoomView {
div(
className := "flex flex-row",
children <-- otherPlayers.split(_.id) { (id, initial, playerSignal) =>
renderPlayer(playerSignal, roomStateSignal.map(_.allowedCards.size))
}
renderPlayer(playerSignal, roomStateSignal.map(_.allowedCards.size))
},
TableView.renderTable(roomStateSignal)
)
)
}
@ -33,11 +34,10 @@ object RoomView {
)
}
// TODO will also be a signal, i suppose separate, yeah
def renderHandCardBacks(amountSignal: Signal[Int]): Element = {
def renderCard(index: Int): Element =
div(
className := "w-4 h-8 m-1 rounded bg-gray-600 text-yellow-400"
className := "w-4 h-8 m-1 rounded bg-gray-600 text-yellow"
)
div(

View File

@ -0,0 +1,64 @@
package industries.sunshine.planningpoker
import scala.scalajs.js
import com.raquo.laminar.api.L.{*, given}
import scala.scalajs.js.Dynamic.{global => g}
object TableView {
// new plan. map to players, split by playerId, map into specific card
// have single funciton that calculates the card from the state.
// but, can't have map to player, because overall state is required.
// but can i split full state into several observables by that key? i think i should be able to
// so, it's more efficient to share an observable, than to create multiple copies...
def renderTable(roundSignal: Signal[RoomStateView]): Element = {
val playerIdToCardTypeSignal =
roundSignal.map(state =>
state.players.map(p =>
p.id -> getPlayerCardType(p.id, state.round, p.name)
)
)
div(
className := "w-32 h-24 border-2 border-amber-700 flex flex-row",
children <-- playerIdToCardTypeSignal.split(_._1) {
(id, initial, cardTypeSignal) =>
renderPlayerCard(cardTypeSignal.map(_._2))
}
)
}
trait CardState
case class NoCard(name: String) extends CardState
case object Closed extends CardState
case class Open(value: String) extends CardState
def getPlayerCardType(
id: PlayerID,
state: RoundState,
name: String
): CardState = {
state match {
case isOpen: OpenRound =>
isOpen.alreadyVoted.find(_.id == id).fold(NoCard(name))(_ => Closed)
case isClosed: ClosedRound =>
isClosed.votes
.get(id)
.fold {
g.console.error(s"missing vote for player $name")
Open("error")
} { vote => Open(vote) }
}
}
def renderPlayerCard(state: Signal[CardState]): Element = {
div(
className := "w-4 h-8 m-1 rounded bg-gray-400 text-yellow-400",
child.text <-- state.map {
case NoCard(name) => name
case Closed => ""
case Open(vote) => vote
}
)
}
}