chat/apps/chat/views/conversations.py
2026-06-15 13:21:21 +03:30

94 lines
3 KiB
Python

from uuid import UUID
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from apps.chat.models import ConversationParticipant
from apps.chat.serializers.conversations import (
ConversationListSerializer,
ConversationSerializer,
CreateConversationSerializer,
)
from apps.chat.services.conversation import ConversationService
from apps.chat.services.message import MessageService
from apps.chat.services.read_state import ReadStateService
class ConversationCreateView(APIView):
authentication_classes = []
permission_classes = []
@extend_schema(
request=CreateConversationSerializer,
responses={201: ConversationSerializer},
)
def post(self, request):
serializer = CreateConversationSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
conversation = ConversationService().create(
serializer.validated_data["user_1_id"],
serializer.validated_data["user_2_id"],
)
return Response(
ConversationSerializer(conversation).data,
status=status.HTTP_201_CREATED,
)
class UserConversationListView(APIView):
authentication_classes = []
permission_classes = []
@extend_schema(
parameters=[
OpenApiParameter("page", int, description="0-based page number", default=0),
OpenApiParameter("page_size", int, description="Results per page", default=20),
],
responses={200: ConversationListSerializer(many=True)},
)
def get(self, request, user_id):
uid = UUID(str(user_id))
page = int(request.query_params.get("page", 0))
page_size = int(request.query_params.get("page_size", 20))
conv_svc = ConversationService()
read_svc = ReadStateService()
msg_svc = MessageService()
conversations = conv_svc.list_for_user(uid, page, page_size)
result = []
for conv in conversations:
participants = list(
ConversationParticipant.objects.filter(conversation_id=conv.id)
.order_by("joined_at")
.values_list("user_id", flat=True)
)
try:
has_unread = read_svc.has_unread(conv.id, uid)
except Exception:
has_unread = False
try:
last_msgs = msg_svc.list_messages(conv.id, page=0, per_page=1)
last_message = last_msgs[0] if last_msgs else None
except Exception:
last_message = None
result.append(
{
"id": conv.id,
"type": conv.type,
"created_at": conv.created_at,
"participants": participants,
"has_unread": has_unread,
"last_message": last_message,
}
)
return Response(ConversationListSerializer(result, many=True).data)