frontPanel/src/ui_kit/FloatingSupportChat/ChatInput.tsx

137 lines
3.9 KiB
TypeScript
Raw Normal View History

2025-07-11 16:21:36 +00:00
import { useCallback, useRef, useState } from "react";
import {
FormControl,
IconButton,
InputAdornment,
InputBase,
useMediaQuery,
useTheme,
} from "@mui/material";
import SendIcon from "@icons/SendIcon";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import { checkAcceptableMediaType } from "@utils/checkAcceptableMediaType";
import { enqueueSnackbar } from "notistack";
interface ChatInputProps {
sendMessage: (message: string) => Promise<boolean>;
sendFile: (file: File | undefined) => Promise<void>;
isMessageSending: boolean;
}
const ChatInput = ({ sendMessage, sendFile, isMessageSending }: ChatInputProps) => {
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const [messageField, setMessageField] = useState<string>("");
const [disableFileButton, setDisableFileButton] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleSendMessage = useCallback(async () => {
const successful = await sendMessage(messageField);
if (successful) {
setMessageField("");
}
}, [sendMessage, messageField]);
const handleSendFile = useCallback(async (file: File) => {
const check = checkAcceptableMediaType(file);
if (check.length > 0) {
enqueueSnackbar(check);
return;
}
setDisableFileButton(true);
await sendFile(file);
setDisableFileButton(false);
}, [sendFile]);
const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files?.[0]) {
handleSendFile(e.target.files[0]);
}
}, [handleSendFile]);
const handleFileButtonClick = useCallback(() => {
if (!disableFileButton) {
fileInputRef.current?.click();
}
}, [disableFileButton]);
const handleTextfieldKeyPress: React.KeyboardEventHandler<
HTMLInputElement | HTMLTextAreaElement
> = useCallback((e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSendMessage();
}
}, [handleSendMessage]);
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setMessageField(e.target.value);
}, []);
return (
<FormControl fullWidth sx={{ borderTop: "1px solid black" }}>
<InputBase
value={messageField}
fullWidth
placeholder="Введите сообщение..."
id="message"
multiline
onKeyDown={handleTextfieldKeyPress}
sx={{
width: "100%",
p: 0,
}}
inputProps={{
sx: {
fontWeight: 400,
fontSize: "16px",
lineHeight: "19px",
pt: upMd ? "30px" : "28px",
pb: upMd ? "30px" : "24px",
px: "19px",
maxHeight: "calc(19px * 5)",
color: "black",
},
}}
onChange={handleInputChange}
endAdornment={
<InputAdornment position="end">
<IconButton
disabled={disableFileButton}
onClick={handleFileButtonClick}
>
<AttachFileIcon />
</IconButton>
<input
ref={fileInputRef}
id="fileinput"
onChange={handleFileInputChange}
style={{ display: "none" }}
type="file"
/>
<IconButton
disabled={isMessageSending}
onClick={handleSendMessage}
sx={{
height: "53px",
width: "53px",
mr: "13px",
p: 0,
opacity: isMessageSending ? 0.3 : 1,
}}
>
<SendIcon
style={{
width: "100%",
height: "100%",
}}
/>
</IconButton>
</InputAdornment>
}
/>
</FormControl>
);
};
export default ChatInput;