From d03c99b8e374536095abaef5af8c16d5316e015f Mon Sep 17 00:00:00 2001 From: ben8 Date: Tue, 29 Jul 2025 19:01:20 +0200 Subject: [PATCH] =?UTF-8?q?sch=C3=B6nes=20Siegerpodest=20(und=20bessere=20?= =?UTF-8?q?Punkte=C3=BCbersicht)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- django/play/consumers/game.py | 74 +++ .../0014_alter_quizgame_current_state.py | 18 + .../0015_alter_quizgame_current_state.py | 18 + django/play/models.py | 5 +- django/play/urls.py | 2 + django/play/views.py | 85 ++- django/templates/partials/_footer.html | 2 +- django/templates/play/game/question_host.html | 2 +- .../play/game/question_participant.html | 3 +- .../templates/play/game/score_overview.html | 173 ++--- django/templates/play/game/scoreboard.html | 310 +++++++++ django/templates/play/game/winner_podest.html | 594 ++++++++++++++++++ 12 files changed, 1210 insertions(+), 76 deletions(-) create mode 100644 django/play/migrations/0014_alter_quizgame_current_state.py create mode 100644 django/play/migrations/0015_alter_quizgame_current_state.py create mode 100644 django/templates/play/game/scoreboard.html create mode 100644 django/templates/play/game/winner_podest.html diff --git a/django/play/consumers/game.py b/django/play/consumers/game.py index 5500af7..649aaf5 100644 --- a/django/play/consumers/game.py +++ b/django/play/consumers/game.py @@ -128,6 +128,15 @@ class GameConsumer(AsyncWebsocketConsumer): host_id = text_data_json['host_id'] if await self.verify_host(host_id): await self.advance_to_next_question() + elif message_type == 'winner_podest': + host_id = text_data_json['host_id'] + if await self.verify_host(host_id): + await self.show_winner_podest() + + elif message_type == 'scoreboard': + host_id = text_data_json['host_id'] + if await self.verify_host(host_id): + await self.show_scoreboard() elif message_type == 'finish_game': host_id = text_data_json['host_id'] @@ -430,6 +439,26 @@ class GameConsumer(AsyncWebsocketConsumer): 'redirect_url': reverse('play:question', kwargs={'join_code': self.join_code}) } ) + elif result == 'winner_podest': + # Notify clients to redirect to next question + await self.channel_layer.group_send( + self.game_group_name, + { + 'type': 'game_state_update', + 'action': 'show_winner_podest', + 'redirect_url': reverse('play:winner_podest', kwargs={'join_code': self.join_code}) + } + ) + elif result == 'scoreboard': + # Notify clients to redirect to next question + await self.channel_layer.group_send( + self.game_group_name, + { + 'type': 'game_state_update', + 'action': 'show_scoreboard', + 'redirect_url': reverse('play:scoreboard', kwargs={'join_code': self.join_code}) + } + ) @database_sync_to_async def _show_scores(self): @@ -476,3 +505,48 @@ class GameConsumer(AsyncWebsocketConsumer): 'redirect_url': reverse('play:finished', kwargs={'join_code': self.join_code}) } ) + @database_sync_to_async + def _show_winner_podest(self): + try: + quiz_game = QuizGame.objects.get(join_code=self.join_code) + quiz_game.current_state = 'winner_podest' + quiz_game.save() + return True + except QuizGame.DoesNotExist: + return False + + async def show_winner_podest(self): + success = await self._show_winner_podest() + if success: + # Notify clients to redirect to finished page + await self.channel_layer.group_send( + self.game_group_name, + { + 'type': 'game_state_update', + 'action': 'show_winner_podest', + 'redirect_url': reverse('play:winner_podest', kwargs={'join_code': self.join_code}) + } + ) + + @database_sync_to_async + def _show_scoreboard(self): + try: + quiz_game = QuizGame.objects.get(join_code=self.join_code) + quiz_game.current_state = 'scoreboard' + quiz_game.save() + return True + except QuizGame.DoesNotExist: + return False + + async def show_scoreboard(self): + success = await self._show_scoreboard() + if success: + # Notify clients to redirect to finished page + await self.channel_layer.group_send( + self.game_group_name, + { + 'type': 'game_state_update', + 'action': 'show_scoreboard', + 'redirect_url': reverse('play:scoreboard', kwargs={'join_code': self.join_code}) + } + ) diff --git a/django/play/migrations/0014_alter_quizgame_current_state.py b/django/play/migrations/0014_alter_quizgame_current_state.py new file mode 100644 index 0000000..865b3f7 --- /dev/null +++ b/django/play/migrations/0014_alter_quizgame_current_state.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-07-25 16:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('play', '0013_quizanswer_answer_text_quizanswer_answers_order_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='quizgame', + name='current_state', + field=models.CharField(choices=[('lobby', 'In Lobby'), ('question', 'Frage läuft'), ('scores', 'Punkteübersicht'), ('winner_podest', 'Siegerpodest'), ('finished', 'Beendet')], default='lobby', max_length=20), + ), + ] diff --git a/django/play/migrations/0015_alter_quizgame_current_state.py b/django/play/migrations/0015_alter_quizgame_current_state.py new file mode 100644 index 0000000..f34fa3d --- /dev/null +++ b/django/play/migrations/0015_alter_quizgame_current_state.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-07-28 13:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('play', '0014_alter_quizgame_current_state'), + ] + + operations = [ + migrations.AlterField( + model_name='quizgame', + name='current_state', + field=models.CharField(choices=[('lobby', 'In Lobby'), ('question', 'Frage läuft'), ('scores', 'Punkteübersicht'), ('winner_podest', 'Siegerpodest'), ('finished', 'Beendet'), ('scoreboard', 'Scoreboard')], default='lobby', max_length=20), + ), + ] diff --git a/django/play/models.py b/django/play/models.py index 36d35e7..81bca6a 100644 --- a/django/play/models.py +++ b/django/play/models.py @@ -10,7 +10,10 @@ class QuizGame(models.Model): ('lobby', 'In Lobby'), ('question', 'Frage läuft'), ('scores', 'Punkteübersicht'), - ('finished', 'Beendet') + ('winner_podest','Siegerpodest'), + ('finished', 'Beendet'), + ('scoreboard', 'Scoreboard'), + ] host_id = models.CharField(max_length=200, unique=True) diff --git a/django/play/urls.py b/django/play/urls.py index 261b472..272d631 100644 --- a/django/play/urls.py +++ b/django/play/urls.py @@ -12,6 +12,8 @@ urlpatterns = [ path('game//waiting', views.waiting_room, name='waiting'), path('game//scores', views.scores, name='scores'), path('game//finished', views.finished, name='finished'), + path('game//winner_podest', views.winner_podest, name='winner_podest'), + path('game//scoreboard', views.scoreboard, name='scoreboard'), path('select_mode/', views.select_mode, name='select_mode'), path('selected_mode/', views.selected_mode, name='selected_mode'), ] \ No newline at end of file diff --git a/django/play/views.py b/django/play/views.py index 9090044..daeba2a 100644 --- a/django/play/views.py +++ b/django/play/views.py @@ -188,6 +188,49 @@ def scores(request, join_code): 'question_index': quiz_game.current_question_index, 'total_questions': len(questions) }) + + +def scoreboard(request, join_code): + quiz_game = get_object_or_404(QuizGame, join_code=join_code) + + # Verify game state + if quiz_game.current_state != 'scoreboard': + return redirect('play:lobby', join_code=join_code) + + # Get participants sorted by score + participants = QuizGameParticipant.objects.filter(quiz_game=quiz_game).order_by('-score') + + # Check if user is host + is_host = False + if 'host_id' in request.COOKIES and request.COOKIES['host_id'] == quiz_game.host_id: + is_host = True + + # Get current question for context + questions = quiz_game.quiz_id.questions.all() + current_question = questions[quiz_game.current_question_index] + question_data = json.loads(current_question.data) + + try: + my_participant = request.session.get('my_participant-participant_id') + participant = QuizGameParticipant.objects.get(participant_id=my_participant) + my_participant=participant + except: + participant = QuizGameParticipant.objects.none() + + return render(request, 'play/game/scoreboard.html', { + 'quiz_game': quiz_game, + 'participants': participants, + 'participant': participant, + 'my_participant':my_participant, + 'is_host': is_host, + 'host_id': quiz_game.host_id if is_host else None, + 'is_last_question': quiz_game.current_question_index + 1 >= len(questions), + 'question_data': question_data, + 'question_index': quiz_game.current_question_index, + 'total_questions': len(questions) + }) + + """ def finished(request, join_code): @@ -225,6 +268,45 @@ def finished(request, join_code): """ +def winner_podest(request, join_code): + quiz_game = get_object_or_404(QuizGame, join_code=join_code) + + # Verify game state + if quiz_game.current_state != 'winner_podest': + return redirect('play:lobby', join_code=join_code) + + # Get participants sorted by score + participants = QuizGameParticipant.objects.filter(quiz_game=quiz_game).order_by('-score') + + # Check if user is host + is_host = False + if 'host_id' in request.COOKIES and request.COOKIES['host_id'] == quiz_game.host_id: + is_host = True + + # Get current question for context + questions = quiz_game.quiz_id.questions.all() + current_question = questions[quiz_game.current_question_index] + question_data = json.loads(current_question.data) + + try: + my_participant = request.session.get('my_participant-participant_id') + participant = QuizGameParticipant.objects.get(participant_id=my_participant) + my_participant=participant + except: + participant = QuizGameParticipant.objects.none() + + return render(request, 'play/game/winner_podest.html', { + 'quiz_game': quiz_game, + 'participants': participants, + 'participant': participant, + 'my_participant':my_participant, + 'is_host': is_host, + 'host_id': quiz_game.host_id if is_host else None, + 'is_last_question': quiz_game.current_question_index + 1 >= len(questions), + 'question_data': question_data, + 'question_index': quiz_game.current_question_index, + 'total_questions': len(questions) + }) def finished(request, join_code): quiz_game = get_object_or_404(QuizGame, join_code=join_code) @@ -260,8 +342,7 @@ def finished(request, join_code): return render(request, 'play/game/finished.html', context) except QuizGame.DoesNotExist: return redirect('home') - - + def question(request, join_code): quiz_game = get_object_or_404(QuizGame, join_code=join_code) diff --git a/django/templates/partials/_footer.html b/django/templates/partials/_footer.html index bb20404..93e1e45 100644 --- a/django/templates/partials/_footer.html +++ b/django/templates/partials/_footer.html @@ -1,5 +1,5 @@
-
+

