feat(14): controls generated from fragment

with their own ids and htmx requests to submit the vote
This commit is contained in:
efim 2023-07-01 13:40:48 +00:00
parent 560ce6896a
commit 69a464a767
4 changed files with 73 additions and 42 deletions

View File

@ -522,6 +522,10 @@ video {
--tw-backdrop-sepia: ; --tw-backdrop-sepia: ;
} }
.static {
position: static;
}
.fixed { .fixed {
position: fixed; position: fixed;
} }

View File

@ -59,34 +59,52 @@
<section <section
id="controls" id="controls"
class=" bg-center bg-no-repeat bg-60% bg-triangle-pattern w-[375px] h-[375px] relative" class="bg-center bg-no-repeat bg-60% bg-triangle-pattern w-[375px] h-[375px] relative"
> >
<!-- This control will be repeated 3 times, with different htmx requests -->
<div <div
id="paper" th:each="choiceBadgeData : ${choiceBadges}"
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)]" id="paper-control"
style=" th:id="${choiceBadgeData.c.name} + '-control'"
--diameter: 8rem;
--bg-dark: hsl(230, 89%, 62%);
--bg-bright: hsl(230, 89%, 65%);
--top-offset: 6rem;
--left-offset: 6rem;
--translation: 50%;
position: absolute;
"
hx-get="/select/paper" hx-get="/select/paper"
th:hx-get="'/select/' + ${choiceBadgeData.c.name}"
hx-target="#controls" hx-target="#controls"
hx-swap="outerHTML" hx-swap="outerHTML"
> >
<!-- This badge is fragment to be repeated in other pages as well -->
<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:fragment="choiceBadge (choiceBadgeData)"
></div> id="paper"
<img th:id="${choiceBadgeData.c.name}"
src="../public/images/icon-paper.svg" 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)]"
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2" style="
/> --diameter: 8rem;
--bg-dark: hsl(230, 89%, 62%);
--bg-bright: hsl(230, 89%, 65%);
--top-offset: 6rem;
--left-offset: 6rem;
--translation: 50%;
position: absolute;
"
th:style="| --diameter: ${choiceBadgeData.c.diameter};
--bg-dark: ${choiceBadgeData.c.bgDark};
--bg-bright: ${choiceBadgeData.c.bgBright};
${choiceBadgeData.p.toStyle}; |"
>
<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-paper.svg"
th:src="${choiceBadgeData.c.iconPath}"
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2"
/>
</div>
</div> </div>
<!-- This controls is only for static preview -->
<div <div
th:remove="all"
id="scissors" id="scissors"
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)]" 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=" style="
@ -108,7 +126,9 @@
/> />
</div> </div>
<!-- This controls is only for static preview -->
<div <div
th:remove="all"
id="rock" 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)]" 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=" style="

View File

@ -47,10 +47,10 @@ object Main {
@cask.get("/") @cask.get("/")
def index(req: cask.Request) = { def index(req: cask.Request) = {
val context = new Context() val context = new Context()
println(s"getting request for ${req.remainingPathSegments}") val choices = Models.choiceSelectionItems.asJava
context.setVariable( context.setVariable(
"myVar", "choiceBadges",
"Hello, from Scala world!" choices
) )
val result = templateEngine.process("index", context) val result = templateEngine.process("index", context)
cask.Response( cask.Response(

View File

@ -6,14 +6,14 @@ object Models {
sealed trait Positioning sealed trait Positioning
object Positioning { object Positioning {
case object Relative extends Positioning { case object Relative extends Positioning {
override def toString(): String = " position: absolute; " def toStyle(): String = " position: absolute; "
} }
final case class Absolute( final case class Absolute(
topOffset: String, topOffset: String,
leftOffset: String, leftOffset: String,
translation: String = "50%" translation: String = "50%"
) extends Positioning { ) extends Positioning {
override def toString(): String = def toStyle(): String =
s""" s"""
--top-offset: $topOffset; --top-offset: $topOffset;
--left-offset: $leftOffset; --left-offset: $leftOffset;
@ -27,6 +27,8 @@ position: absolute;
def diameter: String def diameter: String
def bgDark: String def bgDark: String
def bgBright: String def bgBright: String
def name: String
def iconPath: String
} }
object Choice { object Choice {
val scissorsDark = "hsl(39, 89%, 49%)" val scissorsDark = "hsl(39, 89%, 49%)"
@ -40,39 +42,44 @@ position: absolute;
diameter: String, diameter: String,
bgDark: String = paperDark, bgDark: String = paperDark,
bgBright: String = paperBright bgBright: String = paperBright
) extends Choice ) extends Choice {
def name: String = "paper"
def iconPath: String = "public/images/icon-paper.svg"
}
case class Scissors( case class Scissors(
diameter: String, diameter: String,
bgDark: String = scissorsDark, bgDark: String = scissorsDark,
bgBright: String = scissorsBright bgBright: String = scissorsBright
) extends Choice ) extends Choice {
def name: String = "scissors"
def iconPath: String = "public/images/icon-scissors.svg"
}
case class Rock( case class Rock(
diameter: String, diameter: String,
bgDark: String = rockDark, bgDark: String = rockDark,
bgBright: String = rockBright bgBright: String = rockBright
) extends Choice ) extends Choice {
} def name: String = "rock"
def iconPath: String = "public/images/icon-rock.svg"
/**
* this will be Data Transfer Object, because Thymeleaf wants var and Bean Object Notation
* and i want vals and enums
*/
final class ChoiceBadge(
var diameter: String = "",
var bgDark: String = "",
var bgBright: String = "",
var positioningStyle: String = "",
) {
def this(c: Choice, p: Positioning) = {
this(c.diameter, c.bgDark, c.bgBright, p.toString())
} }
} }
/** this will be Data Transfer Object, because Thymeleaf wants var and i want
* vals and enums
*/
final case class ChoiceBadge(
var c: Choice,
var p: Positioning
)
val choiceSelectionItems = { val choiceSelectionItems = {
List( List(
ChoiceBadge(Choice.Paper("8rem"), Positioning.Absolute("6rem", "6rem")), ChoiceBadge(Choice.Paper("8rem"), Positioning.Absolute("6rem", "6rem")),
ChoiceBadge(Choice.Scissors("8rem"), Positioning.Absolute("6rem", "17rem")), ChoiceBadge(
ChoiceBadge(Choice.Rock("8rem"), Positioning.Absolute("15rem", "11.5rem")), Choice.Scissors("8rem"),
Positioning.Absolute("6rem", "17rem")
),
ChoiceBadge(Choice.Rock("8rem"), Positioning.Absolute("15rem", "11.5rem"))
) )
} }