135 lines
4.9 KiB
HTML
135 lines
4.9 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block content %}
|
|
<div class="container mx-auto px-4">
|
|
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
|
<p class="text-gray-700 font-bold text-xl mb-4">Frage {{ question_index|add:1 }} von {{ total_questions }}</p>
|
|
<h1 class="text-3xl font-bold mb-6">{{ question_data.question }}</h1>
|
|
|
|
{% if question_image %}
|
|
<div class="flex justify-center">
|
|
<img class="m-4" src="{{ question_image.url }}" style="max-width: 500px;" alt="Bild der Frage">
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="grid grid-cols-2 gap-4 mb-6">
|
|
<div class="p-4 bg-blue-50 rounded-lg">
|
|
<p class="text-blue-600 text-xl mb-2">Verbleibende Zeit</p>
|
|
<p id="remaining-time" class="text-6xl font-bold text-blue-700">30</p>
|
|
</div>
|
|
<div class="p-4 bg-blue-50 rounded-lg">
|
|
<p class="text-blue-600 text-xl mb-2">Antworten</p>
|
|
<p id="answer-count" class="text-6xl font-bold text-blue-700">0/0</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-4">
|
|
{% for option in question_data.options %}
|
|
<div class="p-4 bg-gray-100 rounded-lg" data-correct="{{ option.is_correct }}">
|
|
<p class="text-lg">{{ option.value }}</p>
|
|
<p id="option-count-{{ forloop.counter0 }}" class="text-gray-600 hidden">0 Antworten</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
{% include 'play/game/common_scripts.html' %}
|
|
<script>
|
|
const joinCode = '{{ quiz_game.join_code }}';
|
|
const hostId = '{{ host_id }}';
|
|
const questionStartTime = {{ start_time }};
|
|
const questionDuration = '{{ current_question.time_per_question }}'*1000; //Zeit pro Frage (indviduell eingestellt)
|
|
const gameSocket = initializeGameSocket(joinCode);
|
|
let answeredParticipants = 0;
|
|
let totalParticipants = 0;
|
|
const optionCounts = {};
|
|
|
|
gameSocket.onmessage = function(e) {
|
|
const data = JSON.parse(e.data);
|
|
if (data.type === 'participant_answer') {
|
|
answeredParticipants++;
|
|
updateAnswerCount();
|
|
updateOptionCount(data.answer);
|
|
} else if (data.type === 'participant_list_update') {
|
|
totalParticipants = data.participants.length;
|
|
updateAnswerCount();
|
|
} else if (data.type === 'game_state_update' &&
|
|
data.action === 'show_scores' &&
|
|
data.redirect_url) {
|
|
window.location.href = data.redirect_url;
|
|
}
|
|
};
|
|
|
|
gameSocket.onclose = function(e) {
|
|
wsUtil.handleClose(e);
|
|
};
|
|
|
|
function updateAnswerCount() {
|
|
const answerCountElement = document.getElementById('answer-count');
|
|
if (answerCountElement) {
|
|
answerCountElement.textContent = `${answeredParticipants}/${totalParticipants}`;
|
|
}
|
|
|
|
// If everyone has answered, advance to scores
|
|
if (answeredParticipants === totalParticipants && totalParticipants > 0) {
|
|
advanceToScores();
|
|
}
|
|
}
|
|
|
|
function updateOptionCount(optionIndex) {
|
|
optionCounts[optionIndex] = (optionCounts[optionIndex] || 0) + 1;
|
|
const optionElement = document.getElementById(`option-count-${optionIndex}`);
|
|
if (optionElement) {
|
|
optionElement.textContent = `${optionCounts[optionIndex]} Antworten`;
|
|
}
|
|
}
|
|
|
|
function advanceToScores() {
|
|
// Show correct answers and answer counts
|
|
var correctOptions = document.querySelectorAll('[data-correct="True"]');
|
|
for (var i = 0; i < correctOptions.length; i++) {
|
|
correctOptions[i].classList.add('border-2', 'border-green-500');
|
|
}
|
|
|
|
// Show answer counts
|
|
var countElements = document.querySelectorAll('[id^="option-count-"]');
|
|
for (var j = 0; j < countElements.length; j++) {
|
|
countElements[j].classList.remove('hidden');
|
|
}
|
|
|
|
// Wait a moment to show the correct answer and counts
|
|
setTimeout(function() {
|
|
gameSocket.send(JSON.stringify({
|
|
'type': 'advance_to_scores',
|
|
'host_id': hostId
|
|
}));
|
|
}, 2000);
|
|
}
|
|
|
|
// Timer
|
|
function updateTimer() {
|
|
const now = Date.now();
|
|
const elapsed = now - questionStartTime;
|
|
const remaining = Math.max(0, Math.ceil((questionDuration - elapsed) / 1000));
|
|
|
|
document.getElementById('remaining-time').textContent = remaining;
|
|
|
|
if (remaining === 0) {
|
|
advanceToScores();
|
|
} else {
|
|
requestAnimationFrame(updateTimer);
|
|
}
|
|
}
|
|
|
|
// Request initial participants list
|
|
gameSocket.onopen = function(e) {
|
|
gameSocket.send(JSON.stringify({
|
|
'type': 'update_participants'
|
|
}));
|
|
updateTimer();
|
|
};
|
|
</script>
|
|
{% endblock %} |