frontend/src/views/Game.vue

145 lines
3.8 KiB
Vue

<template>
<div id="game">
<h1>
Room: {{ this.$route.params.code }}
</h1>
<h2>Your name is: {{ this.name }}</h2>
<ul>
<li v-for="player in this.room.players">{{ player.name }}: {{player.points}}</li>
</ul>
<button v-if="this.game.owner && !this.room.started" @click="this.start_game">Stort</button>
<card-component v-if="this.room.started" :text="this.card.text" :isBlack="true" />
<ul v-show="this.card && !this.czar()">
<li v-for="blank in this.card.pick">
Card {{blank}}:
<input type="text" v-model="inputs[blank - 1]" :disabled="input_blocked" />
</li>
<li v-show="!input_blocked && room.started">
<button @click="this.send_answers">Submit Answers</button>
</li>
</ul>
<div class="cards">
<stacked-cards
class="card"
v-for="ans in this.answers"
:key="ans.index"
:text="ans.text"
:showhover="czar()"
v-on:clicked="pick(ans)"
/>
</div>
<qrcode-vue v-if="!this.room.started" :value="gameURL" :size="300"></qrcode-vue>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { Game, axios_api, fullURL } from "../util/api";
import { Message, MessageType } from "../models/Message";
import { Room } from "../models/Room";
import { Card } from "../models/Card";
import { Answer } from "../models/Answer";
import CardComponent from "../components/CardComponent.vue";
import StackedCards from "../components/StackedCards.vue";
import QrcodeVue from "qrcode.vue";
@Component({
components: { CardComponent, StackedCards, QrcodeVue },
})
export default class GameVueView extends Vue {
private game: Game = new Game("", "", () => {console.error("OwO we did an oopsie woopsie"); });
private room: Room = new Room("");
private card: Card = new Card("", 0, "", "");
private inputs: string[] = [];
private input_blocked: boolean = false;
private answers: Answer[] = [];
private name: string = "";
private gameURL: string = "";
/**
* Lifecycle hooks
*/
private async mounted() {
this.gameURL = `${fullURL}/?code=${this.$route.params.code}`;
this.name = (this.$route.query.name || prompt("What is your nickname?")) as string;
if (this.name && this.$route.params.code.length > 3) {
this.name = this.name as string;
const room = await axios_api.get(`/room/${this.$route.params.code}`);
if (room.status === 200) {
this.game = new Game(
this.$route.params.code,
this.name,
this.on_message,
);
}
}
}
private start_game() {
this.game.start_game();
}
private send_answers() {
this.input_blocked = true;
this.game.send_answer(this.inputs);
}
private czar(): boolean {
return this.game.you === this.room.czar;
}
private pick(ans: Answer) {
if (this.czar()) {
this.game.pick_answer(ans);
}
}
private async on_message(message: Message) {
switch (message.msgtype) {
case MessageType.JOIN:
break;
case MessageType.START:
this.answers = [];
this.inputs = [];
this.input_blocked = false;
this.card = message.data.card as Card;
break;
case MessageType.ROOM:
this.room = message.data as Room;
break;
case MessageType.ANSWER:
this.answers = message.data as Answer[];
break;
case MessageType.PICK:
alert(message.data.text);
break;
}
}
}
</script>
<style lang="scss">
#game {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.cards {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.card {
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
}
</style>