209 lines
6.9 KiB
Vue
209 lines
6.9 KiB
Vue
<script setup lang="ts">
|
|
import { inject, onMounted, onUnmounted, ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useGameStore } from '@/stores/game'
|
|
import { storeToRefs } from 'pinia'
|
|
import type { LoggingService } from '@/services/LoggingService'
|
|
import type { GameService } from '@/services/GameService'
|
|
import type { MatchSessionDto } from '@/common/interfaces'
|
|
import { useEventBusStore } from '@/stores/eventBus'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import { copyToclipboard } from '@/common/helpers'
|
|
import { useGameOptionsStore } from '@/stores/gameOptions'
|
|
|
|
let background = ref<string>('green')
|
|
let teamed = ref<boolean>(false)
|
|
let pointsToWin = ref<number>(100)
|
|
let seed = ref<string>('')
|
|
let sessionName = ref('Test Value')
|
|
let matchSessions = ref<MatchSessionDto[]>([])
|
|
let dataInterval: any
|
|
|
|
const router = useRouter()
|
|
const gameStore = useGameStore()
|
|
const auth = useAuthStore()
|
|
const gameOptionsStore = useGameOptionsStore()
|
|
|
|
const socketService: any = inject('socket')
|
|
const gameService: GameService = inject<GameService>('game') as GameService
|
|
const logger: LoggingService = inject<LoggingService>('logger') as LoggingService
|
|
|
|
const { sessionState, isSessionStarted, playerState, amIHost } = storeToRefs(gameStore)
|
|
const { user } = storeToRefs(auth)
|
|
const { gameOptions } = storeToRefs(gameOptionsStore)
|
|
|
|
// function setPlayerReady() {
|
|
// logger.debug('Starting game')
|
|
// if (!sessionState.value) {
|
|
// logger.error('No session found')
|
|
// return
|
|
// }
|
|
// if (!playerState.value) {
|
|
// logger.error('No player found')
|
|
// return
|
|
// }
|
|
// socketService.sendMessage('client:set-player-ready', {
|
|
// userId: playerState.value.id,
|
|
// sessionId: sessionState.value.id
|
|
// })
|
|
// }
|
|
|
|
const eventBus = useEventBusStore()
|
|
eventBus.subscribe('window-before-unload', () => {
|
|
logger.debug('Window before unload')
|
|
})
|
|
|
|
async function createMatch() {
|
|
logger.debug('Creating match')
|
|
await socketService.connect()
|
|
gameOptions.value = { background: background.value }
|
|
const id = await gameService.createMatchSession(sessionName.value, seed.value)
|
|
logger.debug('Match created successfully')
|
|
router.push({ name: 'match', params: { id } })
|
|
}
|
|
|
|
async function joinMatch(id: string) {
|
|
if (id) {
|
|
await socketService.connect()
|
|
await gameService.joinMatchSession(id)
|
|
router.push({ name: 'match', params: { id } })
|
|
}
|
|
}
|
|
async function deleteMatch(id: string) {
|
|
if (id) {
|
|
await socketService.connect()
|
|
await gameService.cancelMatchSession(id)
|
|
loadData()
|
|
}
|
|
}
|
|
|
|
async function loadData() {
|
|
const listResponse = await gameService.listMatchSessions()
|
|
matchSessions.value = listResponse.data
|
|
sessionName.value = `Test #${listResponse.pagination.total + 1}`
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadData()
|
|
dataInterval = setInterval(loadData, 5000)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
clearInterval(dataInterval)
|
|
})
|
|
|
|
function copy(sessionSeed: string) {
|
|
seed.value = sessionSeed
|
|
copyToclipboard(sessionSeed)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="block home">
|
|
<section class="section">
|
|
<h1 class="title is-2">Welcome to the {{ user.username }}'s Home Page</h1>
|
|
<div class="block">
|
|
<div class="field">
|
|
<label class="label">Name</label>
|
|
<div class="control">
|
|
<input type="text" class="input" v-model="sessionName" placeholder="Session Name" />
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<label class="label">Seed</label>
|
|
<div class="control">
|
|
<input
|
|
type="text"
|
|
class="input"
|
|
style="margin-bottom: 0"
|
|
v-model="seed"
|
|
placeholder="Type the session seed here!"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid">
|
|
<div class="cell">
|
|
<div class="field">
|
|
<label for="background" class="label">Background color</label>
|
|
<div class="control">
|
|
<div class="select">
|
|
<select v-model="background" name="background">
|
|
<option value="green">Green Fabric</option>
|
|
<option value="gray">Gray Fabric</option>
|
|
<option value="blue">Blue Fabric</option>
|
|
<option value="yellow">Yellow Fabric</option>
|
|
<option value="red">Red Fabric</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<div class="control">
|
|
<label for="teamed" class="checkbox">
|
|
<input v-model="teamed" name="teamed" type="checkbox" />
|
|
Crossed game ({{ teamed }})
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="cell">
|
|
<div class="field">
|
|
<label for="pointsToWin" class="label">Points to win</label>
|
|
<div class="control">
|
|
<div class="select">
|
|
<select v-model="pointsToWin" name="pointsToWin">
|
|
<option value="50">50</option>
|
|
<option value="80">80</option>
|
|
<option value="100">100</option>
|
|
<option value="150">150</option>
|
|
<option value="200">200</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="block" v-if="!isSessionStarted"></div>
|
|
|
|
<button class="button is-primary" @click.once="createMatch">Create Match Session</button>
|
|
</section>
|
|
<section class="section available-sessions">
|
|
<h2 class="title is-4">Available Sessions</h2>
|
|
<div class="block">
|
|
<div v-if="matchSessions.length === 0">
|
|
<p>No sessions available</p>
|
|
</div>
|
|
<div v-else class="grid is-col-min-12">
|
|
<div class="cell" v-for="session in matchSessions" :key="session.id">
|
|
<div class="card">
|
|
<div class="card-content">
|
|
<p class="title is-6">{{ session.name }}</p>
|
|
<p>ID: {{ session._id }}</p>
|
|
<p>Players: {{ session.players.length }}</p>
|
|
<p>
|
|
Seed: {{ session.seed }}
|
|
<button class="button is-small" @click="() => copy(session.seed)">Copy</button>
|
|
</p>
|
|
<p>Status: {{ session.status }}</p>
|
|
<div class="buttons is-centered mt-4"></div>
|
|
</div>
|
|
<div class="card-footer">
|
|
<p class="card-footer-item">
|
|
<a href="#" @click.once.prevent="() => joinMatch(session._id)"> Join </a>
|
|
</p>
|
|
<p class="card-footer-item">
|
|
<a href="#" @click.once.prevent="() => deleteMatch(session._id)"> Delete </a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss"></style>
|