adding tauri
This commit is contained in:
		@@ -1,23 +1,23 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { inject, onMounted, onUnmounted, ref } from 'vue'
 | 
			
		||||
import { computed, 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 type { MatchSessionOptions, MatchSessionDto } from '@/common/interfaces'
 | 
			
		||||
import { useEventBusStore } from '@/stores/eventBus'
 | 
			
		||||
import { useAuthStore } from '@/stores/auth'
 | 
			
		||||
import { copyToclipboard } from '@/common/helpers'
 | 
			
		||||
import { useGameOptionsStore } from '@/stores/gameOptions'
 | 
			
		||||
import MatchConfiguration from '@/components/MatchConfiguration.vue'
 | 
			
		||||
import { useI18n } from 'vue-i18n'
 | 
			
		||||
 | 
			
		||||
let teamedWith = ref<string | undefined>(undefined)
 | 
			
		||||
 | 
			
		||||
let background = ref<string>('green')
 | 
			
		||||
let teamed = ref<boolean>(false)
 | 
			
		||||
let pointsToWin = ref<number>(100)
 | 
			
		||||
let seed = ref<string>('')
 | 
			
		||||
let sessionName = ref(`Test #${Date.now()}`)
 | 
			
		||||
let matchSessions = ref<MatchSessionDto[]>([])
 | 
			
		||||
let dataInterval: any
 | 
			
		||||
let loadingSessions = ref<boolean>(false)
 | 
			
		||||
 | 
			
		||||
const router = useRouter()
 | 
			
		||||
const gameStore = useGameStore()
 | 
			
		||||
@@ -33,36 +33,18 @@ const { sessionState, isSessionStarted, playerState, amIHost, readyForStart } =
 | 
			
		||||
const { user } = storeToRefs(auth)
 | 
			
		||||
const { gameOptions } = storeToRefs(gameOptionsStore)
 | 
			
		||||
const { updateSessionState, updatePlayerState, updateGameState } = gameStore
 | 
			
		||||
 | 
			
		||||
// 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 { t } = useI18n()
 | 
			
		||||
 | 
			
		||||
const eventBus = useEventBusStore()
 | 
			
		||||
eventBus.subscribe('window-before-unload', () => {
 | 
			
		||||
  logger.debug('Window before unload')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
async function createMatch() {
 | 
			
		||||
async function createMatch(options: MatchSessionOptions) {
 | 
			
		||||
  logger.debug('Creating match')
 | 
			
		||||
  await socketService.connect()
 | 
			
		||||
  gameOptions.value = { background: background.value }
 | 
			
		||||
  const sessionOptions = {
 | 
			
		||||
    pointsToWin: pointsToWin.value,
 | 
			
		||||
  }
 | 
			
		||||
  const id = await gameService.createMatchSession(sessionName.value, seed.value, sessionOptions)
 | 
			
		||||
  gameOptions.value = options
 | 
			
		||||
  await gameService.createMatchSession(options)
 | 
			
		||||
  logger.debug('Match created successfully')
 | 
			
		||||
  // router.push({ name: 'match', params: { id } })
 | 
			
		||||
}
 | 
			
		||||
@@ -90,6 +72,7 @@ async function startMatch() {
 | 
			
		||||
    await socketService.sendMessageWithAck('client:start-session', {
 | 
			
		||||
      sessionId: sessionId,
 | 
			
		||||
      playerId: playerId,
 | 
			
		||||
      teamedWith: teamedWith.value,
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -97,13 +80,16 @@ async function startMatch() {
 | 
			
		||||
async function cancelMatch() {
 | 
			
		||||
  logger.debug('Cancelling match')
 | 
			
		||||
  if (sessionState?.value?.id) {
 | 
			
		||||
    await gameService.cancelMatchSession(sessionState?.value?.id)
 | 
			
		||||
    if (amIHost.value) {
 | 
			
		||||
      await gameService.cancelMatchSession(sessionState?.value?.id)
 | 
			
		||||
    } else {
 | 
			
		||||
      //TODO: await gameService.leaveMatchSession(sessionState?.value?.id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateSessionState(undefined)
 | 
			
		||||
    updatePlayerState(undefined)
 | 
			
		||||
    updateGameState(undefined)
 | 
			
		||||
 | 
			
		||||
    logger.debug('Match cancelled successfully')
 | 
			
		||||
    router.push({ name: 'home' })
 | 
			
		||||
    teamedWith.value = undefined
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -127,14 +113,28 @@ async function deleteMatch(id: string) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const playersToTeamUpWith = computed(() => {
 | 
			
		||||
  return (
 | 
			
		||||
    sessionState?.value?.players.filter((player) => player.id !== sessionState?.value?.creator) ||
 | 
			
		||||
    []
 | 
			
		||||
  )
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const canStart = computed(() => {
 | 
			
		||||
  const players = sessionState?.value?.players || []
 | 
			
		||||
  const options = gameOptions.value
 | 
			
		||||
  const allReady = (players.length || 0) > 0 && players.every((player) => player.ready)
 | 
			
		||||
  return (!options?.teamed && allReady) || (options?.teamed && !!teamedWith.value && allReady)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
async function loadData() {
 | 
			
		||||
  const listResponse = await gameService.listMatchSessions()
 | 
			
		||||
  matchSessions.value = listResponse.data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  loadData()
 | 
			
		||||
  dataInterval = setInterval(loadData, 5000)
 | 
			
		||||
  // loadData()
 | 
			
		||||
  // dataInterval = setInterval(loadData, 5000)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
@@ -142,9 +142,34 @@ onUnmounted(() => {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function copy(sessionSeed: string) {
 | 
			
		||||
  seed.value = sessionSeed
 | 
			
		||||
  copyToclipboard(sessionSeed)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let tabs = ref<any[]>([
 | 
			
		||||
  { label: t('create-session'), id: 'create-tab', active: true, disabled: false },
 | 
			
		||||
  { label: t('join-a-multiplayer-session'), id: 'join-tab', active: false, disabled: false },
 | 
			
		||||
  { label: t('tournaments'), id: 'torunaments-tab', active: false, disabled: true },
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
const selectedTab = computed(() => tabs.value.find((t) => t.active)?.id)
 | 
			
		||||
const isCreateTab = computed(() => selectedTab.value === 'create-tab')
 | 
			
		||||
const isJoinTab = computed(() => selectedTab.value === 'join-tab')
 | 
			
		||||
const isTournamentTab = computed(() => selectedTab.value === 'torunaments-tab')
 | 
			
		||||
async function tabClick(tab: any) {
 | 
			
		||||
  tabs.value.forEach((t) => (t.active = t === tab))
 | 
			
		||||
  if (tab.id === 'join-tab') {
 | 
			
		||||
    loadingSessions.value = true
 | 
			
		||||
    await loadData()
 | 
			
		||||
    dataInterval = setInterval(loadData, 5000)
 | 
			
		||||
  } else {
 | 
			
		||||
    clearInterval(dataInterval)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onCreateMatch(options: MatchSessionOptions) {
 | 
			
		||||
  console.log('Creating match', options)
 | 
			
		||||
  createMatch(options)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
@@ -153,139 +178,110 @@ function copy(sessionSeed: string) {
 | 
			
		||||
      <h1 class="title is-2">
 | 
			
		||||
        {{ $t('welcome-to-the-user-username-s-home-page', [user.username]) }}
 | 
			
		||||
      </h1>
 | 
			
		||||
      <!-- Tabs -->
 | 
			
		||||
      <div class="block" v-if="!isSessionStarted">
 | 
			
		||||
        <div class="field">
 | 
			
		||||
          <label class="label">{{ $t('session-name') }}</label>
 | 
			
		||||
          <div class="control">
 | 
			
		||||
            <input
 | 
			
		||||
              type="text"
 | 
			
		||||
              class="input"
 | 
			
		||||
              v-model="sessionName"
 | 
			
		||||
              placeholder="$t('session-name-placeholder')"
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
        <div class="tabs is-centered">
 | 
			
		||||
          <ul>
 | 
			
		||||
            <li
 | 
			
		||||
              v-bind:key="tab.label"
 | 
			
		||||
              v-for="tab in tabs"
 | 
			
		||||
              :class="{ 'is-active': tab.active, 'is-disabled': tab.disabled }"
 | 
			
		||||
            >
 | 
			
		||||
              <a @click="() => tabClick(tab)">{{ tab.label }}</a>
 | 
			
		||||
            </li>
 | 
			
		||||
          </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="field">
 | 
			
		||||
          <label class="label">{{ $t('seed') }}</label>
 | 
			
		||||
          <div class="control">
 | 
			
		||||
            <input
 | 
			
		||||
              type="text"
 | 
			
		||||
              class="input"
 | 
			
		||||
              style="margin-bottom: 0"
 | 
			
		||||
              v-model="seed"
 | 
			
		||||
              :placeholder="$t('seed-placeholder')"
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="grid">
 | 
			
		||||
          <div class="cell">
 | 
			
		||||
            <div class="field">
 | 
			
		||||
              <label for="background" class="label">{{ $t('background-color') }}</label>
 | 
			
		||||
              <div class="control">
 | 
			
		||||
                <div class="select">
 | 
			
		||||
                  <select v-model="background" name="background">
 | 
			
		||||
                    <option value="green">{{ $t('green-fabric') }}</option>
 | 
			
		||||
                    <option value="gray">{{ $t('gray-fabric') }}</option>
 | 
			
		||||
                    <option value="blue">{{ $t('blue-fabric') }}</option>
 | 
			
		||||
                    <option value="yellow">{{ $t('yellow-fabric') }}</option>
 | 
			
		||||
                    <option value="red">{{ $t('red-fabric') }}</option>
 | 
			
		||||
                  </select>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
        <!-- Tabs End -->
 | 
			
		||||
        <!-- Match Configuration -->
 | 
			
		||||
        <section class="section" v-if="isCreateTab">
 | 
			
		||||
          <MatchConfiguration @create-match="onCreateMatch" />
 | 
			
		||||
        </section>
 | 
			
		||||
        <!-- Match Configuration End -->
 | 
			
		||||
        <!-- Join a Multiplayer Session -->
 | 
			
		||||
        <section class="section available-sessions" v-if="isJoinTab">
 | 
			
		||||
          <div class="block">
 | 
			
		||||
            <div v-if="matchSessions.length === 0">
 | 
			
		||||
              <p>{{ $t('no-sessions-available') }}</p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="field">
 | 
			
		||||
              <div class="control">
 | 
			
		||||
                <label for="teamed" class="checkbox">
 | 
			
		||||
                  <input v-model="teamed" name="teamed" type="checkbox" />
 | 
			
		||||
                  {{ $t('crossed-game-teamed', [teamed]) }}
 | 
			
		||||
                </label>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="cell">
 | 
			
		||||
            <div class="field">
 | 
			
		||||
              <label for="pointsToWin" class="label">{{ $t('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 class="buttons">
 | 
			
		||||
          <button class="button is-primary" @click.once="createMatch">
 | 
			
		||||
            {{ $t('create-match-session') }}
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="block" v-if="isSessionStarted">
 | 
			
		||||
        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
			
		||||
        <h6 class="title is-size-5">Players</h6>
 | 
			
		||||
        <div v-for="player in sessionState?.players" :key="player.id">
 | 
			
		||||
          <p>{{ player.name }}</p>
 | 
			
		||||
          <p>{{ player.ready ? 'Ready' : 'Not ready' }}</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="buttons mt-6">
 | 
			
		||||
          <button class="button" @click="setPlayerReady">
 | 
			
		||||
            <span v-if="!readyForStart">{{ $t('ready') }}</span
 | 
			
		||||
            ><span v-else>{{ $t('unready') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button class="button" @click="startMatch" v-if="amIHost && readyForStart">
 | 
			
		||||
            <span>{{ $t('start') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
 | 
			
		||||
          <button class="button" @click="cancelMatch">
 | 
			
		||||
            <span>{{ $t('cancel') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
    <section class="section available-sessions" v-if="!isSessionStarted">
 | 
			
		||||
      <h2 class="title is-4">{{ $t('available-sessions') }}</h2>
 | 
			
		||||
      <div class="block">
 | 
			
		||||
        <div v-if="matchSessions.length === 0">
 | 
			
		||||
          <p>{{ $t('no-sessions-available') }}</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div v-else class="fixed-grid has-3-cols">
 | 
			
		||||
          <div class="grid">
 | 
			
		||||
            <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>{{ $t('id-session-_id', [session._id]) }}</p>
 | 
			
		||||
                  <p>{{ $t('players-session-players-length', [session.players.length]) }}</p>
 | 
			
		||||
                  <p>
 | 
			
		||||
                    {{ $t('seed-session-seed', [session.seed]) }}
 | 
			
		||||
                    <button class="button is-small is-ghost" @click="() => copy(session.seed)">
 | 
			
		||||
                      {{ $t('copy') }}
 | 
			
		||||
                    </button>
 | 
			
		||||
                  </p>
 | 
			
		||||
                  <p>{{ $t('status-session-status', [session.status]) }}</p>
 | 
			
		||||
                  <div class="buttons is-centered mt-6">
 | 
			
		||||
                    <button
 | 
			
		||||
                      class="button is-primary"
 | 
			
		||||
                      @click.once.prevent="() => joinMatch(session._id)"
 | 
			
		||||
                    >
 | 
			
		||||
                      <span>{{ $t('join') }}</span>
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <button
 | 
			
		||||
                      class="button is-text"
 | 
			
		||||
                      @click.once.prevent="() => deleteMatch(session._id)"
 | 
			
		||||
                    >
 | 
			
		||||
                      <span>{{ $t('delete') }}</span>
 | 
			
		||||
                    </button>
 | 
			
		||||
            <div v-else class="fixed-grid has-3-cols">
 | 
			
		||||
              <div class="grid">
 | 
			
		||||
                <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>{{ $t('id-session-_id', [session._id]) }}</p>
 | 
			
		||||
                      <p>{{ $t('players-session-players-length', [session.players.length]) }}</p>
 | 
			
		||||
                      <p>
 | 
			
		||||
                        {{ $t('seed-session-seed', [session.seed]) }}
 | 
			
		||||
                        <button class="button is-small is-ghost" @click="() => copy(session.seed)">
 | 
			
		||||
                          {{ $t('copy') }}
 | 
			
		||||
                        </button>
 | 
			
		||||
                      </p>
 | 
			
		||||
                      <p>{{ $t('status-session-status', [session.status]) }}</p>
 | 
			
		||||
                      <div class="buttons is-centered mt-6">
 | 
			
		||||
                        <button
 | 
			
		||||
                          class="button is-primary"
 | 
			
		||||
                          @click.once.prevent="() => joinMatch(session._id)"
 | 
			
		||||
                        >
 | 
			
		||||
                          <span>{{ $t('join') }}</span>
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button
 | 
			
		||||
                          class="button is-text"
 | 
			
		||||
                          @click.once.prevent="() => deleteMatch(session._id)"
 | 
			
		||||
                        >
 | 
			
		||||
                          <span>{{ $t('delete') }}</span>
 | 
			
		||||
                        </button>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </section>
 | 
			
		||||
        <!-- Join a Multiplayer Session End -->
 | 
			
		||||
        <!-- Tournaments -->
 | 
			
		||||
        <section class="section" v-if="isTournamentTab"></section>
 | 
			
		||||
        <!-- Tournaments End -->
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="block" v-if="isSessionStarted">
 | 
			
		||||
        <h2 class="title is-4">{{ sessionState?.name }}</h2>
 | 
			
		||||
        <h6 class="title is-size-5">Players</h6>
 | 
			
		||||
        <div v-for="player in sessionState?.players" :key="player.id">
 | 
			
		||||
          <p>{{ player.name }} ({{ player.ready ? 'Ready' : 'Not ready' }})</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="mt-4" v-if="amIHost && gameOptions?.teamed && playersToTeamUpWith.length > 0">
 | 
			
		||||
          <div class="field">
 | 
			
		||||
            <label for="background" class="label">Team up with</label>
 | 
			
		||||
            <div class="control">
 | 
			
		||||
              <div class="select">
 | 
			
		||||
                <select v-model="teamedWith" name="teamedWidth">
 | 
			
		||||
                  <option v-for="player in playersToTeamUpWith" :key="player.id" :value="player.id">
 | 
			
		||||
                    {{ player.name }}
 | 
			
		||||
                  </option>
 | 
			
		||||
                </select>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="buttons mt-6">
 | 
			
		||||
          <button class="button is-dark" @click="setPlayerReady">
 | 
			
		||||
            <span v-if="!readyForStart">{{ $t('ready') }}</span
 | 
			
		||||
            ><span v-else>{{ $t('unready') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button
 | 
			
		||||
            class="button is-success"
 | 
			
		||||
            :disabled="!canStart"
 | 
			
		||||
            @click="startMatch"
 | 
			
		||||
            v-if="amIHost"
 | 
			
		||||
          >
 | 
			
		||||
            <span>{{ $t('start') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
 | 
			
		||||
          <button class="button is-danger" @click="cancelMatch">
 | 
			
		||||
            <span>{{ $t('cancel') }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
 
 | 
			
		||||
@@ -39,9 +39,13 @@ onBeforeMount(() => {
 | 
			
		||||
        <span class="title is-5">{{ $t('winner') }}</span>
 | 
			
		||||
        <span class="is-size-5 ml-4">{{ matchSession?.matchWinner?.name }}</span>
 | 
			
		||||
      </p>
 | 
			
		||||
      <p class="mb-4">
 | 
			
		||||
        <span class="title is-5">{{ $t('win-type') }}</span>
 | 
			
		||||
        <span class="is-size-5 ml-4">{{ matchSession?.options.winType }}</span>
 | 
			
		||||
      </p>
 | 
			
		||||
      <p class="mb-4">
 | 
			
		||||
        <span class="title is-5">{{ $t('points-to-win') }}</span>
 | 
			
		||||
        <span class="is-size-5 ml-4">{{ matchSession?.pointsToWin }}</span>
 | 
			
		||||
        <span class="is-size-5 ml-4">{{ matchSession?.options.winTarget }}</span>
 | 
			
		||||
      </p>
 | 
			
		||||
      <h3 class="title is-5">{{ $t('final-scoreboard') }}</h3>
 | 
			
		||||
      <div v-bind:key="$index" v-for="(score, $index) in matchSession?.scoreboard">
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user