feat(ui): FRO-34 Lobby (#21)
Started with Lobby Component Co-authored-by: LQ63 <lkhermann@web.de> Co-authored-by: Janis <janis-e@gmx.de> Reviewed-on: #21 Reviewed-by: Janis <janis-e@gmx.de> Co-authored-by: lq64 <lq@blackhole.local> Co-committed-by: lq64 <lq@blackhole.local>
This commit is contained in:
@@ -1,42 +1,40 @@
|
||||
<script lang="ts" setup>
|
||||
import {toRefs} from 'vue'
|
||||
import type {Hand, Player} from "@/types/GameSubTypes.ts";
|
||||
import {useWebSocket} from "@/composables/useWebsocket.ts";
|
||||
import {useIngame} from "@/composables/useIngame.ts";
|
||||
import type {GameInfo} from "@/types/GameTypes.ts";
|
||||
import {useQuasar} from "quasar";
|
||||
import { ref } from 'vue';
|
||||
|
||||
const wb = useWebSocket()
|
||||
const wi = useIngame()
|
||||
const $q = useQuasar();
|
||||
|
||||
const props = defineProps<{
|
||||
hand: Hand
|
||||
isHandInactive?: boolean
|
||||
self: Player | null
|
||||
}>()
|
||||
const wiggleIdx = ref<number | null>(null)
|
||||
let wiggleTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const { hand, isHandInactive, self } = toRefs(props)
|
||||
function triggerWiggle(index: number) {
|
||||
// clear previous timer if any
|
||||
if (wiggleTimer) clearTimeout(wiggleTimer)
|
||||
wiggleIdx.value = index
|
||||
wiggleTimer = setTimeout(() => {
|
||||
wiggleIdx.value = null
|
||||
wiggleTimer = null
|
||||
}, 700)
|
||||
}
|
||||
|
||||
function handlePlayCard(element: any, index: number | null) {
|
||||
function handlePlayCard(index: number | null) {
|
||||
if (index === null) return
|
||||
if (isHandInactive?.value) return
|
||||
isHandInactive.value = true
|
||||
|
||||
const wiggleKeyframes = [
|
||||
{ transform: 'translateX(0)' },
|
||||
{ transform: 'translateX(-5px)' },
|
||||
{ transform: 'translateX(5px)' },
|
||||
{ transform: 'translateX(-5px)' },
|
||||
{ transform: 'translateX(0)' }
|
||||
];
|
||||
|
||||
const wiggleTiming = {
|
||||
duration: 400,
|
||||
iterations: 1,
|
||||
easing: 'ease-in-out',
|
||||
fill: 'forwards'
|
||||
};
|
||||
|
||||
wb.sendAndWait("PlayCard", { cardindex: index })
|
||||
.catch(() => {
|
||||
element.animate(wiggleKeyframes, wiggleTiming);
|
||||
isHandInactive.value = false;
|
||||
.catch((error) => {
|
||||
triggerWiggle(index)
|
||||
|
||||
$q.notify({
|
||||
message: error.message,
|
||||
color: "negative",
|
||||
position: "top"
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -52,16 +50,16 @@ function getCardImagePath(cardPath: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bottom-div hand-container">
|
||||
<div id="card-slide" :class="'ingame-cards-slide ' + (isHandInactive ? 'inactive' : '' )">
|
||||
<div class="hand-container">
|
||||
<div id="card-slide" class="ingame-cards-slide">
|
||||
<div class="cards-row">
|
||||
<div v-for="card in hand.cards" :key="card.identifier" class="handcard">
|
||||
<div class="card-btn" @click="handlePlayCard(this, card.idx)" aria-label="Play card">
|
||||
<q-img :src="getCardImagePath(card.path)" :alt="card.identifier" class="card" />
|
||||
<div v-for="card in (<GameInfo>wi.data)?.hand?.cards" :key="card.identifier" :class="['handcard', { wiggle: wiggleIdx === card.idx }]">
|
||||
<div class="card-btn" aria-label="Play card">
|
||||
<q-img :src="getCardImagePath(card.path)" v-on:click="handlePlayCard(card.idx)" :alt="card.identifier" class="card" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="self?.dogLife" class="dog-actions">
|
||||
<div v-if="(<GameInfo>wi.data)?.self?.dogLife" class="dog-actions">
|
||||
<q-btn color="negative" label="Skip Turn" @click="handleSkipDogLife" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,6 +117,18 @@ function getCardImagePath(cardPath: string) {
|
||||
width:120px;
|
||||
border-radius:6px
|
||||
}
|
||||
.wiggle {
|
||||
animation: wiggle 700ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes wiggle {
|
||||
0% { transform: translateY(0) rotate(0deg); }
|
||||
15% { transform: translateY(-8px) rotate(-6deg); }
|
||||
35% { transform: translateY(0) rotate(6deg); }
|
||||
55% { transform: translateY(-4px) rotate(-3deg); }
|
||||
75% { transform: translateY(0) rotate(2deg); }
|
||||
100% { transform: translateY(0) rotate(0deg); }
|
||||
}
|
||||
|
||||
@media (max-height: 500px) {
|
||||
.card {
|
||||
|
||||
Reference in New Issue
Block a user