feat(14): manual request of house choice
hodgepodge of 2 fragments which are put into house choice depending on the state. the alignment is done in a very not nice way.
This commit is contained in:
parent
66013ae1c6
commit
de3d4781f0
|
@ -2,6 +2,6 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
/* div, section, span, p { */
|
div, section, span, p {
|
||||||
/* outline: 1px solid red; */
|
outline: 1px solid red;
|
||||||
/* } */
|
}
|
||||||
|
|
|
@ -522,6 +522,10 @@ video {
|
||||||
--tw-backdrop-sepia: ;
|
--tw-backdrop-sepia: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.static {
|
.static {
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
@ -559,6 +563,10 @@ video {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-2\/3 {
|
||||||
|
top: 66.666667%;
|
||||||
|
}
|
||||||
|
|
||||||
.top-\[var\(--top-offset\)\] {
|
.top-\[var\(--top-offset\)\] {
|
||||||
top: var(--top-offset);
|
top: var(--top-offset);
|
||||||
}
|
}
|
||||||
|
@ -567,14 +575,22 @@ video {
|
||||||
margin-right: 0.75rem;
|
margin-right: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-14 {
|
|
||||||
margin-top: 3.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-6 {
|
.mt-6 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-\[4\.5rem\] {
|
||||||
|
margin-top: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-\[0\.5rem\] {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-\[1rem\] {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -587,6 +603,10 @@ video {
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.h-10 {
|
.h-10 {
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
}
|
}
|
||||||
|
@ -603,6 +623,10 @@ video {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-\[300px\] {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
.h-\[375px\] {
|
.h-\[375px\] {
|
||||||
height: 375px;
|
height: 375px;
|
||||||
}
|
}
|
||||||
|
@ -619,6 +643,14 @@ video {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-full {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-0 {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.w-1\/3 {
|
.w-1\/3 {
|
||||||
width: 33.333333%;
|
width: 33.333333%;
|
||||||
}
|
}
|
||||||
|
@ -635,6 +667,10 @@ video {
|
||||||
width: 8rem;
|
width: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-9\/12 {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
.w-\[100px\] {
|
.w-\[100px\] {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
@ -651,12 +687,16 @@ video {
|
||||||
width: var(--diameter);
|
width: var(--diameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-screen {
|
||||||
|
width: 100vw;
|
||||||
|
}
|
||||||
|
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-screen {
|
.w-0 {
|
||||||
width: 100vw;
|
width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grow {
|
.grow {
|
||||||
|
@ -815,8 +855,8 @@ video {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pt-10 {
|
.pt-14 {
|
||||||
padding-top: 2.5rem;
|
padding-top: 3.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pt-8 {
|
.pt-8 {
|
||||||
|
@ -896,8 +936,6 @@ video {
|
||||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* div, section, span, p { */
|
div, section, span, p {
|
||||||
|
outline: 1px solid red;
|
||||||
/* outline: 1px solid red; */
|
}
|
||||||
|
|
||||||
/* } */
|
|
||||||
|
|
|
@ -56,64 +56,95 @@
|
||||||
</h2>
|
</h2>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="showdown-table" class="grid grid-cols-2 w-[375px] h-[375px]"
|
<div id="showdown-table" th:fragment="showdown-table (showdownState)">
|
||||||
th:fragment="showdown-table"
|
<section class="grid grid-cols-2 w-[375px] h-[300px]">
|
||||||
>
|
|
||||||
<div id="players-choice"
|
|
||||||
class="flex relative flex-col items-center pt-10"
|
|
||||||
>
|
|
||||||
<!-- This will be imported fragment -->
|
|
||||||
<!-- <p th:text="${playersChoiceData.c.toString}">Hello</p> -->
|
|
||||||
<div th:replace="index::choiceBadge (${playersChoiceData})"> </div>
|
|
||||||
<div
|
<div
|
||||||
th:remove="all"
|
id="players-choice"
|
||||||
id="rock"
|
class="flex relative flex-col items-center pt-14"
|
||||||
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
|
||||||
style="
|
|
||||||
--diameter: 8rem;
|
|
||||||
--bg-dark: hsl(349, 71%, 52%);
|
|
||||||
--bg-bright: hsl(349, 70%, 56%);
|
|
||||||
--top-offset: 0rem;
|
|
||||||
--left-offset: 0rem;
|
|
||||||
--translation: 0%;
|
|
||||||
position: relative;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
|
<!-- This will be imported fragment -->
|
||||||
|
<!-- <p th:text="${showdownState}">Hello</p> -->
|
||||||
<div
|
<div
|
||||||
class="absolute top-1/2 left-1/2 w-3/4 h-3/4 bg-gradient-to-b from-gray-300 to-gray-100 rounded-full -translate-x-1/2 -translate-y-1/2"
|
th:replace="index::choiceBadge (${showdownState.playersChoice})"
|
||||||
></div>
|
></div>
|
||||||
<img
|
<div
|
||||||
src="../public/images/icon-rock.svg"
|
th:remove="all"
|
||||||
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2"
|
id="rock"
|
||||||
/>
|
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
||||||
|
style="
|
||||||
|
--diameter: 8rem;
|
||||||
|
--bg-dark: hsl(349, 71%, 52%);
|
||||||
|
--bg-bright: hsl(349, 70%, 56%);
|
||||||
|
--top-offset: 0rem;
|
||||||
|
--left-offset: 0rem;
|
||||||
|
--translation: 0%;
|
||||||
|
position: relative;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute top-1/2 left-1/2 w-3/4 h-3/4 bg-gradient-to-b from-gray-300 to-gray-100 rounded-full -translate-x-1/2 -translate-y-1/2"
|
||||||
|
></div>
|
||||||
|
<img
|
||||||
|
src="../public/images/icon-rock.svg"
|
||||||
|
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="absolute top-2/3 tracking-widest text-center text-white uppercase text-md"
|
||||||
|
>
|
||||||
|
You picked
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="absolute top-1/2 tracking-widest text-center text-white uppercase text-md">You picked</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="house-choice"
|
<div id="house-choice"
|
||||||
class="flex relative flex-col items-center"
|
class="flex relative flex-col items-center pt-14"
|
||||||
>
|
|
||||||
<!-- This will be imported fragment -->
|
|
||||||
<div
|
|
||||||
class="mt-14 rounded-full bg-radial-gradient-top h-[100px] w-[100px]"
|
|
||||||
>
|
>
|
||||||
|
<!-- Here will be imported fragment -->
|
||||||
|
<!-- conditionally either house choice or request for house choice -->
|
||||||
|
<!-- <div th:text="${showdownState.houseChoice.nonEmpty} ? 'nonEmpty' : 'empty'">...</div> -->
|
||||||
|
<div
|
||||||
|
th:replace="${showdownState.houseChoice.nonEmpty} ? ~{index::choiceBadge (${showdownState.houseChoice.get})} : ~{::house-choice-placeholder}"
|
||||||
|
class="w-0 h-0"
|
||||||
|
th:class=""
|
||||||
|
>
|
||||||
|
...
|
||||||
|
</div>
|
||||||
|
<!-- This will be shown before the house made the choice, this will trigger timed request for house choice -->
|
||||||
|
<div class="w-full h-full" th:remove="all">
|
||||||
|
<div
|
||||||
|
class="flex relative flex-col items-center h-full"
|
||||||
|
th:fragment="house-choice-placeholder"
|
||||||
|
th:hx-get="'/house-choice/' + ${showdownState.playersChoice.c.name}"
|
||||||
|
hx-get="/house-choice/paper"
|
||||||
|
hx-target="#showdown-table"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="rounded-full mt-[1rem] bg-radial-gradient-top h-[100px] w-[100px]"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="absolute top-2/3 tracking-widest text-center text-white uppercase text-md"
|
||||||
|
>
|
||||||
|
The house picked
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="absolute top-1/2 tracking-widest text-center text-white uppercase text-md">The house picked</p>
|
</section>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="message"
|
id="message"
|
||||||
class="text-white"
|
class="flex flex-col items-center text-white"
|
||||||
>
|
th:classappend="${gameFinished} ? '' : 'invisible'"
|
||||||
<p
|
>
|
||||||
class="text-6xl tracking-wide uppercase"
|
<p class="text-6xl tracking-wide text-center uppercase">You lose</p>
|
||||||
>You lose</p>
|
<button
|
||||||
<button
|
class="mt-6 w-9/12 h-12 tracking-widest uppercase bg-white rounded-xl text-radial-gradient-bottom"
|
||||||
class="mt-6 w-full h-12 tracking-widest uppercase bg-white rounded-xl text-radial-gradient-bottom"
|
>
|
||||||
>Play again</button>
|
Play again
|
||||||
|
</button>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -11,6 +11,7 @@ import scala.jdk.CollectionConverters._
|
||||||
import javax.swing.text.Position
|
import javax.swing.text.Position
|
||||||
import rockpaperscissors.Models.Positioning
|
import rockpaperscissors.Models.Positioning
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
import rockpaperscissors.Models.ShowdownState
|
||||||
|
|
||||||
object Main {
|
object Main {
|
||||||
@main def run(
|
@main def run(
|
||||||
|
@ -70,8 +71,13 @@ object Main {
|
||||||
case Some(playersChoiceBadge) =>
|
case Some(playersChoiceBadge) =>
|
||||||
val badge = playersChoiceBadge.copy()
|
val badge = playersChoiceBadge.copy()
|
||||||
badge.p = Positioning.Relative
|
badge.p = Positioning.Relative
|
||||||
context.setVariable("playersChoiceData", badge)
|
val showdownState = ShowdownState(badge, None, false)
|
||||||
val result = templateEngine.process("showdown", Set("showdown-table").asJava, context)
|
context.setVariable("showdownState", showdownState)
|
||||||
|
val result = templateEngine.process(
|
||||||
|
"showdown",
|
||||||
|
Set("showdown-table").asJava,
|
||||||
|
context
|
||||||
|
)
|
||||||
cask.Response(
|
cask.Response(
|
||||||
result,
|
result,
|
||||||
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
||||||
|
@ -82,9 +88,37 @@ object Main {
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@cask.get("/house-choice/:playersChoice")
|
||||||
|
def requestHouseChoice(playersChoice: String) = {
|
||||||
|
val context = new Context()
|
||||||
|
val badge = Models.choiceSelectionItems.find(_.c.name == playersChoice)
|
||||||
|
val response = badge match {
|
||||||
|
case Some(playersChoiceBadge) =>
|
||||||
|
val badge = playersChoiceBadge.copy()
|
||||||
|
badge.p =
|
||||||
|
Positioning.Relative // this probably should be set in enclosing html tag
|
||||||
|
val houseChoice = Models.choiceSelectionItems(Random.nextInt(3)).copy()
|
||||||
|
houseChoice.p = Positioning.Relative
|
||||||
|
println(s"getting house choice $houseChoice")
|
||||||
|
val showdownState = ShowdownState(badge, Some(houseChoice), false)
|
||||||
|
context.setVariable("showdownState", showdownState)
|
||||||
|
val result = templateEngine.process(
|
||||||
|
"showdown",
|
||||||
|
Set("showdown-table").asJava,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
cask.Response(
|
||||||
|
result,
|
||||||
|
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
||||||
|
)
|
||||||
|
case None =>
|
||||||
|
cask.Response(s"Unknown choice: '${playersChoice}'", 400)
|
||||||
|
}
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
@cask.staticResources("/public")
|
@cask.staticResources("/public")
|
||||||
def publicFiles(req: cask.Request) = {
|
def publicFiles(req: cask.Request) = {
|
||||||
println(s"getting request for ${req.remainingPathSegments}")
|
|
||||||
"public"
|
"public"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,4 +83,9 @@ position: absolute;
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class ShowdownState(
|
||||||
|
var playersChoice: ChoiceBadge,
|
||||||
|
var houseChoice: Option[ChoiceBadge],
|
||||||
|
var gameEnded: Boolean
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue