diff --git a/frontend/src/App.js b/frontend/src/App.js index f1dfbde..ff22dac 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -2,46 +2,46 @@ import React, { useState, useEffect } from "react"; import Routes from "./routes"; import "react-toastify/dist/ReactToastify.css"; -import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles"; +import { createTheme, ThemeProvider } from "@material-ui/core/styles"; import { ptBR } from "@material-ui/core/locale"; const App = () => { - const [locale, setLocale] = useState(); + const [locale, setLocale] = useState(); - const theme = createMuiTheme( - { - scrollbarStyles: { - "&::-webkit-scrollbar": { - width: "8px", - height: "8px", - }, - "&::-webkit-scrollbar-thumb": { - boxShadow: "inset 0 0 6px rgba(0, 0, 0, 0.3)", - backgroundColor: "#e8e8e8", - }, - }, - palette: { - primary: { main: "#2576d2" }, - }, - }, - locale - ); + const theme = createTheme( + { + scrollbarStyles: { + "&::-webkit-scrollbar": { + width: "8px", + height: "8px", + }, + "&::-webkit-scrollbar-thumb": { + boxShadow: "inset 0 0 6px rgba(0, 0, 0, 0.3)", + backgroundColor: "#e8e8e8", + }, + }, + palette: { + primary: { main: "#2576d2" }, + }, + }, + locale + ); - useEffect(() => { - const i18nlocale = localStorage.getItem("i18nextLng"); - const browserLocale = - i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5); + useEffect(() => { + const i18nlocale = localStorage.getItem("i18nextLng"); + const browserLocale = + i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5); - if (browserLocale === "ptBR") { - setLocale(ptBR); - } - }, []); + if (browserLocale === "ptBR") { + setLocale(ptBR); + } + }, []); - return ( - - - - ); + return ( + + + + ); }; export default App; diff --git a/frontend/src/components/ColorPicker/index.js b/frontend/src/components/ColorPicker/index.js index b89b233..c10360e 100644 --- a/frontend/src/components/ColorPicker/index.js +++ b/frontend/src/components/ColorPicker/index.js @@ -4,28 +4,28 @@ import React, { useState } from "react"; import { GithubPicker } from "react-color"; const ColorPicker = ({ onChange, currentColor, handleClose, open }) => { - const [selectedColor, setSelectedColor] = useState(currentColor); + const [selectedColor, setSelectedColor] = useState(currentColor); - const handleChange = color => { - setSelectedColor(color.hex); - handleClose(); - }; + const handleChange = (color) => { + setSelectedColor(color.hex); + handleClose(); + }; - return ( - - onChange(color.hex)} - /> - - ); + return ( + + onChange(color.hex)} + /> + + ); }; export default ColorPicker; diff --git a/frontend/src/components/MainContainer/index.js b/frontend/src/components/MainContainer/index.js index 24b7b9a..0045703 100644 --- a/frontend/src/components/MainContainer/index.js +++ b/frontend/src/components/MainContainer/index.js @@ -3,29 +3,31 @@ import React from "react"; import { makeStyles } from "@material-ui/core/styles"; import Container from "@material-ui/core/Container"; -const useStyles = makeStyles(theme => ({ - mainContainer: { - flex: 1, - padding: theme.spacing(2), - height: `calc(100% - 48px)`, - }, +const useStyles = makeStyles((theme) => ({ + mainContainer: { + flex: 1, + // padding: theme.spacing(2), + // height: `calc(100% - 48px)`, + padding: 0, + height: "100%", + }, - contentWrapper: { - height: "100%", - overflowY: "hidden", - display: "flex", - flexDirection: "column", - }, + contentWrapper: { + height: "100%", + overflowY: "hidden", + display: "flex", + flexDirection: "column", + }, })); const MainContainer = ({ children }) => { - const classes = useStyles(); + const classes = useStyles(); - return ( - -
{children}
-
- ); + return ( + +
{children}
+
+ ); }; export default MainContainer; diff --git a/frontend/src/components/MessageInput/index.js b/frontend/src/components/MessageInput/index.js index f297786..3a33829 100644 --- a/frontend/src/components/MessageInput/index.js +++ b/frontend/src/components/MessageInput/index.js @@ -12,6 +12,7 @@ import CircularProgress from "@material-ui/core/CircularProgress"; import { green } from "@material-ui/core/colors"; import AttachFileIcon from "@material-ui/icons/AttachFile"; import IconButton from "@material-ui/core/IconButton"; +import MoreVert from "@material-ui/icons/MoreVert"; import MoodIcon from "@material-ui/icons/Mood"; import SendIcon from "@material-ui/icons/Send"; import CancelIcon from "@material-ui/icons/Cancel"; @@ -19,7 +20,13 @@ import ClearIcon from "@material-ui/icons/Clear"; import MicIcon from "@material-ui/icons/Mic"; import CheckCircleOutlineIcon from "@material-ui/icons/CheckCircleOutline"; import HighlightOffIcon from "@material-ui/icons/HighlightOff"; -import { FormControlLabel, Switch } from "@material-ui/core"; +import { + FormControlLabel, + Hidden, + Menu, + MenuItem, + Switch, +} from "@material-ui/core"; import ClickAwayListener from "@material-ui/core/ClickAwayListener"; import { i18n } from "../../translate/i18n"; @@ -39,6 +46,11 @@ const useStyles = makeStyles((theme) => ({ flexDirection: "column", alignItems: "center", borderTop: "1px solid rgba(0, 0, 0, 0.12)", + [theme.breakpoints.down("sm")]: { + position: "fixed", + bottom: 0, + width: "100%", + }, }, newMessageBox: { @@ -56,6 +68,7 @@ const useStyles = makeStyles((theme) => ({ display: "flex", borderRadius: 20, flex: 1, + position: "relative", }, messageInput: { @@ -200,6 +213,7 @@ const MessageInput = ({ ticketStatus }) => { const [quickAnswers, setQuickAnswer] = useState([]); const [typeBar, setTypeBar] = useState(false); const inputRef = useRef(); + const [anchorEl, setAnchorEl] = useState(null); const { setReplyingMessage, replyingMessage } = useContext(ReplyMessageContext); const { user } = useContext(AuthContext); @@ -363,6 +377,14 @@ const MessageInput = ({ ticketStatus }) => { } }; + const handleOpenMenuClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuItemClick = (event) => { + setAnchorEl(null); + }; + const renderReplyingMessage = (message) => { return (
@@ -429,60 +451,126 @@ const MessageInput = ({ ticketStatus }) => { {replyingMessage && renderReplyingMessage(replyingMessage)}
- setShowEmoji((prevState) => !prevState)} - > - - - {showEmoji ? ( -
- setShowEmoji(false)}> - - -
- ) : null} - - - - { - setSignMessage(e.target.checked); - }} - name="showAllTickets" - color="primary" - /> - } - /> + {showEmoji ? ( +
+ setShowEmoji(false)}> + + +
+ ) : null} + + + + { + setSignMessage(e.target.checked); + }} + name="showAllTickets" + color="primary" + /> + } + /> + + + + + + + + setShowEmoji((prevState) => !prevState)} + > + + + + + + + + + { + setSignMessage(e.target.checked); + }} + name="showAllTickets" + color="primary" + /> + } + /> + + +
{ diff --git a/frontend/src/components/MessageOptionsMenu/index.js b/frontend/src/components/MessageOptionsMenu/index.js index 83a0b6e..ea0dd0b 100644 --- a/frontend/src/components/MessageOptionsMenu/index.js +++ b/frontend/src/components/MessageOptionsMenu/index.js @@ -10,62 +10,62 @@ import { ReplyMessageContext } from "../../context/ReplyingMessage/ReplyingMessa import toastError from "../../errors/toastError"; const MessageOptionsMenu = ({ message, menuOpen, handleClose, anchorEl }) => { - const { setReplyingMessage } = useContext(ReplyMessageContext); - const [confirmationOpen, setConfirmationOpen] = useState(false); + const { setReplyingMessage } = useContext(ReplyMessageContext); + const [confirmationOpen, setConfirmationOpen] = useState(false); - const handleDeleteMessage = async () => { - try { - await api.delete(`/messages/${message.id}`); - } catch (err) { - toastError(err); - } - }; + const handleDeleteMessage = async () => { + try { + await api.delete(`/messages/${message.id}`); + } catch (err) { + toastError(err); + } + }; - const hanldeReplyMessage = () => { - setReplyingMessage(message); - handleClose(); - }; + const hanldeReplyMessage = () => { + setReplyingMessage(message); + handleClose(); + }; - const handleOpenConfirmationModal = e => { - setConfirmationOpen(true); - handleClose(); - }; + const handleOpenConfirmationModal = (e) => { + setConfirmationOpen(true); + handleClose(); + }; - return ( - <> - - {i18n.t("messageOptionsMenu.confirmationModal.message")} - - - {message.fromMe && ( - - {i18n.t("messageOptionsMenu.delete")} - - )} - - {i18n.t("messageOptionsMenu.reply")} - - - - ); + return ( + <> + + {i18n.t("messageOptionsMenu.confirmationModal.message")} + + + {message.fromMe && ( + + {i18n.t("messageOptionsMenu.delete")} + + )} + + {i18n.t("messageOptionsMenu.reply")} + + + + ); }; export default MessageOptionsMenu; diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js index e22af75..ef91b81 100644 --- a/frontend/src/components/MessagesList/index.js +++ b/frontend/src/components/MessagesList/index.js @@ -6,19 +6,19 @@ import clsx from "clsx"; import { green } from "@material-ui/core/colors"; import { - Button, - CircularProgress, - Divider, - IconButton, - makeStyles, + Button, + CircularProgress, + Divider, + IconButton, + makeStyles, } from "@material-ui/core"; import { - AccessTime, - Block, - Done, - DoneAll, - ExpandMore, - GetApp, + AccessTime, + Block, + Done, + DoneAll, + ExpandMore, + GetApp, } from "@material-ui/icons"; import MarkdownWrapper from "../MarkdownWrapper"; @@ -29,623 +29,626 @@ import whatsBackground from "../../assets/wa-background.png"; import api from "../../services/api"; import toastError from "../../errors/toastError"; -const useStyles = makeStyles(theme => ({ - messagesListWrapper: { - overflow: "hidden", - position: "relative", - display: "flex", - flexDirection: "column", - flexGrow: 1, - }, +const useStyles = makeStyles((theme) => ({ + messagesListWrapper: { + overflow: "hidden", + position: "relative", + display: "flex", + flexDirection: "column", + flexGrow: 1, + }, - messagesList: { - backgroundImage: `url(${whatsBackground})`, - display: "flex", - flexDirection: "column", - flexGrow: 1, - padding: "20px 20px 20px 20px", - overflowY: "scroll", - ...theme.scrollbarStyles, - }, + messagesList: { + backgroundImage: `url(${whatsBackground})`, + display: "flex", + flexDirection: "column", + flexGrow: 1, + padding: "20px 20px 20px 20px", + overflowY: "scroll", + [theme.breakpoints.down("sm")]: { + paddingBottom: "90px", + }, + ...theme.scrollbarStyles, + }, - circleLoading: { - color: green[500], - position: "absolute", - opacity: "70%", - top: 0, - left: "50%", - marginTop: 12, - }, + circleLoading: { + color: green[500], + position: "absolute", + opacity: "70%", + top: 0, + left: "50%", + marginTop: 12, + }, - messageLeft: { - marginRight: 20, - marginTop: 2, - minWidth: 100, - maxWidth: 600, - height: "auto", - display: "block", - position: "relative", - "&:hover #messageActionsButton": { - display: "flex", - position: "absolute", - top: 0, - right: 0, - }, + messageLeft: { + marginRight: 20, + marginTop: 2, + minWidth: 100, + maxWidth: 600, + height: "auto", + display: "block", + position: "relative", + "&:hover #messageActionsButton": { + display: "flex", + position: "absolute", + top: 0, + right: 0, + }, - whiteSpace: "pre-wrap", - backgroundColor: "#ffffff", - color: "#303030", - alignSelf: "flex-start", - borderTopLeftRadius: 0, - borderTopRightRadius: 8, - borderBottomLeftRadius: 8, - borderBottomRightRadius: 8, - paddingLeft: 5, - paddingRight: 5, - paddingTop: 5, - paddingBottom: 0, - boxShadow: "0 1px 1px #b3b3b3", - }, + whiteSpace: "pre-wrap", + backgroundColor: "#ffffff", + color: "#303030", + alignSelf: "flex-start", + borderTopLeftRadius: 0, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + paddingLeft: 5, + paddingRight: 5, + paddingTop: 5, + paddingBottom: 0, + boxShadow: "0 1px 1px #b3b3b3", + }, - quotedContainerLeft: { - margin: "-3px -80px 6px -6px", - overflow: "hidden", - backgroundColor: "#f0f0f0", - borderRadius: "7.5px", - display: "flex", - position: "relative", - }, + quotedContainerLeft: { + margin: "-3px -80px 6px -6px", + overflow: "hidden", + backgroundColor: "#f0f0f0", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, - quotedMsg: { - padding: 10, - maxWidth: 300, - height: "auto", - display: "block", - whiteSpace: "pre-wrap", - overflow: "hidden", - }, + quotedMsg: { + padding: 10, + maxWidth: 300, + height: "auto", + display: "block", + whiteSpace: "pre-wrap", + overflow: "hidden", + }, - quotedSideColorLeft: { - flex: "none", - width: "4px", - backgroundColor: "#6bcbef", - }, + quotedSideColorLeft: { + flex: "none", + width: "4px", + backgroundColor: "#6bcbef", + }, - messageRight: { - marginLeft: 20, - marginTop: 2, - minWidth: 100, - maxWidth: 600, - height: "auto", - display: "block", - position: "relative", - "&:hover #messageActionsButton": { - display: "flex", - position: "absolute", - top: 0, - right: 0, - }, + messageRight: { + marginLeft: 20, + marginTop: 2, + minWidth: 100, + maxWidth: 600, + height: "auto", + display: "block", + position: "relative", + "&:hover #messageActionsButton": { + display: "flex", + position: "absolute", + top: 0, + right: 0, + }, - whiteSpace: "pre-wrap", - backgroundColor: "#dcf8c6", - color: "#303030", - alignSelf: "flex-end", - borderTopLeftRadius: 8, - borderTopRightRadius: 8, - borderBottomLeftRadius: 8, - borderBottomRightRadius: 0, - paddingLeft: 5, - paddingRight: 5, - paddingTop: 5, - paddingBottom: 0, - boxShadow: "0 1px 1px #b3b3b3", - }, + whiteSpace: "pre-wrap", + backgroundColor: "#dcf8c6", + color: "#303030", + alignSelf: "flex-end", + borderTopLeftRadius: 8, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 0, + paddingLeft: 5, + paddingRight: 5, + paddingTop: 5, + paddingBottom: 0, + boxShadow: "0 1px 1px #b3b3b3", + }, - quotedContainerRight: { - margin: "-3px -80px 6px -6px", - overflowY: "hidden", - backgroundColor: "#cfe9ba", - borderRadius: "7.5px", - display: "flex", - position: "relative", - }, + quotedContainerRight: { + margin: "-3px -80px 6px -6px", + overflowY: "hidden", + backgroundColor: "#cfe9ba", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, - quotedMsgRight: { - padding: 10, - maxWidth: 300, - height: "auto", - whiteSpace: "pre-wrap", - }, + quotedMsgRight: { + padding: 10, + maxWidth: 300, + height: "auto", + whiteSpace: "pre-wrap", + }, - quotedSideColorRight: { - flex: "none", - width: "4px", - backgroundColor: "#35cd96", - }, + quotedSideColorRight: { + flex: "none", + width: "4px", + backgroundColor: "#35cd96", + }, - messageActionsButton: { - display: "none", - position: "relative", - color: "#999", - zIndex: 1, - backgroundColor: "inherit", - opacity: "90%", - "&:hover, &.Mui-focusVisible": { backgroundColor: "inherit" }, - }, + messageActionsButton: { + display: "none", + position: "relative", + color: "#999", + zIndex: 1, + backgroundColor: "inherit", + opacity: "90%", + "&:hover, &.Mui-focusVisible": { backgroundColor: "inherit" }, + }, - messageContactName: { - display: "flex", - color: "#6bcbef", - fontWeight: 500, - }, + messageContactName: { + display: "flex", + color: "#6bcbef", + fontWeight: 500, + }, - textContentItem: { - overflowWrap: "break-word", - padding: "3px 80px 6px 6px", - }, + textContentItem: { + overflowWrap: "break-word", + padding: "3px 80px 6px 6px", + }, - textContentItemDeleted: { - fontStyle: "italic", - color: "rgba(0, 0, 0, 0.36)", - overflowWrap: "break-word", - padding: "3px 80px 6px 6px", - }, + textContentItemDeleted: { + fontStyle: "italic", + color: "rgba(0, 0, 0, 0.36)", + overflowWrap: "break-word", + padding: "3px 80px 6px 6px", + }, - messageMedia: { - objectFit: "cover", - width: 250, - height: 200, - borderTopLeftRadius: 8, - borderTopRightRadius: 8, - borderBottomLeftRadius: 8, - borderBottomRightRadius: 8, - }, + messageMedia: { + objectFit: "cover", + width: 250, + height: 200, + borderTopLeftRadius: 8, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + }, - timestamp: { - fontSize: 11, - position: "absolute", - bottom: 0, - right: 5, - color: "#999", - }, + timestamp: { + fontSize: 11, + position: "absolute", + bottom: 0, + right: 5, + color: "#999", + }, - dailyTimestamp: { - alignItems: "center", - textAlign: "center", - alignSelf: "center", - width: "110px", - backgroundColor: "#e1f3fb", - margin: "10px", - borderRadius: "10px", - boxShadow: "0 1px 1px #b3b3b3", - }, + dailyTimestamp: { + alignItems: "center", + textAlign: "center", + alignSelf: "center", + width: "110px", + backgroundColor: "#e1f3fb", + margin: "10px", + borderRadius: "10px", + boxShadow: "0 1px 1px #b3b3b3", + }, - dailyTimestampText: { - color: "#808888", - padding: 8, - alignSelf: "center", - marginLeft: "0px", - }, + dailyTimestampText: { + color: "#808888", + padding: 8, + alignSelf: "center", + marginLeft: "0px", + }, - ackIcons: { - fontSize: 18, - verticalAlign: "middle", - marginLeft: 4, - }, + ackIcons: { + fontSize: 18, + verticalAlign: "middle", + marginLeft: 4, + }, - deletedIcon: { - fontSize: 18, - verticalAlign: "middle", - marginRight: 4, - }, + deletedIcon: { + fontSize: 18, + verticalAlign: "middle", + marginRight: 4, + }, - ackDoneAllIcon: { - color: green[500], - fontSize: 18, - verticalAlign: "middle", - marginLeft: 4, - }, + ackDoneAllIcon: { + color: green[500], + fontSize: 18, + verticalAlign: "middle", + marginLeft: 4, + }, - downloadMedia: { - display: "flex", - alignItems: "center", - justifyContent: "center", - backgroundColor: "inherit", - padding: 10, - }, + downloadMedia: { + display: "flex", + alignItems: "center", + justifyContent: "center", + backgroundColor: "inherit", + padding: 10, + }, })); const reducer = (state, action) => { - if (action.type === "LOAD_MESSAGES") { - const messages = action.payload; - const newMessages = []; + if (action.type === "LOAD_MESSAGES") { + const messages = action.payload; + const newMessages = []; - messages.forEach(message => { - const messageIndex = state.findIndex(m => m.id === message.id); - if (messageIndex !== -1) { - state[messageIndex] = message; - } else { - newMessages.push(message); - } - }); + messages.forEach((message) => { + const messageIndex = state.findIndex((m) => m.id === message.id); + if (messageIndex !== -1) { + state[messageIndex] = message; + } else { + newMessages.push(message); + } + }); - return [...newMessages, ...state]; - } + return [...newMessages, ...state]; + } - if (action.type === "ADD_MESSAGE") { - const newMessage = action.payload; - const messageIndex = state.findIndex(m => m.id === newMessage.id); + if (action.type === "ADD_MESSAGE") { + const newMessage = action.payload; + const messageIndex = state.findIndex((m) => m.id === newMessage.id); - if (messageIndex !== -1) { - state[messageIndex] = newMessage; - } else { - state.push(newMessage); - } + if (messageIndex !== -1) { + state[messageIndex] = newMessage; + } else { + state.push(newMessage); + } - return [...state]; - } + return [...state]; + } - if (action.type === "UPDATE_MESSAGE") { - const messageToUpdate = action.payload; - const messageIndex = state.findIndex(m => m.id === messageToUpdate.id); + if (action.type === "UPDATE_MESSAGE") { + const messageToUpdate = action.payload; + const messageIndex = state.findIndex((m) => m.id === messageToUpdate.id); - if (messageIndex !== -1) { - state[messageIndex] = messageToUpdate; - } + if (messageIndex !== -1) { + state[messageIndex] = messageToUpdate; + } - return [...state]; - } + return [...state]; + } - if (action.type === "RESET") { - return []; - } + if (action.type === "RESET") { + return []; + } }; const MessagesList = ({ ticketId, isGroup }) => { - const classes = useStyles(); + const classes = useStyles(); - const [messagesList, dispatch] = useReducer(reducer, []); - const [pageNumber, setPageNumber] = useState(1); - const [hasMore, setHasMore] = useState(false); - const [loading, setLoading] = useState(false); - const lastMessageRef = useRef(); + const [messagesList, dispatch] = useReducer(reducer, []); + const [pageNumber, setPageNumber] = useState(1); + const [hasMore, setHasMore] = useState(false); + const [loading, setLoading] = useState(false); + const lastMessageRef = useRef(); - const [selectedMessage, setSelectedMessage] = useState({}); - const [anchorEl, setAnchorEl] = useState(null); - const messageOptionsMenuOpen = Boolean(anchorEl); - const currentTicketId = useRef(ticketId); + const [selectedMessage, setSelectedMessage] = useState({}); + const [anchorEl, setAnchorEl] = useState(null); + const messageOptionsMenuOpen = Boolean(anchorEl); + const currentTicketId = useRef(ticketId); - useEffect(() => { - dispatch({ type: "RESET" }); - setPageNumber(1); + useEffect(() => { + dispatch({ type: "RESET" }); + setPageNumber(1); - currentTicketId.current = ticketId; - }, [ticketId]); + currentTicketId.current = ticketId; + }, [ticketId]); - useEffect(() => { - setLoading(true); - const delayDebounceFn = setTimeout(() => { - const fetchMessages = async () => { - try { - const { data } = await api.get("/messages/" + ticketId, { - params: { pageNumber }, - }); + useEffect(() => { + setLoading(true); + const delayDebounceFn = setTimeout(() => { + const fetchMessages = async () => { + try { + const { data } = await api.get("/messages/" + ticketId, { + params: { pageNumber }, + }); - if (currentTicketId.current === ticketId) { - dispatch({ type: "LOAD_MESSAGES", payload: data.messages }); - setHasMore(data.hasMore); - setLoading(false); - } + if (currentTicketId.current === ticketId) { + dispatch({ type: "LOAD_MESSAGES", payload: data.messages }); + setHasMore(data.hasMore); + setLoading(false); + } - if (pageNumber === 1 && data.messages.length > 1) { - scrollToBottom(); - } - } catch (err) { - setLoading(false); - toastError(err); - } - }; - fetchMessages(); - }, 500); - return () => { - clearTimeout(delayDebounceFn); - }; - }, [pageNumber, ticketId]); + if (pageNumber === 1 && data.messages.length > 1) { + scrollToBottom(); + } + } catch (err) { + setLoading(false); + toastError(err); + } + }; + fetchMessages(); + }, 500); + return () => { + clearTimeout(delayDebounceFn); + }; + }, [pageNumber, ticketId]); - useEffect(() => { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL); - socket.on("connect", () => socket.emit("joinChatBox", ticketId)); + socket.on("connect", () => socket.emit("joinChatBox", ticketId)); - socket.on("appMessage", data => { - if (data.action === "create") { - dispatch({ type: "ADD_MESSAGE", payload: data.message }); - scrollToBottom(); - } + socket.on("appMessage", (data) => { + if (data.action === "create") { + dispatch({ type: "ADD_MESSAGE", payload: data.message }); + scrollToBottom(); + } - if (data.action === "update") { - dispatch({ type: "UPDATE_MESSAGE", payload: data.message }); - } - }); + if (data.action === "update") { + dispatch({ type: "UPDATE_MESSAGE", payload: data.message }); + } + }); - return () => { - socket.disconnect(); - }; - }, [ticketId]); + return () => { + socket.disconnect(); + }; + }, [ticketId]); - const loadMore = () => { - setPageNumber(prevPageNumber => prevPageNumber + 1); - }; + const loadMore = () => { + setPageNumber((prevPageNumber) => prevPageNumber + 1); + }; - const scrollToBottom = () => { - if (lastMessageRef.current) { - lastMessageRef.current.scrollIntoView({}); - } - }; + const scrollToBottom = () => { + if (lastMessageRef.current) { + lastMessageRef.current.scrollIntoView({}); + } + }; - const handleScroll = e => { - if (!hasMore) return; - const { scrollTop } = e.currentTarget; + const handleScroll = (e) => { + if (!hasMore) return; + const { scrollTop } = e.currentTarget; - if (scrollTop === 0) { - document.getElementById("messagesList").scrollTop = 1; - } + if (scrollTop === 0) { + document.getElementById("messagesList").scrollTop = 1; + } - if (loading) { - return; - } + if (loading) { + return; + } - if (scrollTop < 50) { - loadMore(); - } - }; + if (scrollTop < 50) { + loadMore(); + } + }; - const handleOpenMessageOptionsMenu = (e, message) => { - setAnchorEl(e.currentTarget); - setSelectedMessage(message); - }; + const handleOpenMessageOptionsMenu = (e, message) => { + setAnchorEl(e.currentTarget); + setSelectedMessage(message); + }; - const handleCloseMessageOptionsMenu = e => { - setAnchorEl(null); - }; + const handleCloseMessageOptionsMenu = (e) => { + setAnchorEl(null); + }; - const checkMessageMedia = message => { - if (message.mediaType === "image") { - return ; - } - if (message.mediaType === "audio") { - return ( - - ); - } + const checkMessageMedia = (message) => { + if (message.mediaType === "image") { + return ; + } + if (message.mediaType === "audio") { + return ( + + ); + } - if (message.mediaType === "video") { - return ( -