Migrate player client to Alpine.js.

This commit is contained in:
Oliver Rümpelein 2021-09-25 15:47:50 +02:00
parent 5b13eb5ece
commit 7357528bb5
4 changed files with 122 additions and 14 deletions

View file

@ -0,0 +1,45 @@
package de.pheerai.buzzer.alpine
import kotlinx.html.HTMLTag
fun HTMLTag.xData(data: String) {
attributes["x-data"] = data
}
fun HTMLTag.xInit(init: String) {
attributes["x-init"] = init
}
fun HTMLTag.xOn(event: String, handler: String, debounce: Boolean = false, debounceMs: Int = 0) {
val debounceString = if (debounce && debounceMs > 0) {
".debounce.${debounceMs}ms"
} else if (debounce) {
".debounce"
} else {
""
}
attributes["x-on:${event}$debounceString"] = handler
}
fun HTMLTag.xModel(model: String, debounce: Boolean = false, debounceMs: Int = 0) {
val debounceString = if (debounce && debounceMs > 0) {
".debounce.${debounceMs}ms"
} else if (debounce) {
".debounce"
} else {
""
}
attributes["x-model$debounceString"] = model
}
fun HTMLTag.xShow(data: String) {
attributes["x-show"] = data
}
fun HTMLTag.xText(text: String) {
attributes["x-text"] = text
}
fun HTMLTag.xBind(type: String, data: String) {
attributes["x-bind:$type"] = data
}

View file

@ -1,5 +1,6 @@
package de.pheerai.buzzer.clients
import de.pheerai.buzzer.alpine.*
import kotlinx.html.*
fun HTML.createPlayerDocument() {
@ -11,23 +12,55 @@ fun HTML.createPlayerDocument() {
rel = "stylesheet",
type = "text/css"
)
script { src = "https://code.jquery.com/jquery-3.6.0.min.js" }
script { src = "/assets/playerClient.js" }
script {
src = "https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"
defer = true
}
script {
src = "/assets/playerClient.js"
}
}
body {
div(classes = "parent") {
attributes["foo"] = "bar"
xInit("startWebSocket()")
xData("{playerName: \"\"}")
div(classes = "input") {
label { +"Player" }
div(classes = "bumper") {}
input {
xModel("playerName", debounce = true)
type = InputType.text
id = "username"
placeholder = "<name>"
}
}
div(classes = "submit disabled") {
xShow("!playerName")
+"Enter a name first!"
}
button(classes = "submit") {
onClick = "sendUsername()"
+"I know that!"
xShow("playerName")
xData("{clicked: false}")
xOn(
"click",
"""
() => {
sendUsername(playerName);
clicked = true
setTimeout(() => {
clicked = false
}, 50)
}
""".trimMargin()
)
xOn("mousedown", "clicked = true")
xOn("touchstart", "clicked = true")
xBind("class", "{'active': clicked}")
+"I'm "
span {
xText("playerName")
}
+" and I know this!"
}
}
}

View file

@ -52,8 +52,9 @@ div > .submit {
display: flex;
align-items: center;
justify-content: center;
white-space: pre;
}
div > .button:hover {
div > button.active {
background-color: #5B1D4A;
}

View file

@ -2,17 +2,46 @@
let webSocket;
$.when($.ready).then(function () {
function startWebSocket() {
let protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:';
webSocket = new WebSocket(`${protocolPrefix}//${location.host}/socket/player`);
});
webSocket.onerror = (ev) => {
switch (ev.code) {
case 1000:
console.log("[WS]: Closed normally")
break
default:
console.log("[WS]: Closed abnormally")
reconnectWebSocket();
}
};
webSocket.onclose = (ev) => {
switch (ev.code) {
case 'ECONNREFUSED':
reconnectWebSocket();
break
default:
webSocket.onerror(ev);
}
};
}
function sendUsername() {
const username = $('#username').val()
if (username !== null && username !== '') {
console.log(`Username: ${username}`)
webSocket.send(username)
function reconnectWebSocket() {
setTimeout(() => {
console.log("[WS]: Reconnecting...")
startWebSocket()
}, 2000)
}
function sendUsername(username) {
if (
username !== undefined
&& username !== null
&& username !== ''
) {
console.log(`Username: ${username}`);
webSocket.send(username);
} else {
alert("Please enter a name!")
alert("Please enter a name!");
}
}