emile 9 months ago
parent f57cc83749
commit eaca4a3405

Binary file not shown.

@ -52,23 +52,34 @@ class OsitcomVisitor(WebsocketConsumer):
class OsitcomChatRoom(WebsocketConsumer): class OsitcomChatRoom(WebsocketConsumer):
def connect(self): def connect(self):
self.session_id = self.scope['url_route']['kwargs']['session_id']
self.domain = 'https://osina.ositcom.com' self.domain = 'https://osina.ositcom.com'
self.session_id = self.scope['url_route']['kwargs']['session_id']
self.visitor = Visitor.objects.filter(session_id=self.session_id).last()
if self.scope['url_route']['kwargs'].get('chat_id'): #Case where admin is accessing a specific conversation between the conversations of this visior
self.chat_room = get_object_or_404(ChatRoom, id=self.scope['url_route']['kwargs'].get('chat_id'))
else:
chat_room_guest = ChatRoomGuest.objects.filter(visitor=self.visitor).last() #Case where the visitor will always acesss his last conversation
if chat_room_guest:
self.chat_room = chat_room_guest.room
else:
self.chat_room = None
if self.chat_room:
self.group = f"{self.session_id}_{self.chat_room.id}"
else:
self.group = self.session_id
async_to_sync(self.channel_layer.group_add)( async_to_sync(self.channel_layer.group_add)(
self.session_id, self.channel_name self.group, self.channel_name
) )
self.accept() self.accept()
self.visitor = Visitor.objects.filter(session_id=self.session_id).last()
chat_room_guest = ChatRoomGuest.objects.filter(visitor=self.visitor).last()
if chat_room_guest:
chat_room = chat_room_guest.room
self.chat_room = chat_room
else:
self.chat_room = None
def disconnect(self, close_code): def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)( async_to_sync(self.channel_layer.group_discard)(
self.session_id, self.channel_name self.group, self.channel_name
) )
@ -100,12 +111,19 @@ class OsitcomChatRoom(WebsocketConsumer):
visitor=self.visitor visitor=self.visitor
) )
self.chat_room = chat_room self.chat_room = chat_room
self.group = f"{self.session_id}_{self.chat_room.id}"
event = { event = {
'type': 'start_conversation_handler', 'type': 'start_conversation_handler',
'chat_room_id': chat_room.id 'chat_room_id': chat_room.id
} }
async_to_sync(self.channel_layer.group_discard)(
self.group, self.channel_name
)
async_to_sync(self.channel_layer.group_add)(
self.group, self.channel_name
)
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
if event_type == 'typing': if event_type == 'typing':
@ -115,7 +133,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'typing_status': text_data_json.get('typing_status') 'typing_status': text_data_json.get('typing_status')
} }
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
if event_type == 'send_message': if event_type == 'send_message':
@ -134,7 +152,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'chat_message_id': chat_message.id 'chat_message_id': chat_message.id
} }
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
if event_type == 'uploaded_file': if event_type == 'uploaded_file':
@ -158,7 +176,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'file_name': text_data_json.get('file_name'), 'file_name': text_data_json.get('file_name'),
} }
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
if event_type == 'update_read_messages' and self.chat_room: if event_type == 'update_read_messages' and self.chat_room:
@ -222,7 +240,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'user_id': text_data_json.get('user_id') 'user_id': text_data_json.get('user_id')
} }
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
if event_type == 'submit_review': if event_type == 'submit_review':
@ -244,7 +262,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'review_id': review.id 'review_id': review.id
} }
async_to_sync(self.channel_layer.group_send)( async_to_sync(self.channel_layer.group_send)(
self.session_id, event self.group, event
) )
@ -295,7 +313,7 @@ class OsitcomChatRoom(WebsocketConsumer):
}, cls=DjangoJSONEncoder)) }, cls=DjangoJSONEncoder))
elif self.client_type == 'website_admin': elif self.client_type == 'website_admin':
html = render_to_string("chat_templates/chat-widget.html", context=context) html = render_to_string("chat_templates/chat-room.html", context=context)
self.send(text_data=json.dumps({ self.send(text_data=json.dumps({
'event_type': 'load_chat', 'event_type': 'load_chat',
'html': html, 'html': html,
@ -370,7 +388,7 @@ class OsitcomChatRoom(WebsocketConsumer):
'chat_message_data': chat_message_data, 'chat_message_data': chat_message_data,
},cls=DjangoJSONEncoder)) },cls=DjangoJSONEncoder))
elif self.client_type == 'website_admin': elif self.client_type == 'website_admin':
html = render_to_string("chat_templates/message.html", context=context) html = render_to_string("chat_templates/partials/message.html", context=context)
self.send(text_data=json.dumps({ self.send(text_data=json.dumps({
'event_type': 'send_message', 'event_type': 'send_message',
'html': html, 'html': html,

@ -2,6 +2,7 @@ from django.db import models
from osinacore.models import * from osinacore.models import *
import mimetypes import mimetypes
import os import os
import pycountry
# Create your models here. # Create your models here.
class Visitor(models.Model): class Visitor(models.Model):
@ -11,6 +12,11 @@ class Visitor(models.Model):
name = models.CharField(max_length=200, blank=True, null=True) name = models.CharField(max_length=200, blank=True, null=True)
mobile_number = models.CharField(max_length=10, null=True, blank=True) mobile_number = models.CharField(max_length=10, null=True, blank=True)
email = models.CharField(max_length=100, null=True, blank=True) email = models.CharField(max_length=100, null=True, blank=True)
@property
def flag_image_url(self):
flag_url = f"https://flagcdn.com/w320/{self.country.lower()}.webp"
return flag_url
class VisitorLog(models.Model): class VisitorLog(models.Model):

@ -4,5 +4,6 @@ from .consumers import *
websocket_urlpatterns = [ websocket_urlpatterns = [
path("ws/osichat/visitors/", OsitcomVisitor.as_asgi()), path("ws/osichat/visitors/", OsitcomVisitor.as_asgi()),
path("ws/osichat/<str:session_id>/", OsitcomChatRoom.as_asgi()), path("ws/osichat/<str:session_id>/", OsitcomChatRoom.as_asgi()),
path("ws/osichat-admin/<str:session_id>/<int:chat_id>/", OsitcomChatRoom.as_asgi()),
] ]

@ -1,55 +1,94 @@
{% load static %} {% load static %}
<p id="sessionid" class="hidden">{{guest_session_id}}</p>
<p id="userId" class="hidden">{{request.user.id}}</p>
<div class="w-full h-full flex flex-col justify-end"> <div class="w-full h-full flex flex-col justify-end">
<!-- HEADER --> <!-- HEADER -->
<div class="w-full flex items-center gap-1 py-3 px-3 border-b border-gray-100 text-[17px] text-secondosiblue"> <div class="w-full flex items-center gap-1 py-3 px-3 border-b border-gray-100 text-[17px] text-secondosiblue">
<div class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue"> <div class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" <img class="w-full h-full object-cover rounded-full" src="{{chat_room.chatroomguest.visitor.flag_image_url}}">
stroke="currentColor" class="w-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
</svg>
</div> </div>
<p>{{chat_room.chatroomguest.name}}</p> <p>{{chat_room.chatroomguest.visitor.name}}</p>
</div> </div>
<!-- MESSAGES --> <!-- MESSAGES -->
<div class="flex-1 overflow-y-auto p-3 flex flex-col gap-4" id="messages_container"> <div class="flex-1 overflow-y-auto p-3 flex flex-col gap-4" id="messages_container">
{% for message in chat_messages %} {% for message in chat_room_messages %}
{% if message.member == request.user %} {% if message.member %}
<div class="w-full flex items-end justify-end gap-2"> {% if not message.chatmessageattachment %}
<div <div class="w-full flex justify-end">
class="w-fit px-3 py-2 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue"> <div
<p class="break-all">{{message.content}}</p> class="max-w-[80%] px-4 py-3 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
</div> <p style="white-space: pre-line; overflow-wrap: anywhere;">{{message.content}}</p>
</div>
<div </div>
class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> {% else %}
<p>nn</p> {% if message.chatmessageattachment.is_image %}
</div> <div class="w-full flex justify-end">
</div> <div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
{% else %} <img src="{{domain}}/{{message.chatmessageattachment.attachment}}" class="rounded-md">
<div class="w-full flex items-end justify-start gap-2"> </div>
<div </div>
class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue"> {% else %}
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" <div class="w-full flex justify-end">
stroke="currentColor" class="w-5"> <div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<path stroke-linecap="round" stroke-linejoin="round" <div class="w-full flex items-center gap-1">
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" /> <div>
</svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-5 text-white notFilledSvg">
</div> <path d="M8 7L16 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<div <path d="M8 11L12 11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
class="w-fit bg-gray-50 px-3 py-2 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-7 bg-opacity-50 shadow-md border border-gray-100"> <path d="M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<p class="break-all">{{message.content}}</p> </svg>
</div> </div>
</div> <div class="flex flex-col">
{% endif %} <span class="text-xs">{{message.chatmessageattachment.file_name}}</span>
</div>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% else %}
<div class="w-full flex items-end justify-start gap-2">
<div>
<div
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
<img class="w-full h-full object-cover rounded-full" src="{{chat_room.chatroomguest.visitor.flag_image_url}}">
</div>
</div>
{% if not message.chatmessageattachment %}
<div
class="max-w-[80%] bg-gray-50 px-4 py-3 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<p style="white-space: pre-line; overflow-wrap: anywhere;">{{message.content}}</p>
</div>
{% else %}
{% if message.chatmessageattachment.is_image %}
<div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="{{domain}}/{{message.chatmessageattachment.attachment}}" class="rounded-md">
</div>
{% else %}
<div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<div class="w-full flex items-center gap-1">
<div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-5 text-secondosiblue notFilledSvg">
<path d="M8 7L16 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M8 11L12 11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<div class="flex flex-col">
<span class="text-xs">{{message.chatmessageattachment.file_name}}</span>
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
{% endif %}
{% endfor %} {% endfor %}
<audio id="notification-sound" src="{{domain}}/static/notifications/osichat-notification.mp3" preload="auto"></audio>
<!-- INCLUDE TYPING HERE --> <!-- INCLUDE TYPING HERE -->
<!-- <div class="mb-2 flex justify-start items-center gap-2"> <!-- <div class="mb-2 flex justify-start items-center gap-2">

@ -1,10 +1,10 @@
<p id="userId" class="hidden">{{request.user.id}}</p>
<div class="h-full flex flex-col text-secondosiblue"> <div class="h-full flex flex-col text-secondosiblue">
<!-- CHATS --> <!-- CHATS -->
{% for chat in latest_chat_rooms %} {% for chat in latest_chat_rooms %}
<div class="w-full flex flex-col gap-1 py-3 px-3 border-b border-gray-100 text-sm cursor-pointer" <div class="chat-room w-full flex flex-col gap-1 py-3 px-3 border-b border-gray-100 text-sm cursor-pointer" data-chatid ="{{chat.id}}" data-session="{{chat.chatroomguest.visitor.session_id}}">
data-id="{{chat.id}}" onclick="openConversation({{chat.id}})">
<div class="w-full flex justify-between items-center"> <div class="w-full flex justify-between items-center">
<p class="text-secondosiblue font-poppinsBold">{{chat.chatroomguest.name}}</p> <p class="text-secondosiblue font-poppinsBold">{{chat.chatroomguest.visitor.session_id}}</p>
<div <div
class="w-[20px] h-[20px] bg-osiblue rounded-full shadow-md flex justify-center items-center text-white text-[10px]"> class="w-[20px] h-[20px] bg-osiblue rounded-full shadow-md flex justify-center items-center text-white text-[10px]">

@ -1,36 +0,0 @@
{% if chat_message.member %}
<div class="w-full flex justify-start items-end gap-2 fade-in-up">
<div>
<div
class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if chat_message.member.staffprofile.image %}
<img class="w-full h-full rounded-full"
src="http://192.168.0.100:8000{{chat_message.member.staffprofile.image.url}}">
{% else %}
<p>{{chat_message.member.first_name.0}}{{chat_message.member.last_name.0}}</p>
{% endif %}
</div>
</div>
<div
class="w-fit bg-gray-50 px-3 py-2 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<p class="break-all">{{chat_message.content}}</p>
</div>
</div>
{% else %}
<div class="w-full flex justify-end">
<div
class="w-fit px-3 py-2 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue fade-in-up">
<p class="break-all">{{chat_message.content}}</p>
</div>
</div>
{% endif %}
<style>
@keyframes fadeInAndUp {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0px); }
}
.fade-in-up {
animation: fadeInAndUp 0.6s ease;
}
</style>

@ -0,0 +1,73 @@
{% if chat_message.member %}
{% if not chat_message.chatmessageattachment %}
<div class="w-full flex justify-end">
<div
class="max-w-[80%] px-4 py-3 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<p style="white-space: pre-line; overflow-wrap: anywhere;">{{chat_message.content}}</p>
</div>
</div>
{% else %}
{% if chat_message.chatmessageattachment.is_image %}
<div class="w-full flex justify-end">
<div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<img src="{{domain}}/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md">
</div>
</div>
{% else %}
<div class="w-full flex justify-end">
<div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<div class="w-full flex items-center gap-1">
<div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-5 text-white notFilledSvg">
<path d="M8 7L16 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M8 11L12 11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<div class="flex flex-col">
<span class="text-xs">{{chat_message.chatmessageattachment.file_name}}</span>
</div>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% else %}
<div class="w-full flex items-end justify-start gap-2">
<div>
<div
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
<img class="w-full h-full object-cover rounded-full" src="{{chat_message.room.chatroomguest.visitor.flag_image_url}}">
</div>
</div>
{% if not chat_message.chatmessageattachment %}
<div
class="max-w-[80%] bg-gray-50 px-4 py-3 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<p style="white-space: pre-line; overflow-wrap: anywhere;">{{chat_message.content}}</p>
</div>
{% else %}
{% if chat_message.chatmessageattachment.is_image %}
<div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="{{domain}}/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md">
</div>
{% else %}
<div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<div class="w-full flex items-center gap-1">
<div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-5 text-secondosiblue notFilledSvg">
<path d="M8 7L16 7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M8 11L12 11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M13 21.5V21C13 18.1716 13 16.7574 13.8787 15.8787C14.7574 15 16.1716 15 19 15H19.5M20 13.3431V10C20 6.22876 20 4.34315 18.8284 3.17157C17.6569 2 15.7712 2 12 2C8.22877 2 6.34315 2 5.17157 3.17157C4 4.34314 4 6.22876 4 10L4 14.5442C4 17.7892 4 19.4117 4.88607 20.5107C5.06508 20.7327 5.26731 20.9349 5.48933 21.1139C6.58831 22 8.21082 22 11.4558 22C12.1614 22 12.5141 22 12.8372 21.886C12.9044 21.8623 12.9702 21.835 13.0345 21.8043C13.3436 21.6564 13.593 21.407 14.0919 20.9081L18.8284 16.1716C19.4065 15.5935 19.6955 15.3045 19.8478 14.9369C20 14.5694 20 14.1606 20 13.3431Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<div class="flex flex-col">
<span class="text-xs">{{chat_message.chatmessageattachment.file_name}}</span>
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
{% endif %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@ -1,34 +1,52 @@
const admin_chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; const admin_chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
const protocol = window.location.protocol === "https:" ? "https" : "http";
const admin_chat_domain = "osina.ositcom.com"; const admin_chat_domain = "osina.ositcom.com";
let chatWebSocket = null; let chatWebSocket;
const userId = document.getElementById('userId').textContent.trim();
function openConversation(chatId) { function handleChatRoomClick(event) {
fetch(`/chat-rooms/${chatId}/`) const sessionId = event.currentTarget.getAttribute('data-session');
.then(response => response.text()) const chatId = event.currentTarget.getAttribute('data-chatid');
.then(html => { if (sessionId && chatId) {
const conversationContainer = document.getElementById('inner-conversation') openConversation(sessionId, chatId);
conversationContainer.innerHTML = html; } else {
const guestSessionId = document.getElementById('sessionid').textContent.trim(); console.error('Session ID not found for this chat room.');
const userId = document.getElementById('userId').textContent.trim(); }
// Close the previous WebSocket connection if it exists }
if (chatWebSocket) {
chatWebSocket.close();
}
chatWebSocket = new WebSocket(`${admin_chat_ws_scheme}://${admin_chat_domain}/ws/osichat/${guestSessionId}/`); document.querySelectorAll('.chat-room').forEach(div => {
div.addEventListener('click', handleChatRoomClick);
});
function appendTextAreaScript(domain, conversationContainer) {
if (!document.querySelector(`script[src="${protocol}://${admin_chat_domain}/static/js/osichat-admin/textarea.js"]`)) {
const textareaScript = document.createElement('script');
textareaScript.type = 'text/javascript';
textareaScript.src = `${protocol}://${admin_chat_domain}/static/js/osichat-admin/textarea.js`;
conversationContainer.appendChild(textareaScript);
}
}
chatWebSocket.onopen = function () {
console.log('WebSocket connection to osichat established'); function openConversation(sessionid, chatid) {
chatWebSocket.send(JSON.stringify({ 'event_type': 'load_chat', 'client_type': 'website_admin' })); if (chatWebSocket && chatWebSocket.readyState !== WebSocket.CLOSED) { //Close previous sockets
}; chatWebSocket.close();
}
chatWebSocket = new WebSocket(`${admin_chat_ws_scheme}://${admin_chat_domain}/ws/osichat-admin/${sessionid}/${chatid}/`);
chatWebSocket.onopen = function () {
console.log('WebSocket connection to osichat established');
chatWebSocket.send(JSON.stringify({ 'event_type': 'load_chat', 'client_type': 'website_admin' }));
};
function handleLoadChatEvent(data, chatWebSocket) {
let chatDiv = document.getElementById('inner-conversation');
chatDiv.innerHTML = data.html;
appendTextAreaScript(admin_chat_domain, chatDiv);
const sendMessageForm = document.querySelector('#sendMessage'); const sendMessageForm = document.querySelector('#sendMessage');
sendMessageForm.addEventListener('submit', function (event) { sendMessageForm.addEventListener('submit', function (event) {
event.preventDefault(); event.preventDefault();
const message = event.target.elements.message.value; const message = event.target.elements.message.value;
const eventMessage = { const eventMessage = {
'event_type': 'send_message', 'event_type': 'send_message',
'message': message, 'message': message,
@ -36,32 +54,34 @@ function openConversation(chatId) {
}; };
chatWebSocket.send(JSON.stringify(eventMessage)); chatWebSocket.send(JSON.stringify(eventMessage));
event.target.reset(); event.target.reset();
}); });
}
chatWebSocket.onmessage = function (e) {
const data = JSON.parse(e.data);
switch (data.event_type) {
case 'load_chat':
handleLoadChatEvent(data, chatWebSocket);
break;
case 'send_message':
const messagesDiv = document.getElementById('messages_container');
messagesDiv.insertAdjacentHTML('beforeend', data.html);
if (!data.user) { // If it is sent by a guest play a notification sound for the guest
const notificationSound = document.getElementById('notification-sound');
notificationSound.play();
}
break;
default:
console.log('Unknown event type:', data.event_type);
}
};
chatWebSocket.onclose = function () {
console.log('WebSocket connection to osichat closed');
};
chatWebSocket.onerror = function (error) {
chatWebSocket.onclose = function () { console.error('WebSocket error:', error);
console.log('WebSocket connection to osichat closed'); };
};
chatWebSocket.onerror = function (error) {
console.error('WebSocket error:', error);
};
appendTextAreaScript(admin_chat_domain, conversationContainer);
})
.catch(error => console.error('Error loading conversation details:', error));
}
function appendTextAreaScript(domain, conversationContainer) {
// Check if the script is already appended
if (!document.querySelector('script[src="https://' + domain + '/static/js/osichat-admin/textarea.js"]')) {
const textareaScript = document.createElement('script');
textareaScript.type = 'text/javascript';
textareaScript.src = `https://${domain}/static/js/osichat-admin/textarea.js`;
conversationContainer.appendChild(textareaScript);
}
} }

@ -1,5 +1,6 @@
const chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; const chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
const domain = "osina.ositcom.com"; const protocol = window.location.protocol === "https:" ? "https" : "http";
const domain = "osina.ositcom";
let osichatSocket; let osichatSocket;
let isOpen = false; let isOpen = false;
let chatLoaded = false; let chatLoaded = false;
@ -49,7 +50,7 @@ function hideLoader() {
function appendTextAreaScript(domain, chatDiv) { function appendTextAreaScript(domain, chatDiv) {
const textareaScript = document.createElement('script'); const textareaScript = document.createElement('script');
textareaScript.type = 'text/javascript'; textareaScript.type = 'text/javascript';
textareaScript.src = `https://${domain}/static/js/osichat/textarea.js`; textareaScript.src = `${protocol}://${domain}/static/js/osichat/textarea.js`;
chatDiv.appendChild(textareaScript); chatDiv.appendChild(textareaScript);
} }
@ -91,10 +92,10 @@ function handleLoadChatEvent(data, osichatSocket) {
} }
if (!document.querySelector('script[src="https://' + domain + '/static/js/osichat/chat-toggle.js"]')) { if (!document.querySelector(`script[src="${protocol}://${domain}/static/js/osichat/chat-toggle.js"]`)) {
const script = document.createElement('script'); const script = document.createElement('script');
script.type = 'text/javascript'; script.type = 'text/javascript';
script.src = `https://${domain}/static/js/osichat/chat-toggle.js`; script.src = `${protocol}://${domain}/static/js/osichat/chat-toggle.js`;
chatDiv.appendChild(script); chatDiv.appendChild(script);
} }
@ -110,12 +111,12 @@ function handleLoadChatEvent(data, osichatSocket) {
const uploadScript = document.createElement('script'); const uploadScript = document.createElement('script');
uploadScript.type = 'text/javascript'; uploadScript.type = 'text/javascript';
uploadScript.src = `https://${domain}/static/js/osichat/upload-file.js`; uploadScript.src = `${protocol}://${domain}/static/js/osichat/upload-file.js`;
chatDiv.appendChild(uploadScript); chatDiv.appendChild(uploadScript);
const endChatScript = document.createElement('script'); const endChatScript = document.createElement('script');
endChatScript.type = 'text/javascript'; endChatScript.type = 'text/javascript';
endChatScript.src = `https://${domain}/static/js/osichat/end-chat.js`; endChatScript.src = `${protocol}://${domain}/static/js/osichat/end-chat.js`;
chatDiv.appendChild(endChatScript); chatDiv.appendChild(endChatScript);
const endChatButton = document.getElementById('endChat'); const endChatButton = document.getElementById('endChat');
@ -126,7 +127,7 @@ function handleLoadChatEvent(data, osichatSocket) {
if (sendReviewContainer) { if (sendReviewContainer) {
const sendReviewScript = document.createElement('script'); const sendReviewScript = document.createElement('script');
sendReviewScript.type = 'text/javascript'; sendReviewScript.type = 'text/javascript';
sendReviewScript.src = `https://${domain}/static/js/osichat/send-review.js`; sendReviewScript.src = `${protocol}://${domain}/static/js/osichat/send-review.js`;
chatDiv.appendChild(sendReviewScript); chatDiv.appendChild(sendReviewScript);
} }
} }
@ -202,7 +203,7 @@ async function initializeChatWebSocket() {
unreadMessages.classList.remove('hidden'); unreadMessages.classList.remove('hidden');
unreadMessages.innerHTML = data.html; unreadMessages.innerHTML = data.html;
const script = document.createElement('script'); const script = document.createElement('script');
script.src = `https://${domain}/static/js/osichat/chat-toggle.js`; script.src = `${protocol}://${domain}/static/js/osichat/chat-toggle.js`;
document.body.appendChild(script); document.body.appendChild(script);
} else { } else {
unreadMessages.classList.add('hidden'); unreadMessages.classList.add('hidden');
@ -218,7 +219,7 @@ async function initializeChatWebSocket() {
document.getElementById(`endChat`).classList.add('hidden'); document.getElementById(`endChat`).classList.add('hidden');
const sendReviewScript = document.createElement('script'); const sendReviewScript = document.createElement('script');
sendReviewScript.type = 'text/javascript'; sendReviewScript.type = 'text/javascript';
sendReviewScript.src = `https://${domain}/static/js/osichat/send-review.js`; sendReviewScript.src = `${protocol}://${domain}/static/js/osichat/send-review.js`;
currentChat.appendChild(sendReviewScript); currentChat.appendChild(sendReviewScript);
break; break;
case 'submit_review': case 'submit_review':
@ -228,7 +229,7 @@ async function initializeChatWebSocket() {
} }
const reviewScript = document.createElement('script'); const reviewScript = document.createElement('script');
reviewScript.type = 'text/javascript'; reviewScript.type = 'text/javascript';
reviewScript.src = `https://${domain}/static/js/osichat/send-review.js`; reviewScript.src = `${protocol}://${domain}/static/js/osichat/send-review.js`;
submitReview.appendChild(reviewScript); submitReview.appendChild(reviewScript);
break; break;
default: default:
@ -237,7 +238,6 @@ async function initializeChatWebSocket() {
}; };
osichatSocket.onclose = () => { osichatSocket.onclose = () => {
console.log('WebSocket connection to osichat closed');
showLoader(); showLoader();
setTimeout(() => { setTimeout(() => {
console.log('Attempting to reconnect to WebSocket...'); console.log('Attempting to reconnect to WebSocket...');

Loading…
Cancel
Save