Keep pregame lobby chat open for an hour after the game ends

The chat used to disappear the moment a session left CREATED status.
Sessions now record a finishedAt timestamp when they're won or lost,
and the lobby (with chat) stays reachable via /game/{session} for an
hour afterward instead of immediately redirecting to the win/lose
feedback page. The lobby template shows a distinct "game finished"
header with a link to that feedback page during this window.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-08-10 16:47:57 +02:00
co-authored by Claude Sonnet 5
parent 846cfbc44a
commit 2bfc2aca1a
8 changed files with 112 additions and 26 deletions
+42 -24
View File
@@ -1,38 +1,56 @@
{% extends 'layout/site.html.twig' %}
{% block title %}Waiting for players - {{ session.game.name }}{% endblock %}
{% set isCreated = session.status.value == 'created' %}
{% set isFinished = session.status.value in ['won', 'lost'] %}
{% block title %}{{ isCreated ? 'Waiting for players' : 'Post-game chat' }} - {{ session.game.name }}{% endblock %}
{% block body %}
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-sm mb-4">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">Waiting for more players to join</h3>
</div>
<div class="card-body">
<h4>{{ session.game.name }}</h4>
<p>Share the invite code with your friends. Feel free to chat below while you wait &mdash; no need to reload the page.</p>
<div class="alert alert-info">
<strong>Players joined:</strong> {{ session.players|length }} / {{ session.game.numberOfPlayers }}
{% if isCreated %}
<div class="card shadow-sm mb-4">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">Waiting for more players to join</h3>
</div>
<div class="card-body">
<h4>{{ session.game.name }}</h4>
<p>Share the invite code with your friends. Feel free to chat below while you wait &mdash; no need to reload the page.</p>
<ul class="list-group mb-3">
{% for sessionPlayer in session.players %}
<li class="list-group-item">{{ sessionPlayer.user.username }}</li>
{% endfor %}
</ul>
<div class="alert alert-info">
<strong>Players joined:</strong> {{ session.players|length }} / {{ session.game.numberOfPlayers }}
</div>
{% if session.players|length >= session.game.numberOfPlayers %}
<form method="post" action="{{ path('game_dashboard') }}" class="mb-3">
<input type="hidden" name="session_id" value="{{ session.id }}">
<button type="submit" name="start_session" class="btn btn-success">Start Session</button>
</form>
{% endif %}
<ul class="list-group mb-3">
{% for sessionPlayer in session.players %}
<li class="list-group-item">{{ sessionPlayer.user.username }}</li>
{% endfor %}
</ul>
<a href="{{ path('game_dashboard') }}" class="btn btn-outline-secondary btn-sm">Back to Dashboard</a>
{% if session.players|length >= session.game.numberOfPlayers %}
<form method="post" action="{{ path('game_dashboard') }}" class="mb-3">
<input type="hidden" name="session_id" value="{{ session.id }}">
<button type="submit" name="start_session" class="btn btn-success">Start Session</button>
</form>
{% endif %}
<a href="{{ path('game_dashboard') }}" class="btn btn-outline-secondary btn-sm">Back to Dashboard</a>
</div>
</div>
</div>
{% elseif isFinished %}
<div class="card shadow-sm mb-4">
<div class="card-header {{ session.status.value == 'won' ? 'bg-success' : 'bg-secondary' }} text-white">
<h3 class="card-title mb-0">{{ session.status.value == 'won' ? 'You won!' : 'Game over' }}</h3>
</div>
<div class="card-body">
<h4>{{ session.game.name }}</h4>
<p>The game has ended, but the chat is still open for a little while &mdash; feel free to keep talking.</p>
<a href="{{ path(session.status.value == 'won' ? 'game_won' : 'game_lost', {session: session.id}) }}" class="btn btn-primary btn-sm">View results</a>
<a href="{{ path('game_dashboard') }}" class="btn btn-outline-secondary btn-sm">Back to Dashboard</a>
</div>
</div>
{% endif %}
<div class="card shadow-sm">
<div class="card-header">