feat: add game controls for gamemaster
This commit is contained in:
parent
4b81042955
commit
ec9a1ef35e
@ -31,7 +31,8 @@ $button-hover-border: 4px solid #00a0c0;
|
|||||||
|
|
||||||
$button-disabled-background-color: #006080;
|
$button-disabled-background-color: #006080;
|
||||||
$button-disabled-text-color: #102028;
|
$button-disabled-text-color: #102028;
|
||||||
$button-disabled-border: 4px solid #004060;
|
$button-disabled-border: 4px solid transparent;
|
||||||
|
$button-disabled-border-border: 4px solid #004060;
|
||||||
|
|
||||||
// Topbar
|
// Topbar
|
||||||
$topbar-background-color: #006898;
|
$topbar-background-color: #006898;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<button :type="type" class="button__button" :class="{ disabled, border }">
|
<button :type="type" class="button__button"
|
||||||
|
:class="{ 'button__button__disabled': disabled, 'button__button__border': border }">
|
||||||
<slot />
|
<slot />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
@ -35,13 +36,14 @@ defineProps({
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
border: none;
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $text-secondary-hover-color;
|
color: $text-secondary-hover-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.border {
|
&__border {
|
||||||
background-color: $button-background-color;
|
background-color: $button-background-color;
|
||||||
color: $button-text-color;
|
color: $button-text-color;
|
||||||
border: $button-border;
|
border: $button-border;
|
||||||
@ -54,13 +56,20 @@ defineProps({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled,
|
&__disabled,
|
||||||
&:hover.disabled {
|
&__disabled:hover {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
background-color: $button-disabled-background-color;
|
background-color: $button-disabled-background-color;
|
||||||
border: $button-disabled-border;
|
// border: $button-disabled-border;
|
||||||
|
margin: 4px;
|
||||||
color: $button-disabled-text-color;
|
color: $button-disabled-text-color;
|
||||||
|
|
||||||
|
&.button__button__border {
|
||||||
|
margin: 0;
|
||||||
|
border: $button-disabled-border-border;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
46
client/src/components/GameControls.vue
Normal file
46
client/src/components/GameControls.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="game-controls__container">
|
||||||
|
<Button class="game-controls__control" :border="!disabled.collect" :disabled="disabled.collect" @click="collect">Collect Quotes</Button>
|
||||||
|
<Button class="game-controls__control" :border="!disabled.start" :disabled="disabled.start" @click="start">Start</Button>
|
||||||
|
<Button class="game-controls__control" :border="!disabled.cont" :disabled="disabled.cont" @click="cont">Continue</Button>
|
||||||
|
<Button class="game-controls__control" :border="!disabled.idle" :disabled="disabled.idle" @click="idle">Idle</Button>
|
||||||
|
<Button class="game-controls__control" :border="!disabled.finish" :disabled="disabled.finish" @click="finish">Finish</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import useEngine from '@/composables/useEngine'
|
||||||
|
import { useGameinfoStore } from "@/stores/GameinfoStore"
|
||||||
|
|
||||||
|
const game = useGameinfoStore()
|
||||||
|
const engine = useEngine()
|
||||||
|
const disabled = computed(() => {
|
||||||
|
return {
|
||||||
|
collect: game.state !== 'idle',
|
||||||
|
start: game.state !== 'idle',
|
||||||
|
cont: game.state !== 'play' && ['select-quote', 'reveal-show-count', 'reveal-source'].indexOf(game.phase) == -1,
|
||||||
|
idle: game.state === 'idle',
|
||||||
|
finish: ['play', 'idle'].indexOf(game.state) == -1,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const collect = async () => await engine.collectQuotes()
|
||||||
|
const start = async () => await engine.startGame()
|
||||||
|
const cont = async () => await engine.continueGame()
|
||||||
|
const idle = async () => await engine.resetGame()
|
||||||
|
const finish = async () => await engine.finishGame()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.game-controls {
|
||||||
|
&__container {
|
||||||
|
display: flex;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__control {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -9,7 +9,7 @@
|
|||||||
Admin
|
Admin
|
||||||
</div>
|
</div>
|
||||||
<div v-if="user.isGamemaster" class="topbar__actionbar__gamemaster">
|
<div v-if="user.isGamemaster" class="topbar__actionbar__gamemaster">
|
||||||
Collect Quotes | Start | Continue | Idle | Finish
|
<GameControls />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="topbar__actionbar__player">
|
<div v-else class="topbar__actionbar__player">
|
||||||
{{ game.name }}
|
{{ game.name }}
|
||||||
|
36
client/src/composables/engine/game.ts
Normal file
36
client/src/composables/engine/game.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { useUserinfoStore } from "@/stores/UserinfoStore"
|
||||||
|
|
||||||
|
export async function collectQuotes(): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/collectQuotes', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function startGame(): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/startGame', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function continueGame(): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/continueGame', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resetGame(): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/resetGame', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function finishGame(): Promise<void> {
|
||||||
|
const userInfoStore = useUserinfoStore()
|
||||||
|
await this.callApi('/api/finishGame', {
|
||||||
|
g: userInfoStore.gameId,
|
||||||
|
})
|
||||||
|
}
|
@ -3,6 +3,7 @@ import { callApi, QueryParams } from '@/composables/engine/callApi'
|
|||||||
import { start, stop } from '@/composables/engine/startStop'
|
import { start, stop } from '@/composables/engine/startStop'
|
||||||
import { fetchUpdate } from '@/composables/engine/fetchUpdate'
|
import { fetchUpdate } from '@/composables/engine/fetchUpdate'
|
||||||
import { loadQuotes, getQuotesRef, deleteQuote, saveQuote } from '@/composables/engine/quotes'
|
import { loadQuotes, getQuotesRef, deleteQuote, saveQuote } from '@/composables/engine/quotes'
|
||||||
|
import { collectQuotes, startGame, continueGame, resetGame, finishGame } from '@/composables/engine/game'
|
||||||
import type { Quotes } from '@/composables/engine.d'
|
import type { Quotes } from '@/composables/engine.d'
|
||||||
|
|
||||||
interface EngineContext {
|
interface EngineContext {
|
||||||
@ -28,6 +29,11 @@ export interface useEngine {
|
|||||||
createQuote(quote: string): Promise<void>
|
createQuote(quote: string): Promise<void>
|
||||||
saveQuote(id: string, quote: string): Promise<void>
|
saveQuote(id: string, quote: string): Promise<void>
|
||||||
deleteQuote(id: string): Promise<void>
|
deleteQuote(id: string): Promise<void>
|
||||||
|
collectQuotes: () => Promise<void>
|
||||||
|
startGame: () => Promise<void>
|
||||||
|
continueGame: () => Promise<void>
|
||||||
|
resetGame: () => Promise<void>
|
||||||
|
finishGame: () => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (): useEngine => {
|
export default (): useEngine => {
|
||||||
@ -55,5 +61,10 @@ export default (): useEngine => {
|
|||||||
createQuote: (quote: string) => saveQuote.apply(context, [':new:', quote]),
|
createQuote: (quote: string) => saveQuote.apply(context, [':new:', quote]),
|
||||||
saveQuote: (id: string, quote: string) => saveQuote.apply(context, [id, quote]),
|
saveQuote: (id: string, quote: string) => saveQuote.apply(context, [id, quote]),
|
||||||
deleteQuote: (id) => deleteQuote.apply(context, [id]),
|
deleteQuote: (id) => deleteQuote.apply(context, [id]),
|
||||||
|
collectQuotes: () => collectQuotes.apply(context),
|
||||||
|
startGame: () => startGame.apply(context),
|
||||||
|
continueGame: () => continueGame.apply(context),
|
||||||
|
resetGame: () => resetGame.apply(context),
|
||||||
|
finishGame: () => finishGame.apply(context),
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user