fixed attribution of .fa-hand-pointer cursor color scheme to ordering according to token-drop sequence instead of seat sequence; updates to accomodate this throughout apps.epic.models & .views, plus new apps.epic migration; assigned #id_sig_cursor_portal a z-index value corresponding to a high position but still beneath the #id_tray apparatus; minor semantic reordering of INSTALLED_APPS in core.settings
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
23
src/apps/epic/migrations/0030_sigreservation_seat_fk.py
Normal file
23
src/apps/epic/migrations/0030_sigreservation_seat_fk.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('epic', '0029_fix_schizo_cautions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sigreservation',
|
||||||
|
name='seat',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name='sig_reservation',
|
||||||
|
to='epic.tableseat',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -359,6 +359,10 @@ class SigReservation(models.Model):
|
|||||||
gamer = models.ForeignKey(
|
gamer = models.ForeignKey(
|
||||||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='sig_reservations'
|
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='sig_reservations'
|
||||||
)
|
)
|
||||||
|
seat = models.ForeignKey(
|
||||||
|
'TableSeat', null=True, blank=True,
|
||||||
|
on_delete=models.SET_NULL, related_name='sig_reservation',
|
||||||
|
)
|
||||||
card = models.ForeignKey(
|
card = models.ForeignKey(
|
||||||
'TarotCard', on_delete=models.CASCADE, related_name='sig_reservations'
|
'TarotCard', on_delete=models.CASCADE, related_name='sig_reservations'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ from django.shortcuts import redirect, render
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from apps.drama.models import GameEvent, record
|
from apps.drama.models import GameEvent, record
|
||||||
|
from django.db.models import Case, IntegerField, Value, When
|
||||||
|
|
||||||
from apps.epic.models import (
|
from apps.epic.models import (
|
||||||
GateSlot, Room, RoomInvite, SigReservation, TableSeat, TarotCard, TarotDeck,
|
GateSlot, Room, RoomInvite, SIG_SEAT_ORDER, SigReservation, TableSeat,
|
||||||
|
TarotCard, TarotDeck,
|
||||||
active_sig_seat, debit_token, levity_sig_cards, gravity_sig_cards,
|
active_sig_seat, debit_token, levity_sig_cards, gravity_sig_cards,
|
||||||
select_token, sig_deck_cards,
|
select_token, sig_deck_cards,
|
||||||
)
|
)
|
||||||
@@ -92,6 +95,22 @@ def _notify_sig_reserved(room_id, card_id, role, reserved):
|
|||||||
|
|
||||||
SLOT_ROLE_LABELS = {1: "PC", 2: "NC", 3: "EC", 4: "SC", 5: "AC", 6: "BC"}
|
SLOT_ROLE_LABELS = {1: "PC", 2: "NC", 3: "EC", 4: "SC", 5: "AC", 6: "BC"}
|
||||||
|
|
||||||
|
_SIG_SEAT_ORDERING = Case(
|
||||||
|
*[When(role=r, then=Value(i)) for i, r in enumerate(SIG_SEAT_ORDER)],
|
||||||
|
default=Value(99),
|
||||||
|
output_field=IntegerField(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _canonical_user_seat(room, user):
|
||||||
|
"""Return the user's seat whose role comes first in PC→NC→EC→SC→AC→BC order.
|
||||||
|
|
||||||
|
In normal play (one user = one seat) this is equivalent to .first().
|
||||||
|
For Carte Blanche (one user = all seats) it returns the PC seat, ensuring
|
||||||
|
sig-select cursor placement is seat-based, not position/slot-based.
|
||||||
|
"""
|
||||||
|
return room.table_seats.filter(gamer=user).order_by(_SIG_SEAT_ORDERING).first()
|
||||||
|
|
||||||
_ROLE_SCRAWL_NAMES = {
|
_ROLE_SCRAWL_NAMES = {
|
||||||
"PC": "Player", "NC": "Narrator", "EC": "Economist",
|
"PC": "Player", "NC": "Narrator", "EC": "Economist",
|
||||||
"SC": "Shepherd", "AC": "Alchemist", "BC": "Builder",
|
"SC": "Shepherd", "AC": "Alchemist", "BC": "Builder",
|
||||||
@@ -242,7 +261,7 @@ def _role_select_context(room, user):
|
|||||||
"slots": room.gate_slots.order_by("slot_number"),
|
"slots": room.gate_slots.order_by("slot_number"),
|
||||||
}
|
}
|
||||||
if room.table_status == Room.SIG_SELECT:
|
if room.table_status == Room.SIG_SELECT:
|
||||||
user_seat = room.table_seats.filter(gamer=user).first() if user.is_authenticated else None
|
user_seat = _canonical_user_seat(room, user) if user.is_authenticated else None
|
||||||
user_role = user_seat.role if user_seat else None
|
user_role = user_seat.role if user_seat else None
|
||||||
user_polarity = None
|
user_polarity = None
|
||||||
if user_role in _LEVITY_ROLES:
|
if user_role in _LEVITY_ROLES:
|
||||||
@@ -583,7 +602,7 @@ def sig_reserve(request, room_id):
|
|||||||
if room.table_status != Room.SIG_SELECT:
|
if room.table_status != Room.SIG_SELECT:
|
||||||
return HttpResponse(status=400)
|
return HttpResponse(status=400)
|
||||||
|
|
||||||
user_seat = room.table_seats.filter(gamer=request.user).first()
|
user_seat = _canonical_user_seat(room, request.user)
|
||||||
if not user_seat or not user_seat.role:
|
if not user_seat or not user_seat.role:
|
||||||
return HttpResponse(status=403)
|
return HttpResponse(status=403)
|
||||||
|
|
||||||
@@ -622,7 +641,7 @@ def sig_reserve(request, room_id):
|
|||||||
|
|
||||||
SigReservation.objects.create(
|
SigReservation.objects.create(
|
||||||
room=room, gamer=request.user, card=card,
|
room=room, gamer=request.user, card=card,
|
||||||
role=user_seat.role, polarity=polarity,
|
seat=user_seat, role=user_seat.role, polarity=polarity,
|
||||||
)
|
)
|
||||||
_notify_sig_reserved(room_id, card.pk, user_seat.role, reserved=True)
|
_notify_sig_reserved(room_id, card.pk, user_seat.role, reserved=True)
|
||||||
return HttpResponse(status=200)
|
return HttpResponse(status=200)
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ INSTALLED_APPS = [
|
|||||||
# Board apps
|
# Board apps
|
||||||
'apps.dashboard',
|
'apps.dashboard',
|
||||||
'apps.gameboard',
|
'apps.gameboard',
|
||||||
|
'apps.billboard',
|
||||||
# Gamer apps
|
# Gamer apps
|
||||||
'apps.lyric',
|
'apps.lyric',
|
||||||
'apps.epic',
|
'apps.epic',
|
||||||
'apps.drama',
|
'apps.drama',
|
||||||
'apps.billboard',
|
|
||||||
'apps.ap',
|
|
||||||
# Custom apps
|
# Custom apps
|
||||||
|
'apps.ap',
|
||||||
'apps.api',
|
'apps.api',
|
||||||
'apps.applets',
|
'apps.applets',
|
||||||
'functional_tests',
|
'functional_tests',
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ html:has(.sig-backdrop) {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 9999;
|
z-index: 200; // above sig-overlay (120), below tray (310)
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user