domino-client/src/views/GameView.vue

271 lines
7.1 KiB
Vue
Raw Normal View History

2024-06-29 16:40:11 +02:00
<script setup lang="ts">
import GameComponent from '@/components/GameComponent.vue'
2024-07-05 01:31:55 +02:00
import { useGameStore } from '@/stores/game'
import { storeToRefs } from 'pinia'
2024-06-29 16:40:11 +02:00
import { inject, onBeforeUnmount, ref } from 'vue'
import { onMounted } from 'vue'
2024-07-05 01:31:55 +02:00
import useClipboard from 'vue-clipboard3'
2024-06-29 16:40:11 +02:00
const socketService: any = inject('socket')
let data = ref('')
let responseField = ref('')
let statusField = ref('')
let sessionId = ref('')
2024-07-05 01:31:55 +02:00
let seed = ref('')
let playerId = ref('')
2024-06-29 16:40:11 +02:00
let selectdAction: any = undefined
2024-07-05 01:31:55 +02:00
const { toClipboard } = useClipboard()
const gameStore = useGameStore()
const { moveToMake, canMakeMove, sessionState, gameState } = storeToRefs(gameStore)
2024-06-29 16:40:11 +02:00
const options = [
{ value: 'createSession', default: '{"user": "arhuako"}' },
2024-07-05 01:31:55 +02:00
{ value: 'startSession', default: (id: string) => `{"sessionId": "${id}"}` }
// { value: 'joinSession', default: '{"user": "pepe", "sessionId": "arhuako"}' },
// { value: 'leaveSession', default: '{"user": "pepe", "sessionId": "arhuako"}' },
// { value: 'chat message', default: 'chat message' }
2024-06-29 16:40:11 +02:00
]
2024-07-05 01:31:55 +02:00
onMounted(async () => {})
2024-06-29 16:40:11 +02:00
2024-07-05 01:31:55 +02:00
function makeMove(move: any) {
moveToMake.value = move
canMakeMove.value = false
2024-06-29 16:40:11 +02:00
}
onBeforeUnmount(() => {
2024-07-05 01:31:55 +02:00
// socketService.disconnect()
2024-06-29 16:40:11 +02:00
})
function actionSelected() {
if (selectdAction.value === 'createSession') {
responseField.value = ''
} else if (selectdAction.value === 'startSession') {
data.value = selectdAction.default(sessionId.value)
return
}
data.value = selectdAction.default
}
const getMessage = (msg: string) => {
if (msg.startsWith('{') && msg.endsWith('}')) return JSON.parse(msg)
return msg
}
2024-07-05 01:31:55 +02:00
async function createSession() {
const response = await socketService.sendMessageWithAck('createSession', { user: 'arhuako' })
sessionId.value = response.sessionId
playerId.value = response.playerId
}
async function startSession() {
if (sessionId.value) {
await socketService.sendMessageWithAck('startSession', {
sessionId: sessionId.value,
seed: seed.value.trim()
})
}
}
async function joinSession() {
if (sessionId.value) {
await socketService.sendMessageWithAck('joinSession', {
user: 'pepe',
sessionId: sessionId.value
})
}
}
2024-06-29 16:40:11 +02:00
async function sendMessage() {
if (selectdAction && data.value.trim() !== '') {
const response = await socketService.sendMessageWithAck(
selectdAction.value,
getMessage(data.value.trim())
)
handleResponse(response)
}
// socketService.emit('message', data.value)
}
function handleResponse(response: any) {
if (selectdAction.value === 'createSession') {
sessionId.value = response.sessionId
2024-07-05 01:31:55 +02:00
playerId.value = response.playerId
2024-06-29 16:40:11 +02:00
}
data.value = ''
const responseStr = JSON.stringify(response, null, 2)
responseField.value = !responseField.value
? responseStr
: responseField.value + '\n---\n ' + responseStr
selectdAction = undefined
}
2024-07-05 01:31:55 +02:00
function copySeed() {
if (sessionState?.value?.seed) toClipboard(sessionState.value.seed)
}
2024-06-29 16:40:11 +02:00
</script>
<template>
2024-07-05 01:31:55 +02:00
<div class="block">
<section class="block">
<p>
Running: {{ sessionState?.sessionInProgress }} Seed: {{ sessionState?.seed }}
<button @click="copySeed">Copy!</button>
</p>
<p>FreeEnds: {{ gameState?.boardFreeEnds }} - {{ gameState?.currentPlayer?.name }}</p>
<p v-if="sessionId">SessionID: {{ sessionId }} PlayerID: {{ playerId }}</p>
</section>
<section class="block">
<div class="game-container">
<GameComponent :playerId="playerId" :canMakeMove="canMakeMove" @move="makeMove" />
</div>
</section>
<section class="block">
<div class="fixed-grid has-8-cols">
<div class="grid" v-if="!sessionId">
<div class="cell">
<button style="width: 200px" class="button" @click="createSession">
Create Session
</button>
2024-06-29 16:40:11 +02:00
</div>
2024-07-05 01:31:55 +02:00
<div class="cell is-col-span7"></div>
2024-06-29 16:40:11 +02:00
</div>
2024-07-05 01:31:55 +02:00
<div class="grid" v-if="sessionId">
<div class="cell">
<button class="button" style="width: 200px" @click="startSession">Start Session</button>
</div>
<div class="cell is-col-span-7">
<input class="input" style="margin-bottom: 0" v-model="seed" placeholder="Seed" />
2024-06-29 16:40:11 +02:00
</div>
</div>
2024-07-05 01:31:55 +02:00
<div class="grid" v-if="!sessionId">
<div class="cell">
<button class="button" style="width: 200px" @click="joinSession">Join Session</button>
</div>
<div class="cell is-col-span-7">
<input
class="input"
style="margin-bottom: 0"
v-model="sessionId"
placeholder="Session Id"
2024-06-29 16:40:11 +02:00
/>
</div>
</div>
2024-07-05 01:31:55 +02:00
<div class="mt-1 action-select"></div>
2024-06-29 16:40:11 +02:00
</div>
2024-07-05 01:31:55 +02:00
<div class="grid" style="margin-top: 16px; display: none">
<div>
<!-- <ul id="messages"></ul> -->
<form id="form" action="">
<div class="action-select select">
<select
v-model="selectdAction"
id="event"
autocomplete="off"
@change="actionSelected"
>
<option value="">Select event</option>
<option :key="option.value" v-for="option in options" :value="option">
{{ option.value }}
</option>
</select>
<button @click.prevent.stop="sendMessage">Send</button>
</div>
<!-- <p><input id="room" autocomplete="off" /></p> -->
<p>
<textarea
v-model="data"
id="message"
autocomplete="off"
placeholder="Data"
></textarea>
</p>
</form>
</div>
<div>
<div class="grid">
<div>
<textarea
:value="responseField"
id="response"
autocomplete="off"
placeholder="Response"
></textarea>
</div>
<div>
<textarea
:value="statusField"
id="status"
autocomplete="off"
placeholder="Game status"
></textarea>
</div>
</div>
2024-06-29 16:40:11 +02:00
</div>
</div>
2024-07-05 01:31:55 +02:00
</section>
2024-06-29 16:40:11 +02:00
</div>
</template>
<style scoped lang="scss">
* {
box-sizing: border-box;
}
2024-07-05 01:31:55 +02:00
.action-select {
display: flex;
gap: 16px;
align-items: start;
justify-items: center;
}
.game-container {
display: flex;
align-items: start;
justify-content: center;
}
2024-06-29 16:40:11 +02:00
.control {
padding: 8px;
margin-right: 4px;
}
textarea {
width: 100%;
2024-07-05 01:31:55 +02:00
height: 110px;
2024-06-29 16:40:11 +02:00
resize: none;
}
#response,
#status {
2024-07-05 01:31:55 +02:00
height: 180px;
2024-06-29 16:40:11 +02:00
}
.tiles-container {
display: flex;
gap: 4px;
flex-flow: row wrap;
align-content: flex-start;
}
.board-container {
position: absolute;
height: 600px;
padding: 10px;
width: calc(50% - 50px);
background-color: var(--pico-form-element-background-color);
}
.hand-container {
position: fixed;
bottom: 0;
height: 200px;
padding: 10px;
width: calc(50% - 50px);
background-color: var(--pico-form-element-background-color);
}
</style>