|
|
|
@ -22,6 +22,15 @@ |
|
|
|
// End game confirmation dialog |
|
|
|
// End game confirmation dialog |
|
|
|
let showEndGameConfirm = $state(false); |
|
|
|
let showEndGameConfirm = $state(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Loading overlay when finishing game |
|
|
|
|
|
|
|
let isFinishing = $state(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function finishGame() { |
|
|
|
|
|
|
|
isFinishing = true; |
|
|
|
|
|
|
|
gameSession.clearSession(); |
|
|
|
|
|
|
|
await goto("/kuldvillak/edit"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function openProjector() { |
|
|
|
function openProjector() { |
|
|
|
gameSession.openProjector(); |
|
|
|
gameSession.openProjector(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -34,6 +43,7 @@ |
|
|
|
let wagerInput = $state(5); |
|
|
|
let wagerInput = $state(5); |
|
|
|
let scoreAdjustment = $state(10); |
|
|
|
let scoreAdjustment = $state(10); |
|
|
|
let introDelayComplete = $state(false); |
|
|
|
let introDelayComplete = $state(false); |
|
|
|
|
|
|
|
let introCountdown = $state(3); |
|
|
|
let prevIntroPhase = $state<string | null>(null); |
|
|
|
let prevIntroPhase = $state<string | null>(null); |
|
|
|
|
|
|
|
|
|
|
|
// Derived state |
|
|
|
// Derived state |
|
|
|
@ -46,13 +56,20 @@ |
|
|
|
phase === "intro-categories" && |
|
|
|
phase === "intro-categories" && |
|
|
|
prevIntroPhase !== "intro-categories" |
|
|
|
prevIntroPhase !== "intro-categories" |
|
|
|
) { |
|
|
|
) { |
|
|
|
// Just entered intro-categories, start 3s delay |
|
|
|
// Just entered intro-categories, start 3s countdown |
|
|
|
introDelayComplete = false; |
|
|
|
introDelayComplete = false; |
|
|
|
setTimeout(() => { |
|
|
|
introCountdown = 3; |
|
|
|
|
|
|
|
const interval = setInterval(() => { |
|
|
|
|
|
|
|
introCountdown--; |
|
|
|
|
|
|
|
if (introCountdown <= 0) { |
|
|
|
|
|
|
|
clearInterval(interval); |
|
|
|
introDelayComplete = true; |
|
|
|
introDelayComplete = true; |
|
|
|
}, 3000); |
|
|
|
} |
|
|
|
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
return () => clearInterval(interval); |
|
|
|
} else if (phase !== "intro-categories") { |
|
|
|
} else if (phase !== "intro-categories") { |
|
|
|
introDelayComplete = false; |
|
|
|
introDelayComplete = false; |
|
|
|
|
|
|
|
introCountdown = 3; |
|
|
|
} |
|
|
|
} |
|
|
|
prevIntroPhase = phase ?? null; |
|
|
|
prevIntroPhase = phase ?? null; |
|
|
|
}); |
|
|
|
}); |
|
|
|
@ -322,7 +339,7 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{:else if session.phase === "intro-categories"} |
|
|
|
{:else if session.phase === "intro-categories"} |
|
|
|
{#if !introDelayComplete && session.introCategoryIndex === 0} |
|
|
|
{#if !introDelayComplete && session.introCategoryIndex === 0} |
|
|
|
<!-- Initial 3s delay - show Villak/Topeltvillak --> |
|
|
|
<!-- Initial 3s delay - show Villak/Topeltvillak with countdown --> |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="font-kv-body text-4xl md:text-6xl text-kv-yellow uppercase kv-shadow-text" |
|
|
|
class="font-kv-body text-4xl md:text-6xl text-kv-yellow uppercase kv-shadow-text" |
|
|
|
> |
|
|
|
> |
|
|
|
@ -330,6 +347,13 @@ |
|
|
|
? "Villak" |
|
|
|
? "Villak" |
|
|
|
: "Topeltvillak"} |
|
|
|
: "Topeltvillak"} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
|
|
|
|
<span |
|
|
|
|
|
|
|
class="font-kv-body text-lg md:text-xl text-kv-white uppercase kv-shadow-text" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
{m.kv_play_introducing_categories({ |
|
|
|
|
|
|
|
seconds: introCountdown, |
|
|
|
|
|
|
|
})} |
|
|
|
|
|
|
|
</span> |
|
|
|
{:else if currentRound?.categories[session.introCategoryIndex]} |
|
|
|
{:else if currentRound?.categories[session.introCategoryIndex]} |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="font-kv-body text-4xl md:text-6xl text-kv-white uppercase kv-shadow-text" |
|
|
|
class="font-kv-body text-4xl md:text-6xl text-kv-white uppercase kv-shadow-text" |
|
|
|
@ -855,23 +879,12 @@ |
|
|
|
> |
|
|
|
> |
|
|
|
{m.kv_play_game_over()}! |
|
|
|
{m.kv_play_game_over()}! |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
<KvButtonPrimary |
|
|
|
<KvButtonPrimary onclick={finishGame} disabled={isFinishing}> |
|
|
|
onclick={() => { |
|
|
|
|
|
|
|
gameSession.clearSession(); |
|
|
|
|
|
|
|
goto("/kuldvillak/edit"); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
{m.kv_play_finish()} |
|
|
|
{m.kv_play_finish()} |
|
|
|
</KvButtonPrimary> |
|
|
|
</KvButtonPrimary> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{/if} |
|
|
|
{/if} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{:else} |
|
|
|
|
|
|
|
<div class="min-h-screen bg-kv-black flex items-center justify-center"> |
|
|
|
|
|
|
|
<span class="font-kv-body text-2xl text-kv-white uppercase"> |
|
|
|
|
|
|
|
{m.kv_play_loading()} |
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
{/if} |
|
|
|
{/if} |
|
|
|
|
|
|
|
|
|
|
|
<!-- Settings Modal --> |
|
|
|
<!-- Settings Modal --> |
|
|
|
@ -885,3 +898,14 @@ |
|
|
|
confirmText={m.kv_play_end_game()} |
|
|
|
confirmText={m.kv_play_end_game()} |
|
|
|
onconfirm={() => gameSession.endGame()} |
|
|
|
onconfirm={() => gameSession.endGame()} |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Loading overlay when finishing game --> |
|
|
|
|
|
|
|
{#if isFinishing} |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
class="fixed inset-0 bg-kv-black/90 flex flex-col items-center justify-center z-50 gap-4" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
class="w-16 h-16 border-4 border-kv-yellow border-t-transparent rounded-full animate-spin" |
|
|
|
|
|
|
|
></div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
{/if} |
|
|
|
|