Impressum

Datenschutz

Repository

diff --git a/django/templates/play/game/question_host.html b/django/templates/play/game/question_host.html index 71fdf17..f3a168c 100644 --- a/django/templates/play/game/question_host.html +++ b/django/templates/play/game/question_host.html @@ -153,7 +153,7 @@ {% if request.session.mode == "learn" %}
+ class="answer-option text-center mb-4 p-2 bg-gray-100 hover:bg-blue-100 rounded-lg transition-colors duration-200 answer-option lg:w-80 dark:bg-transparent dark:text-white dark:hover:bg-[#2a2f3a] "> + + {% else %} + {% endif %} {% else %} - + {% else %} + + {% endif %} + {% endif %} {% endif %}
@@ -205,23 +218,6 @@ {% block extra_js %} {% if is_last_question %} - {% endif %} {% include 'play/game/common_scripts.html' %} {% if is_host %} @@ -232,6 +228,16 @@ +{% endblock %} diff --git a/django/templates/play/game/winner_podest.html b/django/templates/play/game/winner_podest.html new file mode 100644 index 0000000..a6919e5 --- /dev/null +++ b/django/templates/play/game/winner_podest.html @@ -0,0 +1,594 @@ +{% extends 'base.html' %} + +{% block content %} + +{% if is_last_question and is_host %} + +
+

