import { Box, FormControl, IconButton, InputAdornment, InputBase, InputLabel, SxProps, Theme, Typography, useMediaQuery, useTheme, } from "@mui/material"; import { useTicketStore, incrementUnauthMessage, setUnauthIsPreventAutoscroll, } from "@root/ticket"; import { useEffect, useMemo, useRef, useState } from "react"; import ChatMessage from "./ChatMessage"; import ChatVideo from "./ChatVideo"; import SendIcon from "@icons/SendIcon"; import UserCircleIcon from "./UserCircleIcon"; import { throttle, getAuthToken } from "@frontend/kitui"; import { useEventListener } from "@frontend/kitui"; import ArrowLeft from "@icons/questionsPage/arrowLeft"; import { useUserStore } from "@root/user"; import AttachFileIcon from "@mui/icons-material/AttachFile"; import ChatImage from "./ChatImage"; import ChatDocument from "@ui_kit/FloatingSupportChat/ChatDocument"; import * as React from "react"; import { checkAcceptableMediaType, ACCEPT_SEND_MEDIA_TYPES_MAP, } from "@utils/checkAcceptableMediaType"; import { enqueueSnackbar } from "notistack"; interface Props { open: boolean; sx?: SxProps; onclickArrow?: () => void; sendMessage: (a: string) => Promise; sendFile: (a: File | undefined) => Promise; } 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 [messageField, setMessageField] = useState(""); const [disableFileButton, setDisableFileButton] = useState(false); 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); const sendMessageHC = async () => { const successful = await sendMessage(messageField); console.log("successful ", successful); if (successful) { setMessageField(""); } }; const sendFileHC = async (file: File) => { console.log(file); const check = checkAcceptableMediaType(file); if (check.length > 0) { enqueueSnackbar(check); return; } setDisableFileButton(true); await sendFile(file); setDisableFileButton(false); console.log(disableFileButton); }; const fileInputRef = useRef(null); 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], ); useEventListener("scroll", throttledScrollHandler, chatBoxRef); 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], ); function scrollToBottom(behavior?: ScrollBehavior) { if (!chatBoxRef.current) return; const chatBox = chatBoxRef.current; chatBox.scroll({ left: 0, top: chatBox.scrollHeight, behavior, }); } const handleTextfieldKeyPress: React.KeyboardEventHandler< HTMLInputElement | HTMLTextAreaElement > = (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); sendMessageHC(); } }; return ( <> {open && ( {isMobile && ( )} Мария онлайн-консультант {ticket.sessionData?.ticketId && messages.map((message) => { const isFileVideo = () => { if (message.files) { return ACCEPT_SEND_MEDIA_TYPES_MAP.video.some( (fileType) => message.files[0].toLowerCase().endsWith(fileType), ); } }; const isFileImage = () => { if (message.files) { return ACCEPT_SEND_MEDIA_TYPES_MAP.picture.some( (fileType) => message.files[0].toLowerCase().endsWith(fileType), ); } }; const isFileDocument = () => { if (message.files) { return ACCEPT_SEND_MEDIA_TYPES_MAP.document.some( (fileType) => message.files[0].toLowerCase().endsWith(fileType), ); } }; if (message.files.length > 0 && isFileImage()) { return ( ); } if (message.files.length > 0 && isFileVideo()) { return ( ); } if (message.files.length > 0 && isFileDocument()) { return ( ); } return ( ); })} setMessageField(e.target.value)} endAdornment={ { console.log(disableFileButton); if (!disableFileButton) fileInputRef.current?.click(); }} > { if (e.target.files?.[0]) sendFileHC(e.target.files?.[0]); }} style={{ display: "none" }} type="file" /> } /> )} ); }