diff --git a/osinaweb/osinacore/templates/chat_templates/partials/rooms.html b/osinaweb/osinacore/templates/chat_templates/partials/rooms.html
index 9be254ca..f48e1fd4 100644
--- a/osinaweb/osinacore/templates/chat_templates/partials/rooms.html
+++ b/osinaweb/osinacore/templates/chat_templates/partials/rooms.html
@@ -1,49 +1,65 @@
-
-
-
-
-
-
+
+
-
-
- {% for chat_room in chat_rooms %}
-
-
-
{{chat_room.chatroomguest.visitor.ip_address}}
-
-
-
{{chat_room.number_of_unread}}
-
-
-
-
{{chat_room.chatmessage_set.all.last.content}}
-
-
{{chat_room.last_updated}}
-
- {% endfor %}
-
\ No newline at end of file
+
+
+
+
+
+ {% for chat_room in chat_rooms %}
+
+
+
{{chat_room.chatroomguest.visitor.ip_address}}
+
+
+
{{chat_room.number_of_unread}}
+
+
+
+
{{chat_room.chatmessage_set.all.last.content}}
+
+
{{chat_room.last_updated}}
+
+ {% endfor %}
+
+
+
\ No newline at end of file
diff --git a/osinaweb/static/dist/output.css b/osinaweb/static/dist/output.css
index 19e48c24..84dfc6cb 100644
--- a/osinaweb/static/dist/output.css
+++ b/osinaweb/static/dist/output.css
@@ -714,6 +714,10 @@ video {
bottom: 4rem;
}
+.bottom-2 {
+ bottom: 0.5rem;
+}
+
.bottom-20 {
bottom: 5rem;
}
@@ -722,10 +726,18 @@ video {
bottom: 6rem;
}
+.bottom-28 {
+ bottom: 7rem;
+}
+
.bottom-3 {
bottom: 0.75rem;
}
+.bottom-32 {
+ bottom: 8rem;
+}
+
.bottom-5 {
bottom: 1.25rem;
}
@@ -842,18 +854,6 @@ video {
top: 14px;
}
-.bottom-2 {
- bottom: 0.5rem;
-}
-
-.bottom-28 {
- bottom: 7rem;
-}
-
-.bottom-32 {
- bottom: 8rem;
-}
-
.z-10 {
z-index: 10;
}
@@ -1103,6 +1103,10 @@ video {
height: 210px;
}
+.h-\[22px\] {
+ height: 22px;
+}
+
.h-\[250px\] {
height: 250px;
}
@@ -1200,10 +1204,6 @@ video {
height: 100vh;
}
-.h-\[22px\] {
- height: 22px;
-}
-
.max-h-\[200px\] {
max-height: 200px;
}
@@ -1332,6 +1332,10 @@ video {
width: 220px;
}
+.w-\[22px\] {
+ width: 22px;
+}
+
.w-\[240px\] {
width: 240px;
}
@@ -1449,10 +1453,6 @@ video {
width: 100%;
}
-.w-\[22px\] {
- width: 22px;
-}
-
.min-w-full {
min-width: 100%;
}
@@ -1843,6 +1843,11 @@ video {
border-top-right-radius: 0px;
}
+.rounded-l {
+ border-top-left-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
+}
+
.rounded-bl-md {
border-bottom-left-radius: 0.375rem;
}
@@ -2196,6 +2201,10 @@ video {
--tw-bg-opacity: 0.8;
}
+.bg-opacity-60 {
+ --tw-bg-opacity: 0.6;
+}
+
.bg-gradient-to-b {
background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
}
@@ -3190,6 +3199,10 @@ video {
}
} */
+.hover\:pointer-events-none:hover {
+ pointer-events: none;
+}
+
.hover\:scale-105:hover {
--tw-scale-x: 1.05;
--tw-scale-y: 1.05;
@@ -3202,6 +3215,10 @@ video {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
+.hover\:overflow-hidden:hover {
+ overflow: hidden;
+}
+
.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
diff --git a/osinaweb/static/js/osichat-admin/inner-conversation.js b/osinaweb/static/js/osichat-admin/inner-conversation.js
index 096611d1..6db0a1e2 100644
--- a/osinaweb/static/js/osichat-admin/inner-conversation.js
+++ b/osinaweb/static/js/osichat-admin/inner-conversation.js
@@ -2,99 +2,154 @@
function handleChatRoomClick(event) {
const sessionId = event.currentTarget.getAttribute('data-session');
const chatId = event.currentTarget.getAttribute('data-roomid');
- if (sessionId && chatId) {
+ if (sessionId && chatId && chatId !== currentChatId) {
+ showLoader();
openConversation(sessionId, chatId);
- } else {
- console.error('Session ID not found for this chat room.');
+ currentChatId = chatId;
}
}
-
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);
+
+ function markCurrentChatRead(chatid) {
+ const unreadElement = document.querySelector(`.unread[data-roomid='${chatid}']`);
+ if (unreadElement) {
+ unreadElement.classList.add('hidden');
}
}
+ // FUNCTIONS TO SHOW & HIDE THE LOADER
+ function showLoader() {
+ const roomLoader = document.getElementById('roomLoader');
+ if (roomLoader) {
+ roomLoader.classList.remove('hidden');
+ }
- function openConversation(sessionid, chatid) {
- if (osichatadminroomSocket && osichatadminroomSocket.readyState !== WebSocket.CLOSED) { //Close previous sockets
- osichatadminroomSocket.close();
- }
- osichatadminroomSocket = new WebSocket(`${admin_chat_ws_scheme}://${admin_chat_domain}/ws/osichat-admin/${sessionid}/${chatid}/`);
- osichatadminroomSocket.onopen = function () {
- console.log('WebSocket connection to osichat established');
- osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'load_chat', 'client_type': 'website_admin' }));
- osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'update_read_messages', 'user_id': userId, 'chat_state': 'open' }));
- };
- function handleLoadChatEvent(data, osichatadminroomSocket) {
- let chatDiv = document.getElementById('widgetRightSide');
- chatDiv.innerHTML = data.html;
- appendTextAreaScript(admin_chat_domain, chatDiv);
-
- const sendMessageForm = document.querySelector('#sendMessage');
- sendMessageForm.addEventListener('submit', function (event) {
- event.preventDefault();
- const message = event.target.elements.message.value;
- const eventMessage = {
- 'event_type': 'send_message',
- 'message': message,
- 'user_id': userId
- };
-
- osichatadminroomSocket.send(JSON.stringify(eventMessage));
- event.target.reset();
- });
- }
+ const widgetLeftSide = document.getElementById('widgetLeftSide');
+ widgetLeftSide.classList.remove('overflow-y-auto');
+ widgetLeftSide.classList.add('overflow-hidden');
+ }
- osichatadminroomSocket.onmessage = function (e) {
- const data = JSON.parse(e.data);
- const typingDiv = document.getElementById('typing');
- const messagesDiv = document.getElementById('messages_container');
- switch (data.event_type) {
- case 'load_chat':
- handleLoadChatEvent(data, osichatadminroomSocket);
- break;
- case 'typing':
- if(!typingDiv && data.user != userId){
- messagesDiv.insertAdjacentHTML('beforeend', data.html);
- }
- break;
- case 'stopped_typing':
+ function hideLoader() {
+ const roomLoader = document.getElementById('roomLoader');
+ if (roomLoader) {
+ roomLoader.classList.add('hidden');
+ }
+
+ const widgetLeftSide = document.getElementById('widgetLeftSide');
+ widgetLeftSide.classList.remove('overflow-hidden');
+ widgetLeftSide.classList.add('overflow-y-auto');
+ }
+
+ function appendTextAreaScript(conversationContainer) {
+ const textareaScript = document.createElement('script');
+ textareaScript.type = 'text/javascript';
+ textareaScript.src = `${protocol}://${admin_chat_domain}/static/js/osichat-admin/textarea.js`;
+ conversationContainer.appendChild(textareaScript);
+ }
+
+ function scrollBottom() {
+ const conversationContainer = document.getElementById('messages_container');
+ if (conversationContainer) {
+ conversationContainer.scrollTo({
+ top: conversationContainer.scrollHeight,
+ behavior: 'smooth'
+ });
+ }
+ }
+
+ function openConversation(sessionId, chatId) {
+ if (osichatadminroomSocket) {
+ osichatadminroomSocket.close();
+ }
+
+ osichatadminroomSocket = new WebSocket(`${admin_chat_ws_scheme}://${admin_chat_domain}/ws/osichat-admin/${sessionId}/${chatId}/`);
+
+ osichatadminroomSocket.onopen = function () {
+ scrollBottom();
+ hideLoader();
+ markCurrentChatRead(chatId)
+ console.log('WebSocket connection to osichat established');
+ osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'load_chat', 'client_type': 'website_admin' }));
+ osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'update_read_messages', 'user_id': userId, 'chat_state': 'open' }));
+ };
+
+ function handleLoadChatEvent(data) {
+ let chatDiv = document.getElementById('widgetRightSide');
+ chatDiv.innerHTML = data.html;
+ appendTextAreaScript(chatDiv);
+
+ const sendMessageForm = document.querySelector('#sendMessage');
+ sendMessageForm.addEventListener('submit', function (event) {
+ event.preventDefault();
+ const message = event.target.elements.message.value;
+ const eventMessage = {
+ 'event_type': 'send_message',
+ 'message': message,
+ 'user_id': userId
+ };
+
+ osichatadminroomSocket.send(JSON.stringify(eventMessage));
+ event.target.reset();
+ });
+ }
+
+ osichatadminroomSocket.onmessage = function (e) {
+ const data = JSON.parse(e.data);
+ const typingDiv = document.getElementById('typing');
+ const messagesDiv = document.getElementById('messages_container');
+ switch (data.event_type) {
+ case 'load_chat':
+ handleLoadChatEvent(data);
+ break;
+ case 'typing':
+ if (!typingDiv && data.user != userId) {
+ messagesDiv.insertAdjacentHTML('beforeend', data.html);
+ }
+ break;
+ case 'stopped_typing':
+ if (typingDiv) {
+ typingDiv.remove();
+ }
+ break;
+ case 'send_message':
+ osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'update_read_messages', 'user_id': userId, 'chat_state': 'open' }));
+ messagesDiv.insertAdjacentHTML('beforeend', data.html);
+ if (!data.user){
if (typingDiv) {
typingDiv.remove();
}
- break;
- case 'send_message':
- osichatadminroomSocket.send(JSON.stringify({ 'event_type': 'update_read_messages', 'user_id': userId, 'chat_state': 'open' }));
- 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();
- if (typingDiv) {
- typingDiv.remove();
- }
- break;
- }
- break;
- default:
- console.log('Unknown event type:', data.event_type);
- }
- };
-
- osichatadminroomSocket.onclose = function () {
- console.log('WebSocket connection to osichat closed');
- };
-
- osichatadminroomSocket.onerror = function (error) {
- console.error('WebSocket error:', error);
- };
+ }
+ break;
+ default:
+ console.log('Unknown event type:', data.event_type);
+ }
+ };
+
+ osichatadminroomSocket.onclose = function () {
+ console.log('WebSocket connection closed');
+ if (currentChatId === chatId) {
+ setTimeout(() => {
+ console.log('Attempting to reconnect to WebSocket...');
+ openConversation(sessionId, chatId);
+ }, 2000);
+ }
+ };
+
+ osichatadminroomSocket.onerror = function (error) {
+ console.error('WebSocket error:', error);
+ showLoader();
+ };
}
-})();
\ No newline at end of file
+
+ window.addEventListener('offline', () => {
+ showLoader();
+ if (osichatadminroomSocket) {
+ osichatadminroomSocket.close();
+ }
+ });
+
+})();
diff --git a/osinaweb/static/js/osichat-admin/rooms.js b/osinaweb/static/js/osichat-admin/rooms.js
index 1ddea089..28174bbe 100644
--- a/osinaweb/static/js/osichat-admin/rooms.js
+++ b/osinaweb/static/js/osichat-admin/rooms.js
@@ -2,8 +2,24 @@ let admin_chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
let protocol = window.location.protocol === "https:" ? "https" : "http";
let admin_chat_domain = "osina.ositcom.com";
let userId = document.getElementById('userId').textContent.trim();
-let osichatroomsSocket;
-let osichatadminroomSocket;
+let osichatadminroomSocket = null;
+let currentChatId = null;
+
+// FUNCTIONS TO SHOW & HIDE THE LOADER
+function showLoader() {
+ const roomsLoader = document.getElementById('roomsLoader');
+ if (roomsLoader) {
+ roomsLoader.classList.remove('hidden');
+ }
+}
+
+function hideLoader() {
+ const roomsLoader = document.getElementById('roomsLoader');
+ if (roomsLoader) {
+ roomsLoader.classList.add('hidden');
+ }
+}
+
function appendInnerConversationScript(div) {
const innerConversationScript = document.createElement('script');
@@ -12,11 +28,16 @@ function appendInnerConversationScript(div) {
div.appendChild(innerConversationScript);
}
+
+
+
+
function getRooms(){
osichatroomsSocket = new WebSocket(`${admin_chat_ws_scheme}://${admin_chat_domain}/ws/osichat/rooms/`);
osichatroomsSocket.onopen = function () {
console.log('WebSocket connection to rooms established');
+ hideLoader();
osichatroomsSocket.send(JSON.stringify({
'event_type': 'set_client_type',
'client_type': 'website_admin',
@@ -39,11 +60,34 @@ function getRooms(){
if (chatRoomDiv) {
chatRoomDiv.remove(); // Remove the existing chat room div
}
+
// Insert the new chat room HTML at the top of the container
const newChatRoomDiv = document.createElement('div');
newChatRoomDiv.innerHTML = data.html;
roomsContainer.insertAdjacentElement('afterbegin', newChatRoomDiv.firstElementChild);
+ if (parseInt(currentChatId) === parseInt(data.chatroom_id)) {
+ const unreadIndicator = roomsContainer.querySelector(`.unread[data-roomid='${data.chatroom_id}']`);
+ if (unreadIndicator) {
+ unreadIndicator.classList.add('hidden');
+ }
+ 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();
+
+ }
+ } else {
+ const unreadIndicator = roomsContainer.querySelector(`.unread[data-roomid='${data.chatroom_id}']`);
+ if (unreadIndicator) {
+ unreadIndicator.classList.remove('hidden');
+ }
+ 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();
+ }
+ }
+
+
appendInnerConversationScript(leftDiv);
break;
@@ -53,12 +97,25 @@ function getRooms(){
};
osichatroomsSocket.onclose = function () {
- console.log('WebSocket connection to rooms closed');
+ showLoader();
+ setTimeout(() => {
+ console.log('Attempting to reconnect to WebSocket...');
+ getRooms();
+ }, 2000);
};
osichatroomsSocket.onerror = function (error) {
+ showLoader();
console.error('WebSocket error:', error);
};
+
+ window.addEventListener('offline', () => {
+ showLoader();
+ if (osichatroomsSocket) {
+ osichatroomsSocket.close();
+ }
+ });
+
}
getRooms();
\ No newline at end of file
diff --git a/osinaweb/static/js/osichat-admin/textarea.js b/osinaweb/static/js/osichat-admin/textarea.js
index 066ed475..c8840d12 100644
--- a/osinaweb/static/js/osichat-admin/textarea.js
+++ b/osinaweb/static/js/osichat-admin/textarea.js
@@ -1,12 +1,14 @@
(function() {
// FUNCTION TO ADJUST TEXTAREA HEIGHT AND SUBMIT BUTTON VISIBILITY
function adjustTextAreaAndButton(textarea, submitButton) {
+ // Adjust the height of the textarea
if (textarea.value.trim() === '') {
textarea.style.height = '50px';
} else {
textarea.style.height = textarea.scrollHeight + 'px';
}
+ // Display and hide the submit button
if (textarea.value.trim() === '') {
submitButton.classList.add('hidden');
} else {
@@ -14,10 +16,21 @@
}
}
+ function scrollBottom() {
+ const conversationContainer = document.getElementById('messages_container');
+
+ if (conversationContainer) {
+ conversationContainer.scrollTo({
+ top: conversationContainer.scrollHeight,
+ behavior: 'smooth'
+ });
+ }
+ }
+
+
// INITIALIZE ELEMENTS
const form = document.querySelector('#sendMessage');
const textarea = document.querySelector('#dynamicTextarea');
- const conversationContainer = document.getElementById('conversation');
const submitButton = document.getElementById('submitMessageButton');
const typingUserId = document.getElementById('userId').textContent.trim();
let typingTimeout;
@@ -54,8 +67,18 @@
submitButton.classList.add('hidden');
setTimeout(() => {
- conversationContainer.scrollTop = conversationContainer.scrollHeight;
+ scrollBottom();
}, 100);
});
+ textarea.addEventListener('keydown', (event) => {
+ if (event.key === 'Enter' && !event.shiftKey) {
+ event.preventDefault();
+ if (!submitButton.classList.contains('hidden')) {
+ submitButton.click();
+ }
+ scrollBottom();
+ }
+ });
+
})();
diff --git a/osinaweb/static/js/osichat/textarea.js b/osinaweb/static/js/osichat/textarea.js
index 55aaead6..b177b473 100644
--- a/osinaweb/static/js/osichat/textarea.js
+++ b/osinaweb/static/js/osichat/textarea.js
@@ -18,15 +18,19 @@
function scrollBottom() {
const conversationContainer = document.getElementById('conversation');
- conversationContainer.scrollTop = conversationContainer.scrollHeight;
+
+ if (conversationContainer) {
+ conversationContainer.scrollTo({
+ top: conversationContainer.scrollHeight,
+ behavior: 'smooth'
+ });
+ }
}
-
// INITIALIZE ELEMENTS
const form = document.querySelector('#sendMessage');
const textarea = document.querySelector('#dynamicTextarea');
- const conversationContainer = document.getElementById('conversation');
const submitButton = document.getElementById('submitMessageButton');
let typingTimeout;
let isTyping = false;