Add HTML rendering for sessions and card images; refactor output handling in SimpleSession

This commit is contained in:
2025-10-16 08:12:26 +02:00
parent 9aa447f2f6
commit fc751af1ef
8 changed files with 49 additions and 43 deletions

View File

@@ -7,6 +7,7 @@ import de.knockoutwhist.components.Configuration
import di.KnockOutWebConfigurationModule import di.KnockOutWebConfigurationModule
import play.api.* import play.api.*
import play.api.mvc.* import play.api.mvc.*
import play.twirl.api.Html
import java.util.UUID import java.util.UUID
import javax.inject.* import javax.inject.*
@@ -35,13 +36,13 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
KnockOutWhist.entry(injector.getInstance(classOf[Configuration])) KnockOutWhist.entry(injector.getInstance(classOf[Configuration]))
} }
Action { implicit request => Action { implicit request =>
Ok(views.html.index.apply()) Redirect("/sessions")
} }
} }
def sessions(): Action[AnyContent] = { def sessions(): Action[AnyContent] = {
Action { implicit request => Action { implicit request =>
Ok(views.html.tui.apply(PodGameManager.listSessions().map(f => f.toString + "\n").mkString(""))) Ok(views.html.sessions.apply(PodGameManager.listSessions().map(f => f.toString)))
} }
} }
@@ -49,7 +50,7 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
val uuid: UUID = UUID.fromString(id) val uuid: UUID = UUID.fromString(id)
if (PodGameManager.identify(uuid).isEmpty) { if (PodGameManager.identify(uuid).isEmpty) {
Action { implicit request => Action { implicit request =>
NotFound(views.html.tui.apply("Player not found")) NotFound(views.html.tui.apply(List(Html(s"<p>Session with id $id not found!</p>"))))
} }
} else { } else {
val session = PodGameManager.identify(uuid).get val session = PodGameManager.identify(uuid).get

View File

@@ -39,7 +39,7 @@ object WebUI extends CustomThread with EventListener with UI {
if (event.status == TECHNICAL_MATCH_STARTED) { if (event.status == TECHNICAL_MATCH_STARTED) {
val matchImpl = event.objects.head.asInstanceOf[Match] val matchImpl = event.objects.head.asInstanceOf[Match]
for (player <- matchImpl.totalplayers) { for (player <- matchImpl.totalplayers) {
PodGameManager.addSession(SimpleSession(player.id, "")) PodGameManager.addSession(SimpleSession(player.id, List()))
} }
} else { } else {
PodGameManager.transmitAll(event) PodGameManager.transmitAll(event)

View File

@@ -10,13 +10,14 @@ import de.knockoutwhist.events.cards.{RenderHandEvent, ShowTieCardsEvent}
import de.knockoutwhist.events.round.ShowCurrentTrickEvent import de.knockoutwhist.events.round.ShowCurrentTrickEvent
import de.knockoutwhist.player.AbstractPlayer import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.events.SimpleEvent import de.knockoutwhist.utils.events.SimpleEvent
import play.twirl.api.Html
import scalafx.scene.image.Image import scalafx.scene.image.Image
import util.WebUIUtils import util.WebUIUtils
import java.util.UUID import java.util.UUID
case class SimpleSession(id: UUID, private var output: String) extends PlayerSession { case class SimpleSession(id: UUID, private var output: List[Html]) extends PlayerSession {
def get(): String = { def get(): List[Html] = {
output output
} }
@@ -40,28 +41,23 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
} }
private def clear(): Unit = { private def clear(): Unit = {
output = "" output = List()
} }
private def renderHand(event: RenderHandEvent): Unit = { private def renderHand(event: RenderHandEvent): Unit = {
output += WebUICards.renderHandEvent(event.hand, event.showNumbers).map(_.toString).mkString output = output :++ WebUICards.renderHandEvent(event.hand)
output = output :+ Html("<br>")
} }
private def showtiecardseventmethod(event: ShowTieCardsEvent): Option[Boolean] = { private def showtiecardseventmethod(event: ShowTieCardsEvent): Option[Boolean] = {
val a: Array[String] = Array("", "", "", "", "", "", "", "") var l = List[Html]()
for ((player, card) <- event.card) { for ((player, card) <- event.card) {
val playerNameLength = player.name.length l = l :+ Html(s"<p>${player.name}:</p>")
a(0) += " " + player.name + ":" + (" " * (playerNameLength - 1)) l = l :+ WebUIUtils.cardtoImage(card)
val rendered = WebUIUtils.cardtoImage(card) l = l :+ Html("<br>")
//a(1) += " " + rendered(0)
//a(2) += " " + rendered(1)
//a(3) += " " + rendered(2)
//a(4) += " " + rendered(3)
//a(5) += " " + rendered(4)
//a(6) += " " + rendered(5)
//a(7) += " " + rendered(6)
} }
a.foreach(addToOutput) output = output :++ l
output = output :+ Html("<br>")
Some(true) Some(true)
} }
@@ -83,7 +79,7 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
case SHOW_START_MATCH => case SHOW_START_MATCH =>
clear() clear()
println("Starting a new match...") println("Starting a new match...")
output += "\n\n" output = output :+ Html("<br><br>")
Some(true) Some(true)
case SHOW_TYPE_PLAYERS => case SHOW_TYPE_PLAYERS =>
println("Please enter the names of the players, separated by a comma.") println("Please enter the names of the players, separated by a comma.")
@@ -139,7 +135,7 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
Some(true) Some(true)
case SHOW_WON_PLAYER_TRICK => case SHOW_WON_PLAYER_TRICK =>
println(s"${event.player.name} won the trick.") println(s"${event.player.name} won the trick.")
output = "\n\n" output = output :+ Html("<br><br>")
Some(true) Some(true)
} }
} }
@@ -156,7 +152,7 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
case SHOW_START_ROUND => case SHOW_START_ROUND =>
clear() clear()
println(s"Starting a new round. The trump suit is ${event.currentRound.trumpSuit}.") println(s"Starting a new round. The trump suit is ${event.currentRound.trumpSuit}.")
output = "\n\n" output = output :+ Html("<br><br>")
Some(true) Some(true)
case WON_ROUND => case WON_ROUND =>
if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) { if (event.objects.length != 1 || !event.objects.head.isInstanceOf[AbstractPlayer]) {
@@ -219,16 +215,17 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
Some(true) Some(true)
} }
private def addToOutput(str: String): Unit = {
output += str + "\n"
}
private def println(s: String): Unit = { private def println(s: String): Unit = {
output += s + "\n" var html = List[Html]()
for (line <- s.split("\n")) {
html = html :+ Html(line)
html = html :+ Html("<br>")
}
output = output :++ html
} }
private def println(): Unit = { private def println(): Unit = {
output += "\n" output = output :+ Html("<br>")
} }
object WebUICards { object WebUICards {
@@ -256,16 +253,8 @@ case class SimpleSession(id: UUID, private var output: String) extends PlayerSes
) )
} }
def renderHandEvent(hand: Hand, showNumbers: Boolean): List[Image] = { def renderHandEvent(hand: Hand): List[Html] = {
hand.cards.map(WebUIUtils.cardtoImage) hand.cards.map(WebUIUtils.cardtoImage)
//var zipped = cardStrings.transpose
//if (showNumbers) zipped = {
// List.tabulate(hand.cards.length) { i =>
// s" ${i + 1} "
// }
// } :: zipped
// zipped.map(_.mkString(" ")).toVector
// }
} }
} }
} }

