123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import { useEffect, useRef, useState } from "react"
- import { Message, ShortMessage } from "./message"
- import { MyDropzone } from "./dropzone"
- import { Backdrop, Button, CircularProgress, List, TextField } from "@mui/material"
- import SendIcon from '@mui/icons-material/Send';
- import AttachFileIcon from '@mui/icons-material/AttachFile';
- import { Box } from "@mui/system";
- import { ArrowCircleDown } from "@mui/icons-material";
- const updateScroll = (el) => {
- el.scrollTop = el.scrollHeight
- }
- const Chat = ({ chat_id, chat_title, user_id, messages, isLoad, onUpload, onSend, onMSGEdit, onScrollTopComplete }) => {
- let [msg, setMSG] = useState("")
- let [isUpload, setIsUpload] = useState(false)
- let [files, setFiles] = useState([])
- let [isForward, setIsForward] = useState([false, ""])
- let [isReply, setIsReply] = useState([false, ""])
- let [skip, setSkip] = useState(20)
- let [isScroll, setIsScroll] = useState(true)
- let scrollRef = useRef(null)
- let input = useRef(null)
- useEffect(() => {
- if (isScroll) {
- updateScroll(scrollRef.current)
- }
- }, [messages, isScroll])
- useEffect(() => {
- input.current && input.current.focus()
- }, [isReply, isForward])
- let filesHandler = (file) => {
- setFiles(file)
- }
- let buttonScrollHandler = () => {
- setIsScroll(true)
- updateScroll(scrollRef.current)
- }
- let scrollHandler = (el) => {
- setIsScroll(Math.round(el.scrollTop + el.clientHeight) === el.scrollHeight)
- if (el && el.scrollTop === 0) {
- el.scrollTop = el.scrollHeight / 30
- !isScroll && onScrollTopComplete(chat_id, skip)
- setSkip(skip + 20)
- }
- }
- let sendHandler = (e) => {
- if (e.key === "Escape") {
- setIsReply([false, ""])
- setMSG("")
- }
- if ((e.key === "Enter" && !e.shiftKey) || e.type === "click") {
- if (!isReply[0] && !isForward[0]) { //отправить обычное сообщение
- onSend(chat_id, msg, files)
- }
- if (isReply[0]) {
- onSend(chat_id, msg, files, isReply[1]) //ответить на сообщение (isReply[1] - id msg на какое отвечаем)
- setIsReply([false, ""])
- }
- if (isForward[0]) {
- onSend(chat_id, msg, files, false, isForward[1]) //переслать (isForward[1] - id чата куда переслать)
- setIsForward([false, ""])
- }
- setMSG("")
- updateScroll(scrollRef.current)
- setFiles([])
- setIsUpload(false)
- e.preventDefault()
- }
- }
- return (
- <Box>
- {isLoad === "PENDING" && <Backdrop
- sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
- open={true}
- >
- <CircularProgress color="inherit" />
- </Backdrop>}
- <List ref={scrollRef} onScroll={() => scrollHandler(scrollRef.current)} sx={{ maxWidth: '100%', height: '85vh', overflowY: 'auto', display: 'flex', flexDirection: 'column' }}>
- {messages.length > 0 &&
- messages.map(message => {
- return <Message key={message._id}
- id={message._id}
- nick={message.owner.nick || message.owner.login}
- msg={message.text}
- date={message.createdAt}
- media={message.media}
- own={message.owner._id === user_id}
- replyTo={message.replyTo}
- onMSGEdit={onMSGEdit}
- onMSGReply={setIsReply}
- onMSGForward={setIsForward} />
- })}
- </List>
- {isReply[0] &&
- messages.filter(message => message._id === isReply[1]).map(m =>
- <ShortMessage key={m._id} nick={m.owner.nick || m.owner.login}
- text={m.text}
- date={m.createdAt} />)}
- {!isScroll && <Button size='large'
- onClick={() => buttonScrollHandler()}
- sx={{
- position: 'fixed',
- bottom: '10vh',
- left: '25vw',
- }}><ArrowCircleDown /></Button>}
- <div className="message-input">
- <TextField
- label="Введите сообщение..."
- placeholder="Введите сообщение..."
- variant="outlined"
- fullWidth
- multiline
- ref={input}
- value={msg}
- onFocus={() => updateScroll(scrollRef.current)}
- onInput={(e) => setMSG(e.target.value)}
- onKeyDown={(e) => sendHandler(e)}
- />
- {isUpload && <MyDropzone onUpload={onUpload} onSet={filesHandler} />}
- <Button onClick={() => setIsUpload(!isUpload)} variant="outlined"><AttachFileIcon /></Button>
- <Button onClick={(e) => sendHandler(e)} variant="contained" endIcon={<SendIcon />}>Отправить</Button>
- </div>
- </ Box>
- )
- }
- export default Chat
|