from django.contrib.auth.decorators import login_required from django.db.models import Q from django.http import HttpResponse from django.shortcuts import get_object_or_404, redirect, render from django.utils import timezone from apps.applets.utils import applet_context from apps.applets.models import Applet, UserApplet from apps.epic.models import DeckVariant, Room, RoomInvite from apps.lyric.models import Token GAMEBOARD_APPLET_ORDER = [ "new-game", "my-games", "game-kit", ] @login_required(login_url="/") def gameboard(request): pass_token = request.user.tokens.filter(token_type=Token.PASS).first() if request.user.is_staff else None coin = request.user.tokens.filter(token_type=Token.COIN).first() carte = request.user.tokens.filter(token_type=Token.CARTE).first() free_tokens = list(request.user.tokens.filter( token_type=Token.FREE, expires_at__gt=timezone.now() ).order_by("expires_at")) return render( request, "apps/gameboard/gameboard.html", { "pass_token": pass_token, "coin": coin, "carte": carte, "equipped_trinket_id": str(request.user.equipped_trinket_id or ""), "equipped_deck_id": str(request.user.equipped_deck_id or ""), "deck_variants": list(request.user.unlocked_decks.all()), "free_tokens": free_tokens, "free_count": len(free_tokens), "applets": applet_context(request.user, "gameboard"), "page_class": "page-gameboard", "my_games": Room.objects.filter( Q(owner=request.user) | Q(gate_slots__gamer=request.user) | Q(invites__invitee_email=request.user.email, invites__status=RoomInvite.PENDING) ).distinct(), } ) @login_required(login_url="/") def toggle_game_applets(request): checked = request.POST.getlist("applets") for applet in Applet.objects.filter(context="gameboard"): UserApplet.objects.update_or_create( user=request.user, applet=applet, defaults={"visible": applet.slug in checked}, ) if request.headers.get("HX-Request"): return render(request, "apps/gameboard/_partials/_applets.html", { "applets": applet_context(request.user, "gameboard"), "pass_token": request.user.tokens.filter(token_type=Token.PASS).first() if request.user.is_staff else None, "coin": request.user.tokens.filter(token_type=Token.COIN).first(), "carte": request.user.tokens.filter(token_type=Token.CARTE).first(), "equipped_trinket_id": str(request.user.equipped_trinket_id or ""), "equipped_deck_id": str(request.user.equipped_deck_id or ""), "deck_variants": list(request.user.unlocked_decks.all()), "free_tokens": list(request.user.tokens.filter( token_type=Token.FREE, expires_at__gt=timezone.now() ).order_by("expires_at")), "free_count": request.user.tokens.filter( token_type=Token.FREE, expires_at__gt=timezone.now() ).count(), "my_games": Room.objects.filter( Q(owner=request.user) | Q(gate_slots__gamer=request.user) | Q(invites__invitee_email=request.user.email, invites__status=RoomInvite.PENDING) ).distinct(), }) return redirect("gameboard") @login_required(login_url="/") def equip_trinket(request, token_id): token = get_object_or_404(Token, pk=token_id, user=request.user) if request.method == "POST": request.user.equipped_trinket = token request.user.save(update_fields=["equipped_trinket"]) return HttpResponse(status=204) return render( request, "apps/gameboard/_partials/_equip_trinket_btn.html", {"token": token}, ) @login_required(login_url="/") def equip_deck(request, deck_id): deck = get_object_or_404(DeckVariant, pk=deck_id) if request.method == "POST": request.user.equipped_deck = deck request.user.save(update_fields=["equipped_deck"]) return HttpResponse(status=204) return HttpResponse(status=405) @login_required(login_url="/") def game_kit(request): coin = request.user.tokens.filter(token_type=Token.COIN).first() pass_token = request.user.tokens.filter(token_type=Token.PASS).first() if request.user.is_staff else None carte = request.user.tokens.filter(token_type=Token.CARTE).first() free_tokens = list(request.user.tokens.filter( token_type=Token.FREE, expires_at__gt=timezone.now() ).order_by("expires_at")) tithe_tokens = list(request.user.tokens.filter(token_type=Token.TITHE)) return render(request, "apps/gameboard/game_kit.html", { "coin": coin, "pass_token": pass_token, "carte": carte, "free_tokens": free_tokens, "tithe_tokens": tithe_tokens, "unlocked_decks": list(request.user.unlocked_decks.all()), "page_class": "page-gameboard", }) @login_required(login_url="/") def tarot_fan(request, deck_id): from apps.epic.models import TarotCard deck = get_object_or_404(DeckVariant, pk=deck_id) if not request.user.unlocked_decks.filter(pk=deck_id).exists(): return HttpResponse(status=403) _suit_order = {"WANDS": 0, "CUPS": 1, "SWORDS": 2, "COINS": 3, "PENTACLES": 4} cards = sorted( TarotCard.objects.filter(deck_variant=deck), key=lambda c: (0 if c.arcana == "MAJOR" else 1, _suit_order.get(c.suit or "", 9), c.number), ) return render(request, "apps/gameboard/_partials/_tarot_fan.html", { "deck": deck, "cards": cards, })