feat: Add real-time quiz lobby functionality
- Implement WebSocket-based lobby system for quiz participants - Add lobby page with real-time participant updates - Create LobbyConsumer for WebSocket communication - Add routing configuration for WebSocket connections - Update requirements with WebSocket dependencies - Add development and production server documentation This change enables real-time quiz lobbies where participants can join and wait for the quiz to start, with instant updates for all connected users.
This commit is contained in:
@@ -2,20 +2,73 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4">
|
||||
<h1>{{ quiz.name }}</h1>
|
||||
<h3>{{ quiz.name }}</h3>
|
||||
<h1 class="text-center text-4xl font-bold mb-4">{{ quiz_game.join_code }}</h1>
|
||||
{% if participant %}
|
||||
<div class="mt-4 mb-4 text-center">
|
||||
<h3>Sichtbar als <b>{{ participant.display_name }}</b></h3>
|
||||
</div>
|
||||
<div id="player-list">
|
||||
<ul>
|
||||
<li>Noch keine Spieler gefunden.</li>
|
||||
{% endif %}
|
||||
<div class="mb-4">
|
||||
<h3 class="font-bold mb-2">Teilnehmer:</h3>
|
||||
<ul id="participants-list" class="space-y-2">
|
||||
<li class="text-gray-500">Warte auf Teilnehmer...</li>
|
||||
</ul>
|
||||
{{debug}}
|
||||
</div>
|
||||
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit">Starten</button>
|
||||
{% if host_id %}
|
||||
<button id="start-button" class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="button">Starten</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
// TODO: Websocket Verbindung aufbauen und Teilnehmerliste bei beitreten updaten
|
||||
const joinCode = '{{ quiz_game.join_code }}';
|
||||
const wsScheme = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
const lobbySocket = new WebSocket(
|
||||
wsScheme + '://' + window.location.host + '/ws/game/' + joinCode + '/'
|
||||
);
|
||||
|
||||
lobbySocket.onmessage = function(e) {
|
||||
const data = JSON.parse(e.data);
|
||||
if (data.type === 'participant_list' || data.type === 'participant_list_update') {
|
||||
updateParticipantsList(data.participants);
|
||||
}
|
||||
};
|
||||
|
||||
lobbySocket.onclose = function(e) {
|
||||
console.error('Lobby socket closed unexpectedly');
|
||||
};
|
||||
|
||||
{% if participant %}
|
||||
// Send heartbeat every 10 seconds
|
||||
setInterval(() => {
|
||||
if (lobbySocket.readyState === WebSocket.OPEN) {
|
||||
lobbySocket.send(JSON.stringify({
|
||||
'type': 'heartbeat',
|
||||
'participant_id': '{{ participant.participant_id }}'
|
||||
}));
|
||||
}
|
||||
}, 10000);
|
||||
{% endif %}
|
||||
|
||||
function updateParticipantsList(participants) {
|
||||
const list = document.getElementById('participants-list');
|
||||
if (participants.length === 0) {
|
||||
list.innerHTML = '<li class="text-gray-500">Noch keine Teilnehmer...</li>';
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = participants
|
||||
.map(p => `<li class="p-2 bg-gray-100 rounded">${p.name}</li>`)
|
||||
.join('');
|
||||
}
|
||||
|
||||
// Request initial participants list
|
||||
lobbySocket.onopen = function(e) {
|
||||
lobbySocket.send(JSON.stringify({
|
||||
'type': 'update_participants'
|
||||
}));
|
||||
};
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user