// Function to delete message async function deleteMessage(messageId, forEveryone) { try { const response = await fetch("/api/delete-message", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${currentToken}`, }, body: JSON.stringify({ message_id: messageId, for_everyone: forEveryone, }), }); const data = await response.json(); if (data.success) { console.log(`✅ Message deleted: ${data.message}`); showAlert(data.message, "success"); // Remove message from UI const messageElement = document.querySelector( `[data-message-id="${messageId}"]`, ); if (messageElement) { messageElement.remove(); } // Update chat history if (messageHistory[currentRecipient]) { messageHistory[currentRecipient] = messageHistory[ currentRecipient ].filter((msg) => msg.id !== messageId); } // Reload chats to update last message loadChats(); } else { console.error("❌ Failed to delete message:", data.message); showAlert(data.message, "error"); } } catch (error) { console.error("❌ Error deleting message:", error); showAlert("Error deleting message", "error"); } } // Function to mark messages as read async function markMessagesAsRead(fromUser) { try { const response = await fetch("/api/mark-read", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${currentToken}`, }, body: JSON.stringify({ from_user: fromUser, to_user: currentUser, }), }); const data = await response.json(); if (data.success) { console.log(`✅ Marked messages as read from ${fromUser}`); // Обновляем список чатов чтобы убрать красный badge loadChats(); } else { console.error("❌ Failed to mark messages as read:", data.error); } } catch (error) { console.error("❌ Error marking messages as read:", error); } } function deleteMessageForMe() { if (messageToDelete) { deleteMessage(messageToDelete, false); closeDeleteModal(); } } function deleteMessageForEveryone() { if (messageToDelete) { deleteMessage(messageToDelete, true); closeDeleteModal(); } } function handleChatMessage(msg) { console.log("Handling chat message:", msg); const otherUser = msg.from_user === currentUser ? msg.to_user : msg.from_user; if (!messageHistory[otherUser]) { messageHistory[otherUser] = []; } const messageExists = messageHistory[otherUser].some( (existingMsg) => existingMsg.id === msg.id, ); if (!messageExists) { messageHistory[otherUser].push(msg); } loadChats(); if (otherUser === currentRecipient) { displayMessage(msg, true); // Если сообщение пришло в открытый чат, сразу помечаем как прочитанное if (msg.from_user === currentRecipient) { markMessagesAsRead(currentRecipient); } } } function displayMessage(msg, scrollToBottom) { const chatMessages = document.getElementById("chatMessages"); // Remove empty state if it exists const emptyState = chatMessages.querySelector(".empty-state"); if (emptyState) { emptyState.remove(); } const messageDiv = document.createElement("div"); messageDiv.className = `message ${msg.from_user === currentUser ? "outgoing" : "incoming"}`; messageDiv.setAttribute("data-message-id", msg.id); if (msg.message_type === "system") { messageDiv.className = "system-message"; messageDiv.textContent = msg.content; } else { const isOutgoing = msg.from_user === currentUser; if (!isOutgoing) { const senderDiv = document.createElement("div"); senderDiv.className = "message-sender"; senderDiv.textContent = msg.from_user; messageDiv.appendChild(senderDiv); } const contentDiv = document.createElement("div"); contentDiv.className = "message-content"; contentDiv.textContent = msg.content; messageDiv.appendChild(contentDiv); const timeDiv = document.createElement("div"); timeDiv.className = "message-time"; const date = new Date(msg.timestamp); timeDiv.textContent = date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", }); messageDiv.appendChild(timeDiv); // Add delete button for user's own messages or all messages if (msg.from_user === currentUser) { const actionsDiv = document.createElement("div"); actionsDiv.className = "message-actions"; const deleteBtn = document.createElement("button"); deleteBtn.className = "delete-btn"; deleteBtn.innerHTML = "×"; deleteBtn.title = "Delete message"; deleteBtn.onclick = (e) => { console.log("delete message button clicked"); e.stopPropagation(); showDeleteModal(msg.id); }; actionsDiv.appendChild(deleteBtn); messageDiv.appendChild(actionsDiv); } } chatMessages.appendChild(messageDiv); console.log("message added"); if (scrollToBottom) { setTimeout(() => { chatMessages.scrollTop = chatMessages.scrollHeight; }, 100); } } function addSystemMessage(content) { const chatMessages = document.getElementById("chatMessages"); // Remove empty state if it exists const emptyState = chatMessages.querySelector(".empty-state"); if (emptyState) { emptyState.remove(); } const systemDiv = document.createElement("div"); systemDiv.className = "system-message"; systemDiv.textContent = content; chatMessages.appendChild(systemDiv); setTimeout(() => { chatMessages.scrollTop = chatMessages.scrollHeight; }, 100); } function sendMessage() { if (!ws || ws.readyState !== WebSocket.OPEN) { showAlert("Please connect to the server first", "error"); return; } if (!currentRecipient) { showAlert("Please select a user to chat with", "error"); return; } const input = document.getElementById("messageInput"); const content = input.value.trim(); if (!content) return; const message = { id: generateId(), from_user: currentUser, to_user: currentRecipient, content: content, timestamp: Date.now(), message_type: "text", }; console.log("Sending message:", message); ws.send(JSON.stringify(message)); input.value = ""; input.style.height = "auto"; setTimeout(() => loadChats(), 100); } // Event listeners document .getElementById("messageInput") .addEventListener("keydown", function (e) { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendMessage(); } });