initial commit
This commit is contained in:
@ -1,119 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import GameComponent from '@/components/GameComponent.vue'
|
||||
import TileComponent from '@/components/TileComponent.vue'
|
||||
import type { GameState, PlayerState } from '@/utilities/interfaces'
|
||||
import { useGameStore } from '@/stores/game'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { inject, onBeforeUnmount, ref } from 'vue'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
|
||||
const socketService: any = inject('socket')
|
||||
const { socket } = socketService
|
||||
let gameState = ref<GameState | undefined>(undefined)
|
||||
let playerState = ref<PlayerState | undefined>(undefined)
|
||||
let data = ref('')
|
||||
let responseField = ref('')
|
||||
let statusField = ref('')
|
||||
let sessionId = ref('')
|
||||
let seed = ref('')
|
||||
let playerId = ref('')
|
||||
let selectdAction: any = undefined
|
||||
let canSelectTile = false
|
||||
let canMakeMove = false
|
||||
let tileSelected = ''
|
||||
let moveType = ''
|
||||
|
||||
const { toClipboard } = useClipboard()
|
||||
const gameStore = useGameStore()
|
||||
const { moveToMake, canMakeMove, sessionState, gameState } = storeToRefs(gameStore)
|
||||
const options = [
|
||||
{ value: 'createSession', default: '{"user": "arhuako"}' },
|
||||
{ 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' }
|
||||
{ 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' }
|
||||
]
|
||||
|
||||
onMounted(async () => {
|
||||
socket.on('gameState', (data: GameState, callback: any) => {
|
||||
gameState.value = data
|
||||
statusField.value = statusField.value + JSON.stringify(data, null, 2)
|
||||
callback({
|
||||
status: 'ok'
|
||||
})
|
||||
})
|
||||
onMounted(async () => {})
|
||||
|
||||
socket.on('playerState', (data: PlayerState, callback: any) => {
|
||||
console.log('playerState :>> ', data)
|
||||
playerState.value = data
|
||||
statusField.value = statusField.value + JSON.stringify(data, null, 2)
|
||||
callback({
|
||||
status: 'ok'
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('makeMove', async (data: any, callback: any) => {
|
||||
statusField.value = statusField.value + JSON.stringify(data, null, 2)
|
||||
canMakeMove = true
|
||||
while (canMakeMove) {
|
||||
await wait(500)
|
||||
}
|
||||
callback({
|
||||
status: 'ok',
|
||||
tileId: tileSelected,
|
||||
moveType
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('chooseTile', async (data: any, callback: any) => {
|
||||
statusField.value = statusField.value + JSON.stringify(data, null, 2)
|
||||
canSelectTile = true
|
||||
while (canSelectTile) {
|
||||
await wait(500)
|
||||
}
|
||||
callback({
|
||||
status: 'ok',
|
||||
tileId: tileSelected
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function selectTile(id: string) {
|
||||
if (canSelectTile) {
|
||||
tileSelected = id
|
||||
canSelectTile = false
|
||||
}
|
||||
}
|
||||
|
||||
function selectTileToMove(id: string) {
|
||||
if (canMakeMove) {
|
||||
if (tileSelected === id) {
|
||||
tileSelected = ''
|
||||
return
|
||||
}
|
||||
tileSelected = id
|
||||
}
|
||||
}
|
||||
|
||||
function onTileClick(tileId: string) {
|
||||
console.log('tileId :>> ', tileId)
|
||||
selectTile(tileId)
|
||||
}
|
||||
|
||||
function makeMove(type: string) {
|
||||
if (canMakeMove) {
|
||||
if (type === 'pass') {
|
||||
tileSelected = ''
|
||||
canMakeMove = false
|
||||
} else if (tileSelected) {
|
||||
moveType = type
|
||||
canMakeMove = false
|
||||
}
|
||||
}
|
||||
function makeMove(move: any) {
|
||||
moveToMake.value = move
|
||||
canMakeMove.value = false
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
socketService.disconnect()
|
||||
// socketService.disconnect()
|
||||
})
|
||||
|
||||
function actionSelected() {
|
||||
console.log('event :>> ', selectdAction)
|
||||
|
||||
if (selectdAction.value === 'createSession') {
|
||||
responseField.value = ''
|
||||
} else if (selectdAction.value === 'startSession') {
|
||||
@ -129,15 +53,36 @@ const getMessage = (msg: string) => {
|
||||
return msg
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
if (selectdAction && data.value.trim() !== '') {
|
||||
console.log('socketService :>> ', socketService)
|
||||
|
||||
const response = await socketService.sendMessageWithAck(
|
||||
selectdAction.value,
|
||||
getMessage(data.value.trim())
|
||||
)
|
||||
console.log('response :>> ', response)
|
||||
handleResponse(response)
|
||||
}
|
||||
// socketService.emit('message', data.value)
|
||||
@ -146,6 +91,7 @@ async function sendMessage() {
|
||||
function handleResponse(response: any) {
|
||||
if (selectdAction.value === 'createSession') {
|
||||
sessionId.value = response.sessionId
|
||||
playerId.value = response.playerId
|
||||
}
|
||||
|
||||
data.value = ''
|
||||
@ -155,101 +101,113 @@ function handleResponse(response: any) {
|
||||
: responseField.value + '\n---\n ' + responseStr
|
||||
selectdAction = undefined
|
||||
}
|
||||
|
||||
function copySeed() {
|
||||
if (sessionState?.value?.seed) toClipboard(sessionState.value.seed)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid">
|
||||
<div>
|
||||
<GameComponent :gameState="gameState" :playerState="playerState" @tileClick="onTileClick" />
|
||||
<p>SessionID: {{ sessionId }}</p>
|
||||
<ul id="messages"></ul>
|
||||
<form id="form" action="">
|
||||
<p>
|
||||
<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>
|
||||
</p>
|
||||
<!-- <p><input id="room" autocomplete="off" /></p> -->
|
||||
<p>
|
||||
<textarea v-model="data" id="message" autocomplete="off" placeholder="Data"></textarea>
|
||||
</p>
|
||||
<p><button @click.prevent.stop="sendMessage">Send</button></p>
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<!-- <div style="display: flex; gap: 4px">
|
||||
<TileComponent :revealed="false" :top="6" :bottom="0" />
|
||||
<TileComponent :revealed="true" :top="6" :bottom="0" />
|
||||
</div> -->
|
||||
<h4>Board</h4>
|
||||
<!-- Board -->
|
||||
<div class="board-container">
|
||||
<div v-if="gameState?.tileSelectionPhase">
|
||||
<div class="tiles-container">
|
||||
<TileComponent
|
||||
:key="tile.id"
|
||||
v-for="tile in gameState.boneyard"
|
||||
@tile-clicked="selectTile(tile.id)"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="canSelectTile">Please select a tile.</div>
|
||||
<div v-else>Wait your turn.</div>
|
||||
</div>
|
||||
<div v-if="!gameState?.tileSelectionPhase">
|
||||
<div class="tiles-container">
|
||||
<TileComponent
|
||||
:class="{ 'selected-tile': tileSelected === tile.id }"
|
||||
:revealed="true"
|
||||
:key="tile.id"
|
||||
v-for="tile in gameState?.board"
|
||||
:top="tile.pips[0]"
|
||||
:bottom="tile.pips[1]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<!-- End board-->
|
||||
</section>
|
||||
|
||||
<div class="hand-container">
|
||||
<h4>
|
||||
Your Hand <button class="control" @click="makeMove('left')">Left</button
|
||||
><button class="control" @click="makeMove('right')">Right</button
|
||||
><button class="control" @click="makeMove('pass')">Pass</button>
|
||||
</h4>
|
||||
<div class="tiles-container">
|
||||
<TileComponent
|
||||
:revealed="true"
|
||||
:key="tile.id"
|
||||
v-for="tile in playerState?.hand ?? []"
|
||||
@tile-clicked="selectTileToMove(tile.id)"
|
||||
:top="tile.pips[0]"
|
||||
:bottom="tile.pips[1]"
|
||||
/>
|
||||
<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>
|
||||
</div>
|
||||
<div class="cell is-col-span7"></div>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
</div>
|
||||
<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"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 action-select"></div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End hand-->
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -258,21 +216,32 @@ function handleResponse(response: any) {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.action-select {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: start;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.game-container {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.control {
|
||||
font-size: 60%;
|
||||
padding: 8px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
height: 110px;
|
||||
resize: none;
|
||||
font-size: 70%;
|
||||
}
|
||||
#response,
|
||||
#status {
|
||||
height: 400px;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.tiles-container {
|
||||
|
@ -9,16 +9,21 @@ function startGame() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="home">
|
||||
<h1>Welcome to the Player's Home Page</h1>
|
||||
<p>This is a protected route.</p>
|
||||
<button @click="startGame">Start Game</button>
|
||||
<div class="block home">
|
||||
<section class="section">
|
||||
<h1 class="title is-2">Welcome to the Player's Home Page</h1>
|
||||
<div class="block">
|
||||
<p>This is a protected route.</p>
|
||||
</div>
|
||||
<button class="button" @click="startGame">Start Game</button>
|
||||
</section>
|
||||
<section class="section available-sessions">
|
||||
<h2 class="title is-4">Available Sessions</h2>
|
||||
<div class="bloc">
|
||||
<p>There are no available sessions at the moment.</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.home {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
@ -19,10 +19,28 @@ function login() {
|
||||
<template>
|
||||
<div class="login">
|
||||
<h1>Login</h1>
|
||||
<form @submit.prevent="login">
|
||||
<input type="text" v-model="username" placeholder="Username" />
|
||||
<input type="password" v-model="password" placeholder="Password" />
|
||||
<button type="submit">Login</button>
|
||||
<form class="form" @submit.prevent="login">
|
||||
<div class="field">
|
||||
<label class="label">Username</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" v-model="username" placeholder="Username" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Username</label>
|
||||
<div class="control">
|
||||
<input class="input" type="password" v-model="password" placeholder="Password" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit">Login</button>
|
||||
</div>
|
||||
<!-- <div class="control">
|
||||
<button class="button">Cancel</button>
|
||||
</div> -->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
Reference in New Issue
Block a user