94 lines
3 KiB
Python
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)
|