diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 22f14596..7afb0d59 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc b/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc index 05c5bf67..36f754d5 100644 Binary files a/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc and b/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc differ diff --git a/osinaweb/osichat/__pycache__/models.cpython-310.pyc b/osinaweb/osichat/__pycache__/models.cpython-310.pyc index 9e749c37..bc9650cf 100644 Binary files a/osinaweb/osichat/__pycache__/models.cpython-310.pyc and b/osinaweb/osichat/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osichat/__pycache__/routing.cpython-310.pyc b/osinaweb/osichat/__pycache__/routing.cpython-310.pyc index 2f3edad4..7f41bd73 100644 Binary files a/osinaweb/osichat/__pycache__/routing.cpython-310.pyc and b/osinaweb/osichat/__pycache__/routing.cpython-310.pyc differ diff --git a/osinaweb/osichat/api/__pycache__/serializers.cpython-310.pyc b/osinaweb/osichat/api/__pycache__/serializers.cpython-310.pyc index 6c2b519f..e1fe162b 100644 Binary files a/osinaweb/osichat/api/__pycache__/serializers.cpython-310.pyc and b/osinaweb/osichat/api/__pycache__/serializers.cpython-310.pyc differ diff --git a/osinaweb/osichat/api/serializers.py b/osinaweb/osichat/api/serializers.py index 1655e754..80c5651a 100644 --- a/osinaweb/osichat/api/serializers.py +++ b/osinaweb/osichat/api/serializers.py @@ -2,7 +2,14 @@ from osichat.models import * from rest_framework import serializers +class VisitorSerializer(serializers.ModelSerializer): + class Meta: + model = Visitor + fields = '__all__' + + class ChatRoomGuestSerializer(serializers.ModelSerializer): + visitor = VisitorSerializer() class Meta: model = ChatRoomGuest fields = '__all__' diff --git a/osinaweb/osichat/consumers.py b/osinaweb/osichat/consumers.py index 95f0544c..1d33f8ff 100644 --- a/osinaweb/osichat/consumers.py +++ b/osinaweb/osichat/consumers.py @@ -49,10 +49,83 @@ class OsitcomVisitor(WebsocketConsumer): +class OsitcomChatRooms(WebsocketConsumer): + def connect(self): + async_to_sync(self.channel_layer.group_add)( + 'ositcom_chats', self.channel_name + ) + self.accept() + + def disconnect(self, close_code): + async_to_sync(self.channel_layer.group_discard)( + 'ositcom_chats', self.channel_name + ) + + def receive(self, text_data): + data = json.loads(text_data) + event_type = data.get('event_type') + + if event_type == 'set_client_type': + self.client_type = data.get('client_type') + self.user_id = data.get('user_id') + self.get_chats_handler() + + + def get_chats_handler(self): + chat_rooms = ChatRoom.objects.annotate(last_update=Max('chatmessage__date_sent')).order_by('-last_update', '-date_created') + user = get_object_or_404(User, id=self.user_id) + for room in chat_rooms: + room.number_of_unread = room.unread_messages(user) + context = { + 'chat_rooms': chat_rooms, + } + + if self.client_type == 'mobile_admin': + chat_rooms_data = [model_to_dict(chat_room) for chat_room in chat_rooms] + self.send(text_data=json.dumps({ + 'event_type': 'get_chats', + 'chat_rooms_data': chat_rooms_data, + }, cls=DjangoJSONEncoder)) + else: + html = render_to_string("chat_templates/partials/rooms.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'get_chats', + 'html': html, + })) + + + def new_update_handler(self, event): + chat_room = get_object_or_404(ChatRoom, id=event['chatroom_id']) + user = get_object_or_404(User, id=self.user_id) + number_of_unread = ChatMessage.objects.filter(room=chat_room).exclude(member=user).exclude(chatmessageseen__member=user).count() + + context = { + 'chat_room': chat_room, + 'number_of_unread': number_of_unread + } + if self.client_type == 'mobile_admin': + chat_room_data = model_to_dict(chat_room) + self.send(text_data=json.dumps({ + 'event_type': 'new_update', + 'chat_room_data': chat_room_data, + }, cls=DjangoJSONEncoder)) + else: + html = render_to_string("chat_templates/partials/new-chat-room.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'new_update', + 'chatroom_id': chat_room.id, + 'html': html, + })) + + + + + + class OsitcomChatRoom(WebsocketConsumer): def connect(self): - self.domain = 'https://osina.ositcom.com' + self.domain = 'http://192.168.1.111:8000' self.session_id = self.scope['url_route']['kwargs']['session_id'] self.visitor = Visitor.objects.filter(session_id=self.session_id).last() @@ -201,7 +274,7 @@ class OsitcomChatRoom(WebsocketConsumer): ) number_of_unread = 0 else: - number_of_unread = ChatMessage.objects.filter(room=self.chat_room).exclude(member = member, chatmessageseen__member=member).count() + number_of_unread = ChatMessage.objects.filter(room=self.chat_room).exclude(member = member).exclude(hatmessageseen__member=member).count() latest_unread_message = ChatMessage.objects.filter(room=self.chat_room).exclude(chatmessageseen__member=member).last() else: member = None @@ -334,6 +407,7 @@ class OsitcomChatRoom(WebsocketConsumer): 'html': html, })) + def start_conversation_handler(self, event): chat_room = get_object_or_404(ChatRoom, id=event['chat_room_id']) context = { @@ -353,6 +427,7 @@ class OsitcomChatRoom(WebsocketConsumer): 'html': html, })) + def typing_handler(self, event): if event.get('typing_status') == 'typing': if event.get('user_id'): @@ -362,19 +437,37 @@ class OsitcomChatRoom(WebsocketConsumer): context = { 'member': member, + 'chat_room': self.chat_room, 'domain': self.domain } - - html = render_to_string("partials/typing.html", context=context) - self.send(text_data=json.dumps({ - 'event_type': 'typing', - 'html': html, - })) + if self.client_type == 'mobile_admin': + member_data = None + if member: + member_data = model_to_dict(member) + self.send(text_data=json.dumps({ + 'event_type': 'typing', + 'member_data': member_data, + }, cls=DjangoJSONEncoder)) + elif self.client_type == 'website_admin': + html = render_to_string("chat_templates/partials/typing.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'typing', + 'user': member.id if member else None, + 'html': html, + })) + else: + html = render_to_string("partials/typing.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'typing', + 'user': member.id if member else None, + 'html': html, + })) else: self.send(text_data=json.dumps({ 'event_type': 'stopped_typing', })) + def send_message_handler(self, event): chat_message = get_object_or_404(ChatMessage, id=event['chat_message_id']) context = { @@ -391,6 +484,7 @@ class OsitcomChatRoom(WebsocketConsumer): html = render_to_string("chat_templates/partials/message.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'send_message', + 'user': chat_message.member.id if chat_message.member else None, 'html': html, })) else: @@ -401,6 +495,7 @@ class OsitcomChatRoom(WebsocketConsumer): 'html': html, })) + def uploaded_file_handler(self, event): message_attachment = get_object_or_404(ChatMessageAttachment, id=event['message_attachment_id']) context = { @@ -425,6 +520,7 @@ class OsitcomChatRoom(WebsocketConsumer): 'html': html, })) + def update_read_messages_handler(self, event): latest_unread_message_id = event.get('latest_unread_message_id') if latest_unread_message_id: @@ -434,14 +530,21 @@ class OsitcomChatRoom(WebsocketConsumer): 'latest_unread_message': latest_unread_message, 'domain': self.domain } - html = render_to_string("partials/unread-messages.html", context=context) - self.send(text_data=json.dumps({ - 'event_type': 'update_read_messages', - 'html': html, - })) + if self.client_type == 'mobile_admin': + self.send(text_data=json.dumps({ + 'event_type': 'update_read_messages', + 'number_of_unread': event['number_of_unread'], + },cls=DjangoJSONEncoder)) + else: + html = render_to_string("partials/unread-messages.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'update_read_messages', + 'html': html, + })) else: latest_unread_message = None + def end_chat_handler(self, event): if event['user_id']: member = get_object_or_404(User, id=event['user_id']) diff --git a/osinaweb/osichat/models.py b/osinaweb/osichat/models.py index d625ad30..9d4587f2 100644 --- a/osinaweb/osichat/models.py +++ b/osinaweb/osichat/models.py @@ -2,6 +2,9 @@ from django.db import models from osinacore.models import * import mimetypes import os +from channels.layers import get_channel_layer +from asgiref.sync import async_to_sync +import json # Create your models here. @@ -46,6 +49,20 @@ class ChatRoom(models.Model): return last_updated_time.strftime('%I:%M %p') else: return last_updated_time.strftime('%d-%m-%Y') + def unread_messages(self, user): + return ChatMessage.objects.filter(room=self).exclude(member=user).exclude(chatmessageseen__member=user).count() + + + def save(self, *args, **kwargs): + is_new = self.pk is None + super().save(*args, **kwargs) + channel_layer = get_channel_layer() + event = { + 'type': 'new_update_handler', + 'chatroom_id': self.id, + } + async_to_sync(channel_layer.group_send)("ositcom_chats", event) + class ChatRoomGuest(models.Model): @@ -80,6 +97,15 @@ class ChatMessage(models.Model): member = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, blank=True) content = models.TextField(null=True, blank=True) date_sent = models.DateTimeField() + def save(self, *args, **kwargs): + is_new = self.pk is None + super().save(*args, **kwargs) + channel_layer = get_channel_layer() + event = { + 'type': 'new_update_handler', + 'chatroom_id': self.room.id, + } + async_to_sync(channel_layer.group_send)("ositcom_chats", event) class ChatMessageAttachment(models.Model): diff --git a/osinaweb/osichat/routing.py b/osinaweb/osichat/routing.py index 2a833e40..05e2bcb1 100644 --- a/osinaweb/osichat/routing.py +++ b/osinaweb/osichat/routing.py @@ -3,6 +3,7 @@ from .consumers import * websocket_urlpatterns = [ path("ws/osichat/visitors/", OsitcomVisitor.as_asgi()), + path("ws/osichat/rooms/", OsitcomChatRooms.as_asgi()), path("ws/osichat//", OsitcomChatRoom.as_asgi()), path("ws/osichat-admin///", OsitcomChatRoom.as_asgi()), diff --git a/osinaweb/osichat/templates/chat-room.html b/osinaweb/osichat/templates/chat-room.html index f4f31c84..cbd4df33 100644 --- a/osinaweb/osichat/templates/chat-room.html +++ b/osinaweb/osichat/templates/chat-room.html @@ -4,6 +4,16 @@
+ +
@@ -126,8 +136,6 @@
- -
diff --git a/osinaweb/osichat/templates/partials/typing.html b/osinaweb/osichat/templates/partials/typing.html index ec7bc9ac..c1819f56 100644 --- a/osinaweb/osichat/templates/partials/typing.html +++ b/osinaweb/osichat/templates/partials/typing.html @@ -1,12 +1,7 @@ -
+
- {% if member.staffprofile.image %} - - {% else %} -

