Teams can draw a problem

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-03-24 13:24:44 +01:00
parent 6b5c630048
commit e90005b192
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
3 changed files with 102 additions and 7 deletions

View File

@ -5,6 +5,7 @@ from random import randint
from asgiref.sync import sync_to_async from asgiref.sync import sync_to_async
from channels.generic.websocket import AsyncJsonWebsocketConsumer from channels.generic.websocket import AsyncJsonWebsocketConsumer
from django.conf import settings
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from draw.models import Draw, Round, Pool, TeamDraw from draw.models import Draw, Round, Pool, TeamDraw
@ -71,6 +72,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await self.abort(**content) await self.abort(**content)
case 'dice': case 'dice':
await self.process_dice(**content) await self.process_dice(**content)
case 'draw_problem':
await self.select_problem(**content)
@ensure_orga @ensure_orga
async def start_draw(self, fmt, **kwargs): 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}", await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active', 'draw': self.tournament.draw}) {'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): async def draw_alert(self, content):
return await self.alert(**content) return await self.alert(**content)
@ -319,6 +367,12 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async def draw_dice_visibility(self, content): async def draw_dice_visibility(self, content):
await self.send_json({'type': 'dice_visibility', 'visible': content['visible']}) 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): async def draw_send_poules(self, content):
await self.send_json({'type': 'set_poules', 'round': content['round'].number, await self.send_json({'type': 'set_poules', 'round': content['round'].number,
'poules': [{'letter': pool.get_letter_display(), 'teams': await pool.atrigrams()} 'poules': [{'letter': pool.get_letter_display(), 'teams': await pool.atrigrams()}

View File

@ -16,6 +16,10 @@ function drawDice(tid, trigram = null) {
sockets[tid].send(JSON.stringify({'type': 'dice', 'trigram': trigram})) 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) { function showNotification(title, body, timeout = 5000) {
let notif = new Notification(title, {'body': body, 'icon': "/static/tfjm.svg"}) let notif = new Notification(title, {'body': body, 'icon': "/static/tfjm.svg"})
if (timeout) if (timeout)
@ -111,6 +115,22 @@ document.addEventListener('DOMContentLoaded', () => {
div.classList.add('d-none') 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) { function updatePoules(round, poules) {
let roundList = document.getElementById(`recap-${tournament.id}-round-list`) let roundList = document.getElementById(`recap-${tournament.id}-round-list`)
let poolListId = `recap-${tournament.id}-round-${round}-pool-list` let poolListId = `recap-${tournament.id}-round-${round}-pool-list`
@ -413,6 +433,12 @@ document.addEventListener('DOMContentLoaded', () => {
case 'dice_visibility': case 'dice_visibility':
updateDiceVisibility(data.visible) updateDiceVisibility(data.visible)
break break
case 'box_visibility':
updateBoxVisibility(data.visible)
break
case 'buttons_visibility':
updateButtonsVisibility(data.visible)
break
case 'set_poules': case 'set_poules':
updatePoules(data.round, data.poules) updatePoules(data.round, data.poules)
break break

View File

@ -119,12 +119,26 @@
</h2> </h2>
</div> </div>
<div id="draw-problem-{{ tournament.id }}"
{% if tournament.draw.get_state != 'WAITING_DRAW_PROBLEM' %}{% if user.registration.team.participation != tournament.draw.current_round.current_pool.current_team.participation and not user.is_volunteer %}class="d-none"{% endif %}{% endif %}>
<div class="text-center">
<button class="btn btn-lg" style="font-size: 100pt" onclick="drawProblem({{ tournament.id }})">
🗳️
</button>
</div>
<h2 class="text-center">
{% trans "Draw a problem" %}
</h2>
</div>
<div id="buttons-{{ tournament.id }}"
{% if tournament.draw.get_state != 'WAITING_CHOOSE_PROBLEM' %}{% if user.registration.team.participation != tournament.draw.current_round.current_pool.current_team.participation and not user.is_volunteer %}class="d-none"{% endif %}{% endif %}>
<div class="d-grid"> <div class="d-grid">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-success disabled"> <button class="btn btn-success">
{% trans "Accept" %} {% trans "Accept" %}
</button> </button>
<button class="btn btn-danger disabled"> <button class="btn btn-danger">
{% trans "Decline" %} {% trans "Decline" %}
</button> </button>
</div> </div>
@ -133,6 +147,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div id="tables-{{ tournament.id }}" class="row"> <div id="tables-{{ tournament.id }}" class="row">
{% for round in tournament.draw.round_set.all %} {% for round in tournament.draw.round_set.all %}