fix message sending block

This commit is contained in:
nflnkr 2023-05-23 15:49:51 +03:00
parent a70ae04dae
commit 0610368d7b
2 changed files with 28 additions and 11 deletions

@ -1,13 +1,14 @@
import { Box, FormControl, IconButton, InputAdornment, InputBase, SxProps, Theme, Typography, useMediaQuery, useTheme } from "@mui/material"; import { Box, FormControl, IconButton, InputAdornment, InputBase, SxProps, Theme, Typography, useMediaQuery, useTheme } from "@mui/material";
import { createTicket, getUnauthTicketMessages, sendTicketMessage, subscribeToUnauthTicketMessages } from "@root/api/tickets"; import { createTicket, getUnauthTicketMessages, sendTicketMessage, subscribeToUnauthTicketMessages } from "@root/api/tickets";
import { GetMessagesRequest, TicketMessage } from "@root/model/ticket"; import { GetMessagesRequest, TicketMessage } from "@root/model/ticket";
import { addOrUpdateUnauthMessages, setUnauthTicketFetchState, useUnauthTicketStore, incrementUnauthMessageApiPage, setUnauthIsPreventAutoscroll, setUnauthSessionData } from "@root/stores/unauthTicket"; import { addOrUpdateUnauthMessages, setUnauthTicketFetchState, useUnauthTicketStore, incrementUnauthMessageApiPage, setUnauthIsPreventAutoscroll, setUnauthSessionData, setIsMessageSending } from "@root/stores/unauthTicket";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import ChatMessage from "../ChatMessage"; import ChatMessage from "../ChatMessage";
import SendIcon from "../icons/SendIcon"; import SendIcon from "../icons/SendIcon";
import UserCircleIcon from "./UserCircleIcon"; import UserCircleIcon from "./UserCircleIcon";
import { throttle } from "@root/utils/decorators"; import { throttle } from "@root/utils/decorators";
import { getMessageFromFetchError } from "@root/utils/backendMessageHandler";
interface Props { interface Props {
@ -22,6 +23,7 @@ export default function Chat({ sx }: Props) {
const messages = useUnauthTicketStore(state => state.messages); const messages = useUnauthTicketStore(state => state.messages);
const messageApiPage = useUnauthTicketStore(state => state.apiPage); const messageApiPage = useUnauthTicketStore(state => state.apiPage);
const messagesPerPage = useUnauthTicketStore(state => state.messagesPerPage); const messagesPerPage = useUnauthTicketStore(state => state.messagesPerPage);
const isMessageSending = useUnauthTicketStore(state => state.isMessageSending);
const messagesFetchStateRef = useRef(useUnauthTicketStore.getState().fetchState); const messagesFetchStateRef = useRef(useUnauthTicketStore.getState().fetchState);
const isPreventAutoscroll = useUnauthTicketStore(state => state.isPreventAutoscroll); const isPreventAutoscroll = useUnauthTicketStore(state => state.isPreventAutoscroll);
const lastMessageId = useUnauthTicketStore(state => state.lastMessageId); const lastMessageId = useUnauthTicketStore(state => state.lastMessageId);
@ -124,31 +126,41 @@ export default function Chat({ sx }: Props) {
useEffect(() => useUnauthTicketStore.subscribe(state => (messagesFetchStateRef.current = state.fetchState)), []); useEffect(() => useUnauthTicketStore.subscribe(state => (messagesFetchStateRef.current = state.fetchState)), []);
async function handleSendMessage() { async function handleSendMessage() {
if (!messageField) return; if (!messageField || isMessageSending) return;
if (!sessionData) { if (!sessionData) {
const response = await createTicket({ setIsMessageSending(true);
createTicket({
Title: "Unauth title", Title: "Unauth title",
Message: messageField, Message: messageField,
}, false); }, false).then(response => {
setUnauthSessionData({
setUnauthSessionData({ ticketId: response.Ticket,
ticketId: response.Ticket, sessionId: response.sess,
sessionId: response.sess, });
}).catch(error => {
const errorMessage = getMessageFromFetchError(error);
if (errorMessage) enqueueSnackbar(errorMessage);
}).finally(() => {
setMessageField("");
setIsMessageSending(false);
}); });
} else { } else {
setIsMessageSending(true);
sendTicketMessage({ sendTicketMessage({
ticket: sessionData.ticketId, ticket: sessionData.ticketId,
message: messageField, message: messageField,
lang: "ru", lang: "ru",
files: [], files: [],
}, true).catch(error => { }, true).catch(error => {
console.log("Coudn't send message", error); const errorMessage = getMessageFromFetchError(error);
enqueueSnackbar(error.message); if (errorMessage) enqueueSnackbar(errorMessage);
}).finally(() => {
setMessageField("");
setIsMessageSending(false);
}); });
} }
setMessageField("");
} }
function scrollToBottom(behavior?: ScrollBehavior) { function scrollToBottom(behavior?: ScrollBehavior) {
@ -259,12 +271,14 @@ export default function Chat({ sx }: Props) {
endAdornment={ endAdornment={
<InputAdornment position="end"> <InputAdornment position="end">
<IconButton <IconButton
disabled={isMessageSending}
onClick={handleSendMessage} onClick={handleSendMessage}
sx={{ sx={{
height: "53px", height: "53px",
width: "53px", width: "53px",
mr: "13px", mr: "13px",
p: 0, p: 0,
opacity: isMessageSending ? 0.3 : 1,
}} }}
> >
<SendIcon style={{ <SendIcon style={{

@ -8,6 +8,7 @@ interface UnauthTicketStore {
ticketId: string; ticketId: string;
sessionId: string; sessionId: string;
} | null; } | null;
isMessageSending: boolean;
messages: TicketMessage[]; messages: TicketMessage[];
fetchState: "idle" | "fetching" | "all fetched"; fetchState: "idle" | "fetching" | "all fetched";
apiPage: number; apiPage: number;
@ -21,6 +22,7 @@ export const useUnauthTicketStore = create<UnauthTicketStore>()(
devtools( devtools(
(set, get) => ({ (set, get) => ({
sessionData: null, sessionData: null,
isMessageSending: false,
messages: [], messages: [],
fetchState: "idle", fetchState: "idle",
apiPage: 0, apiPage: 0,
@ -44,6 +46,7 @@ export const useUnauthTicketStore = create<UnauthTicketStore>()(
); );
export const setUnauthSessionData = (sessionData: UnauthTicketStore["sessionData"]) => useUnauthTicketStore.setState({ sessionData }); export const setUnauthSessionData = (sessionData: UnauthTicketStore["sessionData"]) => useUnauthTicketStore.setState({ sessionData });
export const setIsMessageSending = (isMessageSending: UnauthTicketStore["isMessageSending"]) => useUnauthTicketStore.setState({ isMessageSending });
export const addOrUpdateUnauthMessages = (receivedMessages: TicketMessage[]) => { export const addOrUpdateUnauthMessages = (receivedMessages: TicketMessage[]) => {
const state = useUnauthTicketStore.getState(); const state = useUnauthTicketStore.getState();