blob: fa10cfd2ec3418a13c513d5cba8ff3972cdec8c6 [file] [log] [blame]
simon26e79f72022-10-05 22:16:08 -04001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
simon07b4eb02022-09-29 17:50:26 -040018import { Stack } from '@mui/material';
simond47ef9e2022-09-28 22:24:28 -040019import { useEffect, useState } from 'react';
simon07b4eb02022-09-29 17:50:26 -040020import { useParams } from 'react-router';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040021
simon07b4eb02022-09-29 17:50:26 -040022import Contact from '../../../model/Contact';
23import Conversation from '../../../model/Conversation';
24import { useAppSelector } from '../../redux/hooks';
25import authManager from '../AuthManager';
Adrien Béraud6ecaa402021-04-06 17:37:25 -040026//import Sound from 'react-sound';
Adrien Béraud995e8022021-04-08 13:46:51 -040027import ConversationList from '../components/ConversationList';
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040028import ConversationView from '../components/ConversationView';
simon07b4eb02022-09-29 17:50:26 -040029import Header from '../components/Header';
simon6b9ddfb2022-10-03 00:04:50 -040030import LoadingPage from '../components/Loading';
simon07b4eb02022-09-29 17:50:26 -040031import NewContactForm from '../components/NewContactForm';
simonfe1de722022-10-02 00:21:43 -040032import AddContactPage from './AddContactPage';
ervinanoh34eb9472022-09-13 04:20:28 -040033
simonfe1de722022-10-02 00:21:43 -040034type MessengerProps = {
35 accountId?: string;
36 conversationId?: string;
37 contactId?: string;
38};
39
40const Messenger = (props: MessengerProps) => {
ervinanoh34eb9472022-09-13 04:20:28 -040041 const { refresh } = useAppSelector((state) => state.app);
42
simonfe1de722022-10-02 00:21:43 -040043 const [conversations, setConversations] = useState<Conversation[] | undefined>(undefined);
simond47ef9e2022-09-28 22:24:28 -040044 const [searchQuery, setSearchQuery] = useState('');
simonfe1de722022-10-02 00:21:43 -040045 const [searchResult, setSearchResults] = useState<Conversation | undefined>(undefined);
Larbi Gharibe9af9732021-03-31 15:08:01 +010046
simond47ef9e2022-09-28 22:24:28 -040047 const params = useParams();
48 const accountId = props.accountId || params.accountId;
49 const conversationId = props.conversationId || params.conversationId;
50 const contactId = props.contactId || params.contactId;
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040051
simonfe1de722022-10-02 00:21:43 -040052 if (accountId == null) {
53 throw new Error('Missing accountId');
54 }
55
Adrien Béraud4e287b92021-04-24 16:15:56 -040056 useEffect(() => {
simond47ef9e2022-09-28 22:24:28 -040057 console.log('REFRESH CONVERSATIONS FROM MESSENGER');
58 const controller = new AbortController();
59 authManager
60 .fetch(`/api/accounts/${accountId}/conversations`, { signal: controller.signal })
61 .then((res) => res.json())
simonfe1de722022-10-02 00:21:43 -040062 .then((result: Conversation[]) => {
simond47ef9e2022-09-28 22:24:28 -040063 console.log(result);
64 setConversations(Object.values(result).map((c) => Conversation.from(accountId, c)));
65 });
ervinanoh34eb9472022-09-13 04:20:28 -040066 // return () => controller.abort()
simond47ef9e2022-09-28 22:24:28 -040067 }, [accountId, refresh]);
Adrien Béraud995e8022021-04-08 13:46:51 -040068
Adrien Béraudabba2e52021-04-24 21:39:56 -040069 useEffect(() => {
simond47ef9e2022-09-28 22:24:28 -040070 if (!searchQuery) return;
71 const controller = new AbortController();
72 authManager
73 .fetch(`/api/accounts/${accountId}/ns/name/${searchQuery}`, { signal: controller.signal })
74 .then((response) => {
75 if (response.status === 200) {
76 return response.json();
77 } else {
simonfe1de722022-10-02 00:21:43 -040078 throw new Error(response.status.toString());
simond47ef9e2022-09-28 22:24:28 -040079 }
80 })
81 .then((response) => {
82 console.log(response);
83 const contact = new Contact(response.address);
84 contact.setRegisteredName(response.name);
85 setSearchResults(contact ? Conversation.fromSingleContact(accountId, contact) : undefined);
86 })
87 .catch((e) => {
88 setSearchResults(undefined);
89 });
90 // return () => controller.abort() // crash on React18
91 }, [accountId, searchQuery]);
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040092
simond47ef9e2022-09-28 22:24:28 -040093 console.log('Messenger render');
Adrien Béraud4e287b92021-04-24 16:15:56 -040094 return (
simond47ef9e2022-09-28 22:24:28 -040095 <Stack direction="row" height="100vh" width="100vw">
96 <Stack flexGrow={0} flexShrink={0} overflow="auto">
idillonbef18a52022-09-01 01:51:40 -040097 <Header />
98 <NewContactForm onChange={setSearchQuery} />
99 {contactId && <AddContactPage accountId={accountId} contactId={contactId} />}
simond47ef9e2022-09-28 22:24:28 -0400100 {conversations ? (
101 <ConversationList search={searchResult} conversations={conversations} accountId={accountId} />
102 ) : (
103 <div className="rooms-list">
104 <LoadingPage />
105 </div>
106 )}
idillonbef18a52022-09-01 01:51:40 -0400107 </Stack>
simond47ef9e2022-09-28 22:24:28 -0400108 <Stack flexGrow={1}>
idillonbef18a52022-09-01 01:51:40 -0400109 {conversationId && <ConversationView accountId={accountId} conversationId={conversationId} />}
110 </Stack>
111 </Stack>
simond47ef9e2022-09-28 22:24:28 -0400112 );
113};
Larbi Gharibe9af9732021-03-31 15:08:01 +0100114
simond47ef9e2022-09-28 22:24:28 -0400115export default Messenger;