separate 'ChatInterface' from 'ConversationView'
Change-Id: Ia77ce0e7884671848e9474dd683d0bc214383730
diff --git a/client/src/components/ConversationView.tsx b/client/src/components/ConversationView.tsx
index 1242541..fc0ee9b 100644
--- a/client/src/components/ConversationView.tsx
+++ b/client/src/components/ConversationView.tsx
@@ -16,19 +16,18 @@
* <https://www.gnu.org/licenses/>.
*/
import { Divider, Stack, Typography } from '@mui/material';
-import { Account, Conversation, ConversationMember, Message } from 'jami-web-common';
-import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
+import { Account, Conversation, ConversationMember } from 'jami-web-common';
+import { useContext, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router';
import { SocketContext } from '../contexts/Socket';
+import ChatInterface from '../pages/ChatInterface';
import { useAccountQuery } from '../services/Account';
-import { useConversationQuery, useMessagesQuery, useSendMessageMutation } from '../services/Conversation';
+import { useConversationQuery } from '../services/Conversation';
import { translateEnumeration, TranslateEnumerationOptions } from '../utils/translations';
import { AddParticipantButton, ShowOptionsMenuButton, StartAudioCallButton, StartVideoCallButton } from './Button';
import LoadingPage from './Loading';
-import MessageList from './MessageList';
-import SendMessageForm from './SendMessageForm';
type ConversationViewProps = {
accountId: string;
@@ -38,14 +37,11 @@
const socket = useContext(SocketContext);
const [account, setAccount] = useState<Account | undefined>();
const [conversation, setConversation] = useState<Conversation | undefined>();
- const [messages, setMessages] = useState<Message[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(false);
const accountQuery = useAccountQuery(accountId);
const conversationQuery = useConversationQuery(accountId, conversationId);
- const messagesQuery = useMessagesQuery(accountId, conversationId);
- const sendMessageMutation = useSendMessageMutation(accountId, conversationId);
useEffect(() => {
if (accountQuery.isSuccess) {
@@ -61,21 +57,12 @@
}, [accountId, conversationQuery.isSuccess, conversationQuery.data]);
useEffect(() => {
- if (messagesQuery.isSuccess) {
- const sortedMessages = sortMessages(messagesQuery.data);
- setMessages(sortedMessages);
- }
- }, [messagesQuery.isSuccess, messagesQuery.data]);
+ setIsLoading(accountQuery.isLoading || conversationQuery.isLoading);
+ }, [accountQuery.isLoading, conversationQuery.isLoading]);
useEffect(() => {
- setIsLoading(accountQuery.isLoading || conversationQuery.isLoading || messagesQuery.isLoading);
- }, [accountQuery.isLoading, conversationQuery.isLoading, messagesQuery.isLoading]);
-
- useEffect(() => {
- setError(accountQuery.isLoading || conversationQuery.isError || messagesQuery.isError);
- }, [accountQuery.isLoading, conversationQuery.isError, messagesQuery.isError]);
-
- const sendMessage = useCallback((message: string) => sendMessageMutation.mutate(message), [sendMessageMutation]);
+ setError(accountQuery.isError || conversationQuery.isError);
+ }, [accountQuery.isError, conversationQuery.isError]);
useEffect(() => {
if (!conversation) return;
@@ -85,11 +72,6 @@
accountId,
conversationId,
});
- socket.off('newMessage');
- socket.on('newMessage', (data) => {
- console.log('newMessage');
- setMessages((messages) => addMessage(messages, data));
- });
}
}, [accountId, conversation, conversationId, socket]);
@@ -112,14 +94,7 @@
borderTop: '1px solid #E5E5E5',
}}
/>
- <MessageList account={account} members={conversation.getMembers()} messages={messages} />
- <Divider
- sx={{
- margin: '30px 16px 0px 16px',
- borderTop: '1px solid #E5E5E5',
- }}
- />
- <SendMessageForm account={account} members={conversation.getMembers()} onSend={sendMessage} />
+ <ChatInterface account={account} conversationId={conversationId} members={conversation.getMembers()} />
</Stack>
);
};
@@ -167,7 +142,7 @@
};
return (
- <Stack direction="row" padding="16px">
+ <Stack direction="row" padding="16px" overflow="hidden">
<Stack flex={1} justifyContent="center" whiteSpace="nowrap" overflow="hidden">
<Typography variant="h3" textOverflow="ellipsis">
{title}
@@ -188,23 +163,4 @@
return contact.getDisplayName();
};
-const addMessage = (sortedMessages: Message[], message: Message) => {
- if (sortedMessages.length === 0) {
- return [message];
- } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
- return [...sortedMessages, message];
- } else if (message.linearizedParent === sortedMessages[0].id) {
- return [message, ...sortedMessages];
- } else {
- console.log("Can't insert message " + message.id);
- return sortedMessages;
- }
-};
-
-const sortMessages = (messages: Message[]) => {
- let sortedMessages: Message[] = [];
- messages.forEach((message) => (sortedMessages = addMessage(sortedMessages, message)));
- return sortedMessages;
-};
-
export default ConversationView;
diff --git a/client/src/pages/ChatInterface.tsx b/client/src/pages/ChatInterface.tsx
new file mode 100644
index 0000000..86f77da
--- /dev/null
+++ b/client/src/pages/ChatInterface.tsx
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2022 Savoir-faire Linux Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+import { Divider, Stack } from '@mui/material';
+import { Account, ConversationMember, Message } from 'jami-web-common';
+import { useCallback, useContext, useEffect, useState } from 'react';
+
+import LoadingPage from '../components/Loading';
+import MessageList from '../components/MessageList';
+import SendMessageForm from '../components/SendMessageForm';
+import { SocketContext } from '../contexts/Socket';
+import { useMessagesQuery, useSendMessageMutation } from '../services/Conversation';
+
+type ChatInterfaceProps = {
+ account: Account;
+ conversationId: string;
+ members: ConversationMember[];
+};
+const ChatInterface = ({ account, conversationId, members }: ChatInterfaceProps) => {
+ const socket = useContext(SocketContext);
+ const [messages, setMessages] = useState<Message[]>([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(false);
+
+ const messagesQuery = useMessagesQuery(account.getId(), conversationId);
+ const sendMessageMutation = useSendMessageMutation(account.getId(), conversationId);
+
+ useEffect(() => {
+ if (messagesQuery.isSuccess) {
+ const sortedMessages = sortMessages(messagesQuery.data);
+ setMessages(sortedMessages);
+ }
+ }, [messagesQuery.isSuccess, messagesQuery.data]);
+
+ useEffect(() => {
+ setIsLoading(messagesQuery.isLoading);
+ }, [messagesQuery.isLoading]);
+
+ useEffect(() => {
+ setError(messagesQuery.isError);
+ }, [messagesQuery.isError]);
+
+ const sendMessage = useCallback((message: string) => sendMessageMutation.mutate(message), [sendMessageMutation]);
+
+ useEffect(() => {
+ if (socket) {
+ socket.off('newMessage');
+ socket.on('newMessage', (data) => {
+ console.log('newMessage');
+ setMessages((messages) => addMessage(messages, data));
+ });
+ }
+ }, [conversationId, socket]);
+
+ if (isLoading) {
+ return <LoadingPage />;
+ } else if (error) {
+ return <div>Error loading {conversationId}</div>;
+ }
+
+ return (
+ <Stack flex={1} overflow="hidden">
+ <MessageList account={account} members={members} messages={messages} />
+ <Divider
+ sx={{
+ margin: '30px 16px 0px 16px',
+ borderTop: '1px solid #E5E5E5',
+ }}
+ />
+ <SendMessageForm account={account} members={members} onSend={sendMessage} />
+ </Stack>
+ );
+};
+
+const addMessage = (sortedMessages: Message[], message: Message) => {
+ if (sortedMessages.length === 0) {
+ return [message];
+ } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
+ return [...sortedMessages, message];
+ } else if (message.linearizedParent === sortedMessages[0].id) {
+ return [message, ...sortedMessages];
+ } else {
+ console.error("Can't insert message " + message.id);
+ return sortedMessages;
+ }
+};
+
+const sortMessages = (messages: Message[]) => {
+ let sortedMessages: Message[] = [];
+ messages.forEach((message) => (sortedMessages = addMessage(sortedMessages, message)));
+ return sortedMessages;
+};
+
+export default ChatInterface;