View File

@@ -3,10 +3,11 @@ package util
import de.knockoutwhist.cards.Card import de.knockoutwhist.cards.Card
import de.knockoutwhist.cards.CardValue.{Ace, Eight, Five, Four, Jack, King, Nine, Queen, Seven, Six, Ten, Three, Two} import de.knockoutwhist.cards.CardValue.{Ace, Eight, Five, Four, Jack, King, Nine, Queen, Seven, Six, Ten, Three, Two}
import de.knockoutwhist.cards.Suit.{Clubs, Diamonds, Hearts, Spades} import de.knockoutwhist.cards.Suit.{Clubs, Diamonds, Hearts, Spades}
import play.twirl.api.Html
import scalafx.scene.image.Image import scalafx.scene.image.Image
object WebUIUtils { object WebUIUtils {
def cardtoImage(card: Card): Image = { def cardtoImage(card: Card): Html = {
val s = card.suit match { val s = card.suit match {
case Spades => "S" case Spades => "S"
case Hearts => "H" case Hearts => "H"
@@ -28,6 +29,6 @@ object WebUIUtils {
case Three => "3" case Three => "3"
case Two => "2" case Two => "2"
} }
new Image(f"public/images/cards/$cv$s.png") views.html.output.card.apply(f"images/cards/$cv$s.png")(card.toString)
} }
} }

View File

@@ -0,0 +1,2 @@
@(src: String)(alt: String)
<img src="@routes.Assets.versioned(src)" alt="@alt"/>

View File

@@ -0,0 +1,3 @@
@(text: String)
<p>@text</p>

View File

@@ -0,0 +1,10 @@
@(toRender: List[String])
@main("Sessions") {
<div id="sessions">
@for(line <- toRender) {
<a href="@routes.HomeController.ingame(line)">@line</a><br>
}
</div>
}

View File

@@ -1,9 +1,9 @@
@(toRender: String) @(toRender: List[Html])
@main("Tui") { @main("Tui") {
<div id="tui"> <div id="tui">
@for(line <- toRender.split('\n')) { @for(line <- toRender) {
<a href="@routes.Relative.ingame(line)">@line</a> @line
} }
</div> </div>
} }