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.combineWith(Main.appStateSignal.map(_.myId)).map((state, myIdOpt) => state.players.map(p => p.id -> getPlayerCardType(p.id, state.round, p.name, myIdOpt) ) ) div( className := "w-full h-full border-2 border-amber-700 flex flex-row justify-center items-center bg-green-100", children <-- playerIdToCardTypeSignal.split(_._1) { (id, initial, cardTypeSignal) => renderPlayerCard(cardTypeSignal.map(_._2)) } ) } trait CardState case class NoCard(name: String) extends CardState case object CardBack extends CardState case class Open(value: String) extends CardState def getPlayerCardType( id: PlayerID, state: RoundState, name: String, myId: Option[PlayerID] ): CardState = { state match { case isOpen: VotingRound => if (myId.forall(_ == id)) { isOpen.myCard.fold(NoCard(name))(vote => Open(vote)) } else isOpen.alreadyVoted.find(_.id == id).fold(NoCard(name))(_ => CardBack) case isClosed: ViewingRound => 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 = { val cardTypeStyle = state.map { case NoCard(_) => "bg-green-100 text-black border-2 border-black" case CardBack => "bg-green-500 border-4 border-green-700" case Open(_) => "text-black bg-gray-50 border-black border-2" } div( className := "w-20 h-40 m-1 rounded flex justify-center items-center m-3", className <-- cardTypeStyle, div( className := "-rotate-45 text-xl", child.text <-- state.map { case NoCard(name) => name case CardBack => "" case Open(vote) => vote } ), ) } }