import React, { useEffect, useMemo } from "react"; import PropTypes from "prop-types"; import { DirectChatContainer } from "./DirectChat.styled"; import DirectChatHeaderTitle from "./DirectChatHeaderTitle/DirectChatHeaderTitle"; import DirectChatHeader from "./DirectChatHeader/DirectChatHeader"; import { useDispatch, useSelector } from "react-redux"; import { useLocation, useRouteMatch } from "react-router-dom"; import { addNewMessage, fetchChats, fetchOneChat, setOneChat, } from "../../store/actions/chat/chatActions"; import { selectLatestChats, selectSelectedChat, } from "../../store/selectors/chatSelectors"; import DirectChatContent from "./DirectChatContent/DirectChatContent"; import { selectOffer } from "../../store/selectors/offersSelectors"; import { fetchOneOffer } from "../../store/actions/offers/offersActions"; import SkeletonDirectChat from "./SkeletonDirectChat/SkeletonDirectChat"; import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; import { CHAT_SCOPE } from "../../store/actions/chat/chatActionConstants"; import { selectUserId } from "../../store/selectors/loginSelectors"; import { acceptExchangeSocket, addMessageListener, removeMessageListener, } from "../../socket/socket"; import { makeErrorToastMessage } from "../../store/utils/makeToastMessage"; import { useTranslation } from "react-i18next"; import { selectExchange, selectRequester, } from "../../store/selectors/exchangeSelector"; import { acceptExchange, fetchExchange, setRequester, } from "../../store/actions/exchange/exchangeActions"; import { convertLocalDateToUTCDate } from "../../util/helpers/dateHelpers"; import requesterStatus from "../../constants/requesterStatus"; import exchangeStatus from "../../constants/exchangeStatus"; import { NEW_CHAT } from "../../constants/chatConstants"; const DirectChat = () => { const chat = useSelector(selectSelectedChat); const allChats = useSelector(selectLatestChats); const offer = useSelector(selectOffer); const routeMatch = useRouteMatch(); const location = useLocation(); const dispatch = useDispatch(); const { t } = useTranslation(); const exchange = useSelector(selectExchange); const requester = useSelector(selectRequester); const userId = useSelector(selectUserId); const isLoadingDirectChat = useSelector( selectIsLoadingByActionType(CHAT_SCOPE) ); const offerObject = useMemo(() => { if (location?.state?.offerId) { return offer; } return chat?.offer; }, [chat, location.state, offer]); const chatObject = useMemo(() => { if (location?.state?.offerId) { return {}; } return chat; }, [chat, location.state]); const amIBuyer = useMemo( () => exchange.buyer?.user?._id === userId, [exchange, userId] ); const exchangeState = useMemo(() => { if (exchange?.buyer) { let haveIAccepted = amIBuyer ? exchange.buyer?.accepted : exchange.seller?.accepted; let haveinterlocutorAccepted = amIBuyer ? exchange.seller?.accepted : exchange.buyer?.accepted; let haveIReviewed = amIBuyer ? exchange.buyer.givenReview : exchange.seller.givenReview; if (haveIAccepted) { if (haveinterlocutorAccepted) { if (haveIReviewed) { return exchangeStatus.REVIEWED; } else { return exchangeStatus.ACCEPTED; } } else { return exchangeStatus.I_OFFERED; } } else { if (haveinterlocutorAccepted) { return exchangeStatus.I_AM_OFFERED; } else { return exchangeStatus.INITIAL; } } } return exchangeStatus.INITIAL; }, [exchange, amIBuyer]); const interlocutorObject = useMemo(() => { if (location?.state?.offerId) { return offer?.user; } if (chat?.participants) { let interlocutor = userId === chat?.participants[0]._id ? 1 : 0; return chat?.participants[interlocutor]; } return {}; }, [chat, location.state, offer]); // Fetch chat after it is created // (renders after state of location changes) useEffect(() => { if (routeMatch.params?.chatId) { refreshChat(); } }, [routeMatch.params?.chatId, location.state?.offerId]); // Listener to socket.IO chat useEffect(() => { addMessageListener(({ succeed, data }) => { if (succeed) { if ( [...allChats].find((item) => { return item._id === data.chatId; }) ) { dispatch( addNewMessage({ _id: data.chatId, message: data.message, }) ); if (data.message?.isAcceptRequest) { dispatch(fetchExchange(exchange?._id)); if (requester === requesterStatus.NOONE) { dispatch(setRequester(requesterStatus.interlocutor)); } } } else { dispatch(fetchChats()); } } else { dispatch(fetchChats()); dispatch(fetchOneChat(routeMatch.params?.chatId)); makeErrorToastMessage(t("apiErrors.somethingWentWrong")); } }); return () => removeMessageListener(); }, [allChats, routeMatch, requester]); const refreshChat = () => { if (routeMatch.params?.chatId === NEW_CHAT) { dispatch(fetchOneOffer(location.state.offerId)); dispatch(setOneChat({})); } else { dispatch(fetchOneChat(routeMatch.params?.chatId)); } }; const handleAcceptExchangeSuccess = () => { let interlocutor = userId === chat?.participants[0]._id ? 1 : 0; acceptExchangeSocket( chat?._id, userId, chat?.participants[interlocutor]._id, () => { dispatch( addNewMessage({ _id: chat?._id, message: { user: { _id: userId, }, isAcceptRequest: true, text: "", _created: convertLocalDateToUTCDate(new Date()), }, }) ); if (requester === requesterStatus.NOONE) { dispatch(setRequester(requesterStatus.ME)); } } ); }; const handleAcceptExchange = () => { console.log("accept salje i prima 1 POZVANA FUNKCIJA") dispatch( acceptExchange({ exchangeId: exchange._id, handleApiResponseSuccess: handleAcceptExchangeSuccess, }) ); }; return ( {isLoadingDirectChat || isLoadingDirectChat === undefined ? ( ) : ( <> )} ); }; DirectChat.propTypes = { children: PropTypes.node, }; export default DirectChat;