Added a nice look to the endscreen. Implemented a ranking method inside GameLobby to get an order. Co-authored-by: LQ63 <lkhermann@web.de> Reviewed-on: #97 Reviewed-by: Janis <janis-e@gmx.de> Co-authored-by: lq64 <lq@blackhole.local> Co-committed-by: lq64 <lq@blackhole.local>
108 lines
4.9 KiB
HTML
108 lines
4.9 KiB
HTML
@(user: Option[model.users.User], gamelobby: logic.game.GameLobby)
|
|
|
|
<div class="lobby-background vh-100 d-flex align-items-start justify-content-center pt-5">
|
|
<div class="container py-5">
|
|
<div class="row justify-content-center">
|
|
<div class="col-lg-8 col-xl-6">
|
|
<div class="card shadow-lg mb-5 text-center bg-white border-0 rounded-4">
|
|
<div class="card-body p-4 p-md-5">
|
|
<h1 class="card-title display-5 fw-bold text-success mb-3">Match Over!</h1>
|
|
<p class="fs-4 text-muted">Congratulations to the winner:</p>
|
|
<h2 class="display-3 fw-bolder mb-4 text-primary">
|
|
@gamelobby.getLogic.getWinner.get.name
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow mb-5 border-0 rounded-4 overflow-hidden">
|
|
<div class="card-header bg-dark text-white text-center fs-5 fw-semibold">
|
|
Final Standings
|
|
</div>
|
|
<div class="d-flex justify-content-between align-items-center p-2 text-uppercase fw-bold border-bottom bg-light">
|
|
<div class="d-flex align-items-center">
|
|
Player
|
|
</div>
|
|
<div class="d-flex flex-row gap-3">
|
|
<span class="fs-6 text-dark text-center" style="width: 5rem;">Rounds won</span>
|
|
<span class="fs-6 text-dark text-center" style="width: 5rem;">Tricks won</span>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
@gamelobby.getFinalRanking.zipWithIndex.map { case ((playerName, (wonRounds, tricksWon)), index) =>
|
|
@defining(index + 1) { rank =>
|
|
<div class="d-flex justify-content-between align-items-center p-3 border-bottom @if(rank == 1){bg-success-subtle fw-bold}">
|
|
<div class="d-flex align-items-center">
|
|
<span class="badge @if(rank == 1){bg-warning text-dark fs-6} else {bg-secondary} rounded-pill me-3">#@rank</span>
|
|
@playerName
|
|
</div>
|
|
<div class="d-flex flex-row gap-3">
|
|
<span class="fs-6 text-muted text-center" style="width: 5rem;">@wonRounds</span>
|
|
<span class="fs-6 text-muted text-center" style="width: 5rem;">@tricksWon</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
@if(gamelobby.getFinalRanking.isEmpty) {
|
|
<div class="p-3 text-center text-muted">No final scores available.</div>
|
|
}
|
|
</div>
|
|
|
|
|
|
@if(user.isDefined && gamelobby.getUserSession(user.get.id).host) {
|
|
<div class="col-12 text-center mt-4">
|
|
<div class="btn btn-success btn-lg shadow" onclick="handleReturnToLobby()">
|
|
Return to Lobby
|
|
</div>
|
|
</div>
|
|
} else {
|
|
<div class="col-12 text-center mt-4">
|
|
<div class="text-primary">
|
|
<div class="spinner-grow text-primary mt-1" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
<p class="mt-3 fs-6 fw-semibold">
|
|
Waiting for the Host to continue...
|
|
</p>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function fireConfetti() {
|
|
let duration = 3 * 1000;
|
|
let animationEnd = Date.now() + duration;
|
|
let defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
|
|
|
|
function randomInRange(min, max) {
|
|
return Math.random() * (max - min) + min;
|
|
}
|
|
|
|
let interval = setInterval(function() {
|
|
let timeLeft = animationEnd - Date.now();
|
|
|
|
if (timeLeft <= 0) {
|
|
return clearInterval(interval);
|
|
}
|
|
|
|
let particleCount = 50 * (timeLeft / duration);
|
|
|
|
// Left burst
|
|
confetti(Object.assign({}, defaults, {
|
|
particleCount,
|
|
origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 }
|
|
}));
|
|
|
|
// Right burst
|
|
confetti(Object.assign({}, defaults, {
|
|
particleCount,
|
|
origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 }
|
|
}));
|
|
}, 250);
|
|
}
|
|
connectWebSocket();
|
|
fireConfetti();
|
|
</script> |