From 814d2885ed124b8126f8180be48c6c4dc2f81db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20R=C3=BCmpelein?= Date: Sun, 26 Sep 2021 14:59:37 +0200 Subject: [PATCH] Migrate game master client to alpine --- .../de/pheerai/buzzer/alpine/template.kt | 14 ++++++ .../de/pheerai/buzzer/clients/adminClient.kt | 21 --------- .../buzzer/clients/gameMasterClient.kt | 47 +++++++++++++++++++ .../de/pheerai/buzzer/clients/playerClient.kt | 12 ++++- .../de/pheerai/buzzer/routing/setupRoutes.kt | 4 +- src/main/resources/js/adminClient.js | 21 --------- src/main/resources/js/buzzerWebSocket.js | 34 ++++++++++++++ src/main/resources/js/gameMasterClient.js | 5 ++ src/main/resources/js/playerClient.js | 35 +------------- 9 files changed, 114 insertions(+), 79 deletions(-) create mode 100644 src/main/kotlin/de/pheerai/buzzer/alpine/template.kt delete mode 100644 src/main/kotlin/de/pheerai/buzzer/clients/adminClient.kt create mode 100644 src/main/kotlin/de/pheerai/buzzer/clients/gameMasterClient.kt delete mode 100644 src/main/resources/js/adminClient.js create mode 100644 src/main/resources/js/buzzerWebSocket.js create mode 100644 src/main/resources/js/gameMasterClient.js diff --git a/src/main/kotlin/de/pheerai/buzzer/alpine/template.kt b/src/main/kotlin/de/pheerai/buzzer/alpine/template.kt new file mode 100644 index 0000000..6440878 --- /dev/null +++ b/src/main/kotlin/de/pheerai/buzzer/alpine/template.kt @@ -0,0 +1,14 @@ +package de.pheerai.buzzer.alpine + +import kotlinx.html.* + +open class TEMPLATE( + initialAttributes: Map, + override val consumer: TagConsumer<*>, +) : HTMLTag("template", consumer, initialAttributes, null, false, false), + HtmlBlockTag + +@HtmlTagMarker +inline fun FlowContent.template(classes: String? = null, crossinline block: TEMPLATE.() -> Unit = {}): Unit = TEMPLATE( + attributesMapOf("class", classes), consumer +).visit(block) diff --git a/src/main/kotlin/de/pheerai/buzzer/clients/adminClient.kt b/src/main/kotlin/de/pheerai/buzzer/clients/adminClient.kt deleted file mode 100644 index b0bb01d..0000000 --- a/src/main/kotlin/de/pheerai/buzzer/clients/adminClient.kt +++ /dev/null @@ -1,21 +0,0 @@ -package de.pheerai.buzzer.clients - -import kotlinx.html.* - -fun HTML.createAdminDocument() { - head { - meta { charset = "UTF-8" } - title { +"JS Client" } - script { src = "https://code.jquery.com/jquery-3.6.0.min.js" } - script { src = "/assets/adminClient.js" } - } - body { - ol { - id = "usernames" - } - button { - onClick = "resetReceived()" - +"Reset" - } - } -} diff --git a/src/main/kotlin/de/pheerai/buzzer/clients/gameMasterClient.kt b/src/main/kotlin/de/pheerai/buzzer/clients/gameMasterClient.kt new file mode 100644 index 0000000..a21b436 --- /dev/null +++ b/src/main/kotlin/de/pheerai/buzzer/clients/gameMasterClient.kt @@ -0,0 +1,47 @@ +package de.pheerai.buzzer.clients + +import de.pheerai.buzzer.alpine.* +import kotlinx.html.* + +fun HTML.createGameMasterDocument() { + head { + meta { charset = "UTF-8" } + title { +"JS Client" } + link( + href = "/assets/colors.css", + rel = "stylesheet", + type = "text/css" + ) + script { + src = "https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" + defer = true + } + script { src = "/assets/gameMasterClient.js" } + script { src = "/assets/buzzerWebSocket.js" } + } + body { + xData("{receivedNames: [], buzzerWebSocket: null}") + xInit( + //language=JavaScript + """ + () => { + startWebSocket('/socket/master', (ev) => { + receivedNames.push(ev.data) + }); + } + """.trimIndent() + ) + div(classes = "parent") { + button { + xOn("click", "receivedNames = []") + +"Reset" + } + ol { + template { + attributes["x-for"] = "name in receivedNames" + this@ol.li { xText("name") } + } + } + } + } +} diff --git a/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt b/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt index 267ad54..a830ab1 100644 --- a/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt +++ b/src/main/kotlin/de/pheerai/buzzer/clients/playerClient.kt @@ -21,13 +21,23 @@ fun HTML.createPlayerDocument() { src = "https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer = true } + script { + src = "/assets/buzzerWebSocket.js" + } script { src = "/assets/playerClient.js" } } body { div(classes = "parent") { - xInit("startWebSocket()") + xInit( + """ + () => { + Alpine.data('buzzerWebSocket', null) + startWebSocket('/socket/player') + } + """.trimIndent() + ) xData("{playerName: \"\"}") div(classes = "input") { label { +"Player" } diff --git a/src/main/kotlin/de/pheerai/buzzer/routing/setupRoutes.kt b/src/main/kotlin/de/pheerai/buzzer/routing/setupRoutes.kt index bbe5e51..37fd54b 100644 --- a/src/main/kotlin/de/pheerai/buzzer/routing/setupRoutes.kt +++ b/src/main/kotlin/de/pheerai/buzzer/routing/setupRoutes.kt @@ -1,6 +1,6 @@ package de.pheerai.buzzer.routing -import de.pheerai.buzzer.clients.createAdminDocument +import de.pheerai.buzzer.clients.createGameMasterDocument import de.pheerai.buzzer.clients.createPlayerDocument import de.pheerai.buzzer.handlers.handleGameMasterSocket import de.pheerai.buzzer.handlers.handlePlayerSocket @@ -39,7 +39,7 @@ private fun Routing.clientRoutes() { get("/client/master") { call.respondHtml { - createAdminDocument() + createGameMasterDocument() } } } diff --git a/src/main/resources/js/adminClient.js b/src/main/resources/js/adminClient.js deleted file mode 100644 index fc8f214..0000000 --- a/src/main/resources/js/adminClient.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -let adminSocket; - -$.when($.ready).then(function () { - let protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:'; - adminSocket = new WebSocket(`${protocolPrefix}//${location.host}/socket/master`); - - adminSocket.addEventListener('message', (ev) => { - console.log(`Received: ${ev.data}`) - appendUsername(ev.data) - }); -}); - -function appendUsername(username) { - $('ol#usernames').append(`
  • ${username}
  • `) -} - -function resetReceived() { - $('ol#usernames').empty() -} diff --git a/src/main/resources/js/buzzerWebSocket.js b/src/main/resources/js/buzzerWebSocket.js new file mode 100644 index 0000000..82d9c1b --- /dev/null +++ b/src/main/resources/js/buzzerWebSocket.js @@ -0,0 +1,34 @@ +'use strict'; + +function startWebSocket(socketPath, messageHandler) { + const protocolPrefix = (window.location.protocol === 'https:') ? 'wss:' : 'ws:'; + const webSocket = new WebSocket(`${protocolPrefix}//${location.host}${socketPath}`); + webSocket.onerror = (ev) => { + switch (ev.code) { + case 1000: + console.log("[WS]: Closed normally") + break + default: + console.log("[WS]: Closed abnormally") + reconnectWebSocket(socketPath, messageHandler); + } + }; + webSocket.onclose = (ev) => { + switch (ev.code) { + case 'ECONNREFUSED': + reconnectWebSocket(socketPath, messageHandler); + break + default: + webSocket.onerror(ev); + } + }; + webSocket.onmessage = messageHandler ? messageHandler : () => {}; + Alpine.data.buzzerWebSocket = webSocket +} + +function reconnectWebSocket(socketPath, messageHandler) { + setTimeout(() => { + console.log("[WS]: Reconnecting...") + startWebSocket(socketPath, messageHandler) + }, 2000) +} diff --git a/src/main/resources/js/gameMasterClient.js b/src/main/resources/js/gameMasterClient.js new file mode 100644 index 0000000..db9c853 --- /dev/null +++ b/src/main/resources/js/gameMasterClient.js @@ -0,0 +1,5 @@ +'use strict'; + +function appendUsername(username) { + $('ol#usernames').append(`
  • ${username}
  • `) +} diff --git a/src/main/resources/js/playerClient.js b/src/main/resources/js/playerClient.js index fc411e9..eeaa47e 100644 --- a/src/main/resources/js/playerClient.js +++ b/src/main/resources/js/playerClient.js @@ -1,38 +1,5 @@ 'use strict'; -let webSocket; - -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 reconnectWebSocket() { - setTimeout(() => { - console.log("[WS]: Reconnecting...") - startWebSocket() - }, 2000) -} - function sendUsername(username) { if ( username !== undefined @@ -40,7 +7,7 @@ function sendUsername(username) { && username !== '' ) { console.log(`Username: ${username}`); - webSocket.send(username); + Alpine.data.buzzerWebSocket.send(username); } else { alert("Please enter a name!"); }