2023-03-28 22:39:27 +08:00
|
|
|
import React, { useEffect } from 'react';
|
|
|
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
|
|
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
2023-03-28 20:36:21 +08:00
|
|
|
|
2023-03-28 22:39:27 +08:00
|
|
|
import Landing from '../components/ui/Landing';
|
|
|
|
|
import Messages from '../components/Messages';
|
|
|
|
|
import TextChat from '../components/Input';
|
2023-03-28 20:36:21 +08:00
|
|
|
|
2023-03-28 22:39:27 +08:00
|
|
|
import store from '~/store';
|
|
|
|
|
import manualSWR from '~/utils/fetchers';
|
2023-03-28 20:36:21 +08:00
|
|
|
|
|
|
|
|
export default function Chat() {
|
2023-03-29 00:08:02 +08:00
|
|
|
const searchQuery = useRecoilValue(store.searchQuery);
|
2023-03-28 20:36:21 +08:00
|
|
|
const [conversation, setConversation] = useRecoilState(store.conversation);
|
|
|
|
|
const setMessages = useSetRecoilState(store.messages);
|
|
|
|
|
const messagesTree = useRecoilValue(store.messagesTree);
|
|
|
|
|
const { newConversation } = store.useConversation();
|
|
|
|
|
const { conversationId } = useParams();
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
2023-03-28 22:39:27 +08:00
|
|
|
const { trigger: messagesTrigger } = manualSWR(`/api/messages/${conversation?.conversationId}`, 'get');
|
2023-03-28 20:36:21 +08:00
|
|
|
|
2023-03-28 22:39:27 +08:00
|
|
|
const { trigger: conversationTrigger } = manualSWR(`/api/convos/${conversationId}`, 'get');
|
2023-03-28 20:36:21 +08:00
|
|
|
|
|
|
|
|
// when conversation changed or conversationId (in url) changed
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (conversation === null) {
|
|
|
|
|
// no current conversation, we need to do something
|
2023-03-29 00:08:02 +08:00
|
|
|
if (conversationId === 'new') {
|
2023-03-28 20:36:21 +08:00
|
|
|
// create new
|
|
|
|
|
newConversation();
|
2023-03-29 00:08:02 +08:00
|
|
|
} else if (conversationId) {
|
2023-03-28 20:36:21 +08:00
|
|
|
// fetch it from server
|
2023-03-29 00:18:27 +08:00
|
|
|
conversationTrigger()
|
|
|
|
|
.then(setConversation)
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('failed to fetch the conversation');
|
|
|
|
|
console.error(error);
|
|
|
|
|
newConversation();
|
|
|
|
|
});
|
2023-03-28 20:36:21 +08:00
|
|
|
setMessages(null);
|
2023-03-29 00:08:02 +08:00
|
|
|
} else {
|
|
|
|
|
navigate(`/chat/new`);
|
2023-03-28 20:36:21 +08:00
|
|
|
}
|
2023-03-29 00:08:02 +08:00
|
|
|
} else if (conversation?.conversationId === 'search') {
|
|
|
|
|
// jump to search page
|
|
|
|
|
navigate(`/search/${searchQuery}`);
|
|
|
|
|
} else if (conversation?.conversationId !== conversationId) {
|
2023-03-28 20:36:21 +08:00
|
|
|
// conversationId (in url) should always follow conversation?.conversationId, unless conversation is null
|
|
|
|
|
navigate(`/chat/${conversation?.conversationId}`);
|
2023-03-29 00:08:02 +08:00
|
|
|
}
|
2023-03-28 20:36:21 +08:00
|
|
|
}, [conversation, conversationId]);
|
|
|
|
|
|
|
|
|
|
// when messagesTree is null (<=> messages is null)
|
|
|
|
|
// we need to fetch message list from server
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (messagesTree === null) {
|
|
|
|
|
messagesTrigger().then(setMessages);
|
|
|
|
|
}
|
|
|
|
|
}, [conversation?.conversationId]);
|
|
|
|
|
|
2023-03-29 00:08:02 +08:00
|
|
|
// if not a conversation
|
|
|
|
|
if (conversation?.conversationId === 'search') return null;
|
|
|
|
|
// if conversationId not match
|
2023-03-28 20:36:21 +08:00
|
|
|
if (conversation?.conversationId !== conversationId) return null;
|
2023-03-29 00:08:02 +08:00
|
|
|
// if conversationId is null
|
|
|
|
|
if (!conversationId) return null;
|
2023-03-28 20:36:21 +08:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2023-03-29 05:48:44 +08:00
|
|
|
{conversationId === 'new' && !!messagesTree?.length ? <Landing /> : <Messages />}
|
2023-03-28 20:36:21 +08:00
|
|
|
<TextChat />
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|