diff --git a/src/main/kotlin/de/pheerai/buzzer/alpine/attributes.kt b/src/main/kotlin/de/pheerai/buzzer/alpine/attributes.kt new file mode 100644 index 0000000..a580a23 --- /dev/null +++ b/src/main/kotlin/de/pheerai/buzzer/alpine/attributes.kt @@ -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 +} diff --git a/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt b/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt index 487bc68..061eb37 100644 --- a/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt +++ b/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt @@ -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 = "" } } + 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!" } } } diff --git a/src/main/resources/css/player.css b/src/main/resources/css/player.css index 805e368..41dcbf5 100644 --- a/src/main/resources/css/player.css +++ b/src/main/resources/css/player.css @@ -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; } diff --git a/src/main/resources/js/playerClient.js b/src/main/resources/js/playerClient.js index 58db232..fc411e9 100644 --- a/src/main/resources/js/playerClient.js +++ b/src/main/resources/js/playerClient.js @@ -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!"); } }