{{member.first_name.0}}{{member.last_name.0}}

- {% endif %} + class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> +
diff --git a/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc b/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc index 89064394..ef3d110e 100644 Binary files a/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc differ diff --git a/osinaweb/osinacore/custom_context.py b/osinaweb/osinacore/custom_context.py index 0a1f0278..d9205367 100644 --- a/osinaweb/osinacore/custom_context.py +++ b/osinaweb/osinacore/custom_context.py @@ -9,8 +9,6 @@ from osichat.models import * def utilities(request): - # Combine protocol and domain - current_url = 'https://osina.ositcom.com' notes = None recent_note = None @@ -123,5 +121,5 @@ def utilities(request): 'closed_tickets': closed_tickets, 'today': today, 'latest_chat_rooms': latest_chat_rooms, - 'current_url': current_url + } \ No newline at end of file diff --git a/osinaweb/osinacore/templates/chat_templates/chat-room.html b/osinaweb/osinacore/templates/chat_templates/chat-room.html index 2173e094..571ac787 100644 --- a/osinaweb/osinacore/templates/chat_templates/chat-room.html +++ b/osinaweb/osinacore/templates/chat_templates/chat-room.html @@ -89,22 +89,7 @@ - - - - +
diff --git a/osinaweb/osinacore/templates/chat_templates/chat-widget.html b/osinaweb/osinacore/templates/chat_templates/chat-widget.html index 554975d3..300c427e 100644 --- a/osinaweb/osinacore/templates/chat_templates/chat-widget.html +++ b/osinaweb/osinacore/templates/chat_templates/chat-widget.html @@ -1,47 +1,14 @@ {% load static %} +