From 712448b1c5e482c4a968041ca1f646c6f9ba7513 Mon Sep 17 00:00:00 2001 From: inmake Date: Fri, 31 Oct 2025 14:40:49 +0500 Subject: [PATCH] Refactor ChatPopup to update WebRTC userId upon authentication, enhance identifier logic for message comparison, and localize guest label. Update useWebRTC to include userId update function and adjust API request headers for guestId handling based on authentication status. --- client/src/components/popups/ChatPopup.tsx | 22 ++++++++++++++++------ client/src/hooks/useWebRTC.ts | 6 ++++++ client/src/lib/api.ts | 8 ++++---- client/src/lib/webrtc.ts | 13 ++++++++++++- client/src/pages/SessionPage.tsx | 5 +++++ server/.env | 2 ++ server/src/index.ts | 10 ++++++---- 7 files changed, 51 insertions(+), 15 deletions(-) diff --git a/client/src/components/popups/ChatPopup.tsx b/client/src/components/popups/ChatPopup.tsx index 0081a1b..0af78df 100644 --- a/client/src/components/popups/ChatPopup.tsx +++ b/client/src/components/popups/ChatPopup.tsx @@ -22,17 +22,27 @@ export default function ChatPopup({ sessionId: sessionIdProp }: ChatPopupProps = chatMessages: realtimeMessages, sendMessage, currentUserId, + updateUserId, } = useWebRTC(); - // Получаем данные текущего пользователя (если авторизован) + // Получаем данные текущего пользователя + // React Query кэширует результат, поэтому множественные вызовы useMe() не приводят к множественным запросам const { data: user } = useMe(); - // currentUserId содержит либо userId (если авторизован), либо guestId (если гость) - // Это и есть наш идентификатор для сравнения с senderId в сообщениях - const myIdentifier = currentUserId; + // Обновляем userId в WebRTC сервисе при авторизации + useEffect(() => { + if (user?.id && updateUserId) { + console.log("[ChatPopup] User authenticated, updating WebRTC userId to:", user.id); + updateUserId(user.id); + } + }, [user?.id, updateUserId]); + + // Определяем идентификатор для сравнения с senderId в сообщениях + // Приоритет: реальный userId (если авторизован), затем currentUserId (guestId) + const myIdentifier = user?.id || currentUserId; console.log("[ChatPopup] Rendering with sessionId:", sessionId); - console.log("[ChatPopup] My identifier:", myIdentifier, "isAuthenticated:", !!user); + console.log("[ChatPopup] My identifier:", myIdentifier, "isAuthenticated:", !!user, "user.id:", user?.id, "currentUserId:", currentUserId); // Загружаем историю через REST API const { data: historyMessages = [], isLoading, error } = useChatHistory(sessionId); @@ -209,7 +219,7 @@ function MessageItem({
{!isFromMe && (
- {senderName || "Guest"} + {senderName || "Гость"}
)}
{content}
diff --git a/client/src/hooks/useWebRTC.ts b/client/src/hooks/useWebRTC.ts index d725cbb..5eda96e 100644 --- a/client/src/hooks/useWebRTC.ts +++ b/client/src/hooks/useWebRTC.ts @@ -225,6 +225,11 @@ export const useWebRTC = (roomId?: string, autoJoin = false) => { webrtcServiceInstance.updateSpeakingState(isSpeaking); }; + const updateUserId = (newUserId: string) => { + if (!webrtcServiceInstance) return; + webrtcServiceInstance.updateUserId(newUserId); + }; + return { localStream, participants, @@ -238,6 +243,7 @@ export const useWebRTC = (roomId?: string, autoJoin = false) => { toggleVideo, sendMessage, updateSpeakingState, + updateUserId, joinRoom, leaveRoom, }; diff --git a/client/src/lib/api.ts b/client/src/lib/api.ts index b5ba18a..d0e924a 100644 --- a/client/src/lib/api.ts +++ b/client/src/lib/api.ts @@ -15,11 +15,11 @@ export const api = ky.create({ if (token) { request.headers.set("Authorization", `Bearer ${token}`); + } else { + // Добавляем guestId только если пользователь НЕ авторизован + const guestId = getOrCreateGuestId(); + request.headers.set("X-Guest-Id", guestId); } - - // Автоматически добавляем guestId для всех запросов - const guestId = getOrCreateGuestId(); - request.headers.set("X-Guest-Id", guestId); }, ], }, diff --git a/client/src/lib/webrtc.ts b/client/src/lib/webrtc.ts index b47f7e8..65dd3d1 100644 --- a/client/src/lib/webrtc.ts +++ b/client/src/lib/webrtc.ts @@ -146,6 +146,12 @@ export function createWebRTCService(callbacks: WebRTCCallbacks = {}) { leaveRoom, sendChatMessage, updateSpeakingState, + updateUserId: (newUserId: string) => { + if (state) { + console.log("[WebRTC] Updating userId from", state.userId, "to", newUserId); + state.userId = newUserId; + } + }, getChatMessages: () => state?.chatMessages || [], getCurrentUserId: () => state?.userId || "", getParticipants: () => Array.from(state?.participants.values() || []), @@ -856,11 +862,16 @@ function sendChatMessage(content: string, senderName?: string, isAuthenticated?: if (!state || !content.trim() || !state.roomId) return; console.log("📤 Sending message via Socket.IO:", content); + console.log("📤 isAuthenticated:", isAuthenticated, "state.userId:", state.userId); - // Определяем userId и guestId + // Определяем userId и guestId на основе реальной авторизации + // Если пользователь авторизован, state.userId содержит настоящий userId + // Если нет - state.userId содержит guestId const userId = isAuthenticated ? state.userId : null; const guestId = !isAuthenticated ? state.userId : null; + console.log("📤 Sending with userId:", userId, "guestId:", guestId); + // Отправляем сообщение через Socket.IO state.socket.emit("chat-message", { roomId: state.roomId, diff --git a/client/src/pages/SessionPage.tsx b/client/src/pages/SessionPage.tsx index 32a4361..38d9efc 100644 --- a/client/src/pages/SessionPage.tsx +++ b/client/src/pages/SessionPage.tsx @@ -27,10 +27,15 @@ import { useWebRTC } from "../hooks/useWebRTC"; import MicrophoneOffFilledIcon from "../components/icons/MicrophoneOffFilledIcon"; import VideoFilledIcon from "../components/icons/VideoFilledIcon"; import clsx from "clsx"; +import { useMe } from "../hooks/useAuth"; function SessionPage() { const { setPopup } = usePopupStore(); + // Загружаем данные пользователя сразу при входе на страницу сессии + // React Query закэширует результат для использования в других компонентах + useMe(); + const [isFullscreen, setIsFullscreen] = useState(false); function toggleFullscreen() { diff --git a/server/.env b/server/.env index e2aaa31..560efa5 100644 --- a/server/.env +++ b/server/.env @@ -1,4 +1,6 @@ DATABASE_URL=postgres://postgres:v1sq3vD5faXL@194.26.138.94:5432/stream JWT_SECRET=b5cf2bd3894fb24191f13dc9dddaeecccc92d0ee298e7ee41c2d0aab51c28fa1 +# PORT=6000 +# SOCKET_PORT=6001 PORT=3000 SOCKET_PORT=3001 \ No newline at end of file diff --git a/server/src/index.ts b/server/src/index.ts index 813a361..0e7488e 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -263,7 +263,7 @@ io.on("connection", (socket) => { try { // Определяем имя отправителя - const finalSenderName = senderName || "Guest"; + const finalSenderName = senderName || "Гость"; console.log( `[Chat] Preparing to save message with senderName: "${finalSenderName}"` @@ -307,10 +307,11 @@ io.on("connection", (socket) => { } // Сохраняем сообщение в БД + // Приоритет: сначала userId (если авторизован), затем guestId (если гость) const messageData = { sessionId: roomId, - userId: userId || null, // null для анонимных пользователей - guestId: guestId || null, // ID гостя для неавторизованных + userId: userId || null, // userId для авторизованных пользователей + guestId: userId ? null : (guestId || null), // guestId только если нет userId senderName: finalSenderName, // Имя отправителя content, type: "text" as const, @@ -324,9 +325,10 @@ io.on("connection", (socket) => { console.log(`[Chat] Message saved successfully:`, savedMessage); // Формируем сообщение для отправки клиентам + // senderId - это либо userId (приоритет), либо guestId const messageToSend = { id: savedMessage.id, - senderId: userId || guestId, + senderId: savedMessage.userId || savedMessage.guestId, senderName: savedMessage.senderName, content: savedMessage.content, timestamp: savedMessage.createdAt,