import { useState, useEffect, useRef } from "react"; import { MessagePanel, type MessagePanelState } from "../../panels/MessagePanel"; import { ChatMessages } from "./ChatMessages"; import { ChatInputWrapper } from "./ChatInputWrapper"; import { setGlobalMessageHandler } from "../../../core/websocket"; import type { Message } from "../../../core/types"; import defaultAvatar from "../../../resources/images/default-avatar.png"; interface MessagePanelRendererProps { panel: MessagePanel | null; isChatSwitching: boolean; } export function MessagePanelRenderer({ panel, isChatSwitching }: MessagePanelRendererProps) { const [panelState, setPanelState] = useState(null); const [switchIn, setSwitchIn] = useState(false); const [switchOut, setSwitchOut] = useState(false); const messagesEndRef = useRef(null); const [replyTo, setReplyTo] = useState(null); const [replyToVisible, setReplyToVisible] = useState(Boolean(replyTo)); const [editMessage, setEditMessage] = useState(null); const [editVisible, setEditVisible] = useState(Boolean(editMessage)); const [pendingAction, setPendingAction] = useState(null); useEffect(() => { if (replyTo) { setReplyToVisible(true); } }, [replyTo]); useEffect(() => { if (editMessage) { setEditVisible(true); } }, [editMessage]); // Handle panel state changes useEffect(() => { if (panel) { setPanelState(panel.getState()); // Set up state change listener const handleStateChange = (newState: MessagePanelState) => { setPanelState(newState); }; // Store the handler for cleanup panel.onStateChange = handleStateChange; // Set up WebSocket message handler for this panel if (panel.handleWebSocketMessage) { setGlobalMessageHandler(panel.handleWebSocketMessage); } } else { setPanelState(null); // Clear global message handler when no panel is active setGlobalMessageHandler(null); } // Cleanup function return () => { if (panel && panel.onStateChange) { panel.onStateChange = null; } }; }, [panel]); // Handle chat switching animation useEffect(() => { if (isChatSwitching) { setSwitchOut(true); setTimeout(() => { setSwitchOut(false); setSwitchIn(true); setTimeout(() => setSwitchIn(false), 200); }, 250); } }, [isChatSwitching]); // Scroll to bottom when messages change useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [panelState?.messages]); if (!panel || !panelState) { return (
Avatar

Выбор чата

Выберите чат, чтобы начать переписку

Выберите чат на боковой панели, чтобы начать переписку
); } return (
Avatar

{panelState.title}

{panelState.online ? "Online" : "Offline"} {panelState.isTyping && " • Typing..."}

{panelState.isLoading ? (
Загрузка сообщений...
): ( { if (editMessage || editVisible) { setPendingAction({ type: "reply", message: message }); setEditVisible(false); // onCloseEdit will apply pending } else { setReplyTo(message); } }} onEditSelect={(message) => { if (replyTo || replyToVisible) { setPendingAction({ type: "edit", message: message }); setReplyToVisible(false); // onCloseReply will apply pending } else { setEditMessage(message); } }} >
)} { panel.handleSendMessage(text, replyTo?.id, files); setReplyTo(null); }} onSaveEdit={(content) => { if (editMessage) { panel.handleEditMessage(editMessage.id, content); setEditMessage(null); } }} replyTo={replyTo} replyToVisible={replyToVisible} onClearReply={() => { setPendingAction(null); setReplyToVisible(false); }} onCloseReply={() => { setReplyTo(null); if (pendingAction && pendingAction.type === "edit") { setEditMessage(pendingAction.message); setPendingAction(null); } }} editingMessage={editMessage} editVisible={editVisible} onClearEdit={() => { setPendingAction(null); setEditVisible(false); }} onCloseEdit={() => { setEditMessage(null); if (pendingAction && pendingAction.type === "reply") { setReplyTo(pendingAction.message); setPendingAction(null); } }} />
); }