import json from django.contrib.auth.decorators import login_required from django.db.models import Max, Q from django.http import JsonResponse from django.shortcuts import redirect, render from apps.applets.utils import applet_context, apply_applet_toggle from apps.dashboard.forms import LineForm from apps.dashboard.models import Post from apps.drama.models import GameEvent, Note, ScrollPosition from apps.epic.models import Room from apps.epic.utils import rooms_for_user def _recent_posts(user, limit=3): return ( Post .objects .filter(Q(owner=user) | Q(shared_with=user)) .annotate(last_line=Max('lines__id')) .order_by('-last_line') .distinct()[:limit] ) @login_required(login_url="/") def billboard(request): my_rooms = rooms_for_user(request.user).order_by("-created_at") recent_room = ( Room.objects.filter( Q(owner=request.user) | Q(gate_slots__gamer=request.user) ) .annotate(last_event=Max("events__timestamp")) .filter(last_event__isnull=False) .order_by("-last_event") .distinct() .first() ) recent_events = ( list( recent_room.events .select_related("actor") .exclude(verb=GameEvent.SIG_UNREADY) .exclude(verb=GameEvent.SIG_READY, data__retracted=True) .order_by("-timestamp")[:36] )[::-1] if recent_room else [] ) return render(request, "apps/billboard/billboard.html", { "my_rooms": my_rooms, "recent_room": recent_room, "recent_events": recent_events, "viewer": request.user, "applets": applet_context(request.user, "billboard"), "form": LineForm(), "recent_posts": _recent_posts(request.user), "page_class": "page-billboard", }) @login_required(login_url="/") def toggle_billboard_applets(request): checked = request.POST.getlist("applets") apply_applet_toggle(request.user, "billboard", checked) if request.headers.get("HX-Request"): return render(request, "apps/billboard/_partials/_applets.html", { "applets": applet_context(request.user, "billboard"), "form": LineForm(), "recent_posts": _recent_posts(request.user), }) return redirect("billboard:billboard") @login_required(login_url="/") def room_scroll(request, room_id): room = Room.objects.get(id=room_id) events = room.events.select_related("actor").all() sp = ScrollPosition.objects.filter(user=request.user, room=room).first() return render(request, "apps/billboard/room_scroll.html", { "room": room, "events": events, "viewer": request.user, "scroll_position": sp.position if sp else 0, "page_class": "page-billscroll", }) _NOTE_META = { "stargazer": { "title": "Stargazer", "description": "You saved your first personal sky chart.", "palette_options": ["palette-bardo", "palette-sheol"], }, "schizo": { "title": "Schizo", "description": "The socius recognizes the line of flight.", "palette_options": [], }, "nomad": { "title": "Nomad", "description": "The socius recognizes the smooth space.", "palette_options": [], }, } @login_required(login_url="/") def note_set_palette(request, slug): from django.http import Http404 from apps.dashboard.views import _unlocked_palettes_for_user try: note = Note.objects.get(user=request.user, slug=slug) except Note.DoesNotExist: raise Http404 if request.method == "POST": body = json.loads(request.body) palette = body.get("palette", "") note.palette = palette note.save(update_fields=["palette"]) # Commit as the user's active sitewide palette now that the Note unlocks it. if palette in _unlocked_palettes_for_user(request.user): request.user.palette = palette request.user.save(update_fields=["palette"]) return JsonResponse({"ok": True}) @login_required(login_url="/") def my_notes(request): qs = Note.objects.filter(user=request.user) note_items = [ { "obj": n, "title": _NOTE_META.get(n.slug, {}).get("title", n.slug), "description": _NOTE_META.get(n.slug, {}).get("description", ""), "palette_options": _NOTE_META.get(n.slug, {}).get("palette_options", []), } for n in qs ] return render(request, "apps/billboard/my_notes.html", { "notes": qs, "note_items": note_items, "page_class": "page-notes", }) @login_required(login_url="/") def save_scroll_position(request, room_id): if request.method != "POST": from django.http import HttpResponseNotAllowed return HttpResponseNotAllowed(["POST"]) room = Room.objects.get(id=room_id) position = int(request.POST.get("position", 0)) ScrollPosition.objects.update_or_create( user=request.user, room=room, defaults={"position": position}, ) from django.http import HttpResponse return HttpResponse(status=204)