import { Box, IconButton, SxProps, Theme, Typography, useMediaQuery, useTheme, } from "@mui/material"; import { addOrUpdateUnauthMessages, incrementUnauthMessage, setUnauthIsPreventAutoscroll, useTicketStore, } from "@root/ticket"; import type { TouchEvent, WheelEvent } from "react"; import { useEffect, useMemo, useRef } from "react"; import ChatMessageRenderer from "./ChatMessageRenderer"; import ChatInput from "./ChatInput"; import UserCircleIcon from "./UserCircleIcon"; import { throttle, TicketMessage } from "@frontend/kitui"; import ArrowLeft from "@icons/questionsPage/arrowLeft"; import { useUserStore } from "@root/user"; interface Props { open: boolean; sx?: SxProps; onclickArrow?: () => void; sendMessage: (a: string) => Promise; sendFile: (a: File | undefined) => Promise; } const greetingMessage: TicketMessage = { id: "greeting", ticket_id: "", user_id: "system", session_id: "", message: "Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут", files: [], shown: {}, request_screenshot: "", created_at: new Date().toISOString(), system: false }; export default function Chat({ open = false, sx, onclickArrow, sendMessage, sendFile, }: Props) { const theme = useTheme(); const upMd = useMediaQuery(theme.breakpoints.up("md")); const isMobile = useMediaQuery(theme.breakpoints.down(800)); const user = useUserStore((state) => state.user?._id); const ticket = useTicketStore( (state) => state[user ? "authData" : "unauthData"], ); const messages = ticket.messages; const isMessageSending = ticket.isMessageSending; const isPreventAutoscroll = ticket.isPreventAutoscroll; const lastMessageId = ticket.lastMessageId; const fetchState = ticket.unauthTicketMessageFetchState; const chatBoxRef = useRef(null); useEffect(() => { if (open) { scrollToBottom(); } }, [open]); const throttledScrollHandler = useMemo( () => throttle(() => { const chatBox = chatBoxRef.current; if (!chatBox) return; const scrollBottom = chatBox.scrollHeight - chatBox.scrollTop - chatBox.clientHeight; const isPreventAutoscroll = scrollBottom > chatBox.clientHeight; setUnauthIsPreventAutoscroll(isPreventAutoscroll); if (fetchState !== "idle") return; if (chatBox.scrollTop < chatBox.clientHeight) { incrementUnauthMessage(); } }, 200), [fetchState], ); useEffect(() => { if (chatBoxRef.current && chatBoxRef.current.scrollTop < 1) chatBoxRef.current.scrollTop = 1; }, [messages]); useEffect( function scrollOnNewMessage() { if (!chatBoxRef.current) return; if (!isPreventAutoscroll) { setTimeout(() => { scrollToBottom(); }, 50); } }, [lastMessageId], ); const loadNewMessages = ( event: WheelEvent | TouchEvent, ) => { event.stopPropagation(); throttledScrollHandler(); }; function scrollToBottom(behavior?: ScrollBehavior) { if (!chatBoxRef.current) return; const chatBox = chatBoxRef.current; chatBox.scroll({ left: 0, top: chatBox.scrollHeight, behavior, }); } return ( <> {open && ( {isMobile && ( )} Данила онлайн-консультант {ticket.sessionData?.ticketId && messages.map((message) => { const isSelf = (ticket.sessionData?.sessionId || user) === message.user_id; return ( ); })} {!ticket.sessionData?.ticketId && ( )} )} ); }