diff options
Diffstat (limited to 'frontend/src/views/HostView.vue')
| -rw-r--r-- | frontend/src/views/HostView.vue | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/frontend/src/views/HostView.vue b/frontend/src/views/HostView.vue new file mode 100644 index 0000000..5b29289 --- /dev/null +++ b/frontend/src/views/HostView.vue @@ -0,0 +1,75 @@ +<script setup lang="ts"> +import { ref, type Ref } from 'vue'; +import type TetrisBoard from '../components/TetrisBoard.vue'; + +let started = ref(false) +let waitingForCode = ref(true) +let code = ref('') +let url = ref(''); +let numClients = ref(0); +let inputQueue: Ref<Array<string>> = ref([]); + +let socket: WebSocket; + +function startGame() { + if (!socket) { + return; + } + socket.send(JSON.stringify({ + action: 'start', + sessionId: code.value, + })); +} + +fetch(`${import.meta.env.VITE_BACKEND_BASE_URL}/session`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + } +).then(async (response) => { + const data: any = await response.json(); + code.value = data.id; + url.value = `${import.meta.env.VITE_FRONTEND_BASE_URL}/join/${data.id}`; + waitingForCode.value = false; + openSocket(data.id); +}); + +function openSocket(id: string) { + socket = new WebSocket(`${import.meta.env.VITE_BACKEND_WS_URL}`); + + socket.onopen = () => { + socket.send(JSON.stringify({ + action: 'host', + sessionId: id, + })); + }; + socket.onmessage = (event) => { + const data = JSON.parse(event.data); + if (data.action === 'join') { + numClients.value = data.clients; + } else if (data.action === 'state' && data.state === 'playing') { + started.value = true; + } else if (data.action === 'move') { + inputQueue.value.push(data.move); + } + }; +} +</script> + +<template> + <main> + <template v-if="waitingForCode"> + <h1>Requesting session...</h1> + </template> + <template v-if="!started && !waitingForCode"> + <h1>Join this game</h1> + <QRCode size=500 level="M" :value="url"></QRCode> + <h2><a :href="url">{{ url }}</a></h2> + <p>Connected clients: {{ numClients }}</p> + <button @click="startGame">Start game</button> + </template> + <TetrisBoard v-if="started" :networked="true" :input-queue="inputQueue"></TetrisBoard> + </main> +</template> |
