diff --git a/draw/consumers.py b/draw/consumers.py index 27803a3..86a2d74 100644 --- a/draw/consumers.py +++ b/draw/consumers.py @@ -5,6 +5,7 @@ from random import randint from asgiref.sync import sync_to_async from channels.generic.websocket import AsyncJsonWebsocketConsumer +from django.conf import settings from django.utils.translation import gettext_lazy as _ from draw.models import Draw, Round, Pool, TeamDraw @@ -71,6 +72,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): await self.abort(**content) case 'dice': await self.process_dice(**content) + case 'draw_problem': + await self.select_problem(**content) @ensure_orga async def start_draw(self, fmt, **kwargs): @@ -304,6 +307,51 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {'type': 'draw.set_active', 'draw': self.tournament.draw}) + await self.channel_layer.group_send(f"tournament-{self.tournament.id}", + {'type': 'draw.dice_visibility', 'visible': False}) + + trigram = await sync_to_async(lambda: pool.current_team.participation.team.trigram)() + await self.channel_layer.group_send(f"team-{trigram}", + {'type': 'draw.box_visibility', 'visible': True}) + await self.channel_layer.group_send(f"volunteer-{self.tournament.id}", + {'type': 'draw.box_visibility', 'visible': True}) + + async def select_problem(self, **kwargs): + state = await sync_to_async(self.tournament.draw.get_state)() + + if state != 'WAITING_DRAW_PROBLEM': + return await self.alert(_("This is not the time for this."), 'danger') + + pool = await sync_to_async(lambda: self.tournament.draw.current_round.current_pool)() + td = await sync_to_async(lambda: pool.current_team)() + if not self.registration.is_volunteer: + participation = await Participation.objects.filter(team__participants=self.registration)\ + .prefetch_related('team').aget() + if participation.id != td.participation_id: + return await self.alert("This is not your turn.", 'danger') + + while True: + problem = randint(1, settings.PROBLEM_COUNT) + if await pool.teamdraw_set.filter(accepted=problem).acount() < (2 if pool.size == 5 else 1): + break + + td.purposed = problem + await sync_to_async(td.save)() + + trigram = await sync_to_async(lambda: td.participation.team.trigram)() + await self.channel_layer.group_send(f"team-{trigram}", + {'type': 'draw.box_visibility', 'visible': False}) + await self.channel_layer.group_send(f"volunteer-{self.tournament.id}", + {'type': 'draw.box_visibility', 'visible': False}) + await self.channel_layer.group_send(f"team-{trigram}", + {'type': 'draw.buttons_visibility', 'visible': True}) + await self.channel_layer.group_send(f"volunteer-{self.tournament.id}", + {'type': 'draw.buttons_visibility', 'visible': True}) + await self.channel_layer.group_send(f"team-{self.tournament.id}", + {'type': 'draw.draw_problem', 'team': trigram, 'problem': problem}) + await self.channel_layer.group_send(f"tournament-{self.tournament.id}", + {'type': 'draw.set_info', 'draw': self.tournament.draw}) + async def draw_alert(self, content): return await self.alert(**content) @@ -319,6 +367,12 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): async def draw_dice_visibility(self, content): await self.send_json({'type': 'dice_visibility', 'visible': content['visible']}) + async def draw_box_visibility(self, content): + await self.send_json({'type': 'box_visibility', 'visible': content['visible']}) + + async def draw_buttons_visibility(self, content): + await self.send_json({'type': 'buttons_visibility', 'visible': content['visible']}) + async def draw_send_poules(self, content): await self.send_json({'type': 'set_poules', 'round': content['round'].number, 'poules': [{'letter': pool.get_letter_display(), 'teams': await pool.atrigrams()} diff --git a/draw/static/draw.js b/draw/static/draw.js index 4580002..4dd9342 100644 --- a/draw/static/draw.js +++ b/draw/static/draw.js @@ -16,6 +16,10 @@ function drawDice(tid, trigram = null) { sockets[tid].send(JSON.stringify({'type': 'dice', 'trigram': trigram})) } +function drawProblem(tid) { + sockets[tid].send(JSON.stringify({'type': 'draw_problem'})) +} + function showNotification(title, body, timeout = 5000) { let notif = new Notification(title, {'body': body, 'icon': "/static/tfjm.svg"}) if (timeout) @@ -111,6 +115,22 @@ document.addEventListener('DOMContentLoaded', () => { div.classList.add('d-none') } + function updateBoxVisibility(visible) { + let div = document.getElementById(`draw-problem-${tournament.id}`) + if (visible) + div.classList.remove('d-none') + else + div.classList.add('d-none') + } + + function updateButtonsVisibility(visible) { + let div = document.getElementById(`buttons-${tournament.id}`) + if (visible) + div.classList.remove('d-none') + else + div.classList.add('d-none') + } + function updatePoules(round, poules) { let roundList = document.getElementById(`recap-${tournament.id}-round-list`) let poolListId = `recap-${tournament.id}-round-${round}-pool-list` @@ -413,6 +433,12 @@ document.addEventListener('DOMContentLoaded', () => { case 'dice_visibility': updateDiceVisibility(data.visible) break + case 'box_visibility': + updateBoxVisibility(data.visible) + break + case 'buttons_visibility': + updateButtonsVisibility(data.visible) + break case 'set_poules': updatePoules(data.round, data.poules) break diff --git a/draw/templates/draw/tournament_content.html b/draw/templates/draw/tournament_content.html index 22d451f..0c769f9 100644 --- a/draw/templates/draw/tournament_content.html +++ b/draw/templates/draw/tournament_content.html @@ -119,15 +119,30 @@ -
-
- -
+

+ {% trans "Draw a problem" %} +

+
+ +
+
+
+ + +
+