🏆 Siegerpodest

+

Wer ist hier der Quiz-Master?

+ +{% with participant=participants.0 %} +
+

+ Glückwunsch, {{ participant.display_name }}! +

+
+{% endwith %} + + + + + + + + +
+ + + + {% with participant=participants.1 %} +
+ {{ participant.display_name }} +

{{ participant.score }}

+
+ 🥈 +
+
+ {% endwith %} + + + {% with participant=participants.0 %} +
+
+ {{ participant.display_name }} +

{{ participant.score }}

+
+ 🥇
+
+
+ {% endwith %} + + + {% with participant=participants.2 %} +
+ {{ participant.display_name }} +

{{ participant.score }}

+
+ 🥉 +
+
+ {% endwith %} + +
+ + +
+ + +{% else %} + + +
+ + + {% with participant=participants.0 %} +
+

+ Glückwunsch, {{ participant.display_name }}! +

+
+{% endwith %} + +
+

🏆 Wer ist hier der Quiz-Master?

+ +

Nach der Siegerehrung siehst du deine Platzierung!

+ + + +
+ + +
+ {% for participant in participants %} + {% if request.session.mode != "learn" %} + {% if participant == my_participant or is_host %} + + + {% endif %} + {% endfor %} +
+
+ + +{% endif %} + + + + + + + +{% endblock %} +
+ +{% block extra_js %} +{% if is_last_question %} + + +{% endif %} +{% include 'play/game/common_scripts.html' %} +{% if is_host %} +{% include 'play/game/sound.html' %} +{% endif %} + + + + + + +{% endblock %} \ No newline at end of file