blob: d7ca047340616259ea779f3d4d9bd4e51d7a4a7a [file] [log] [blame]
idillon07d31cc2022-12-06 22:40:14 -05001/*
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 */
Ziwei Wanga41e1662023-01-27 14:56:32 -050018import GroupAddRounded from '@mui/icons-material/GroupAddRounded';
idillon2ef2be92022-12-30 10:59:06 -050019import { Box, Dialog, DialogProps, Fab, List, ListSubheader, Typography } from '@mui/material';
idillon847b4642022-12-29 14:28:38 -050020import { useTranslation } from 'react-i18next';
21import { useNavigate } from 'react-router-dom';
idillon07d31cc2022-12-06 22:40:14 -050022
23import { Contact } from '../models/contact';
idillon2ef2be92022-12-30 10:59:06 -050024import { useAddContactMutation, useContactsSearchQuery } from '../services/contactQueries';
25import { useConversationsSummariesQuery } from '../services/conversationQueries';
idillon07d31cc2022-12-06 22:40:14 -050026import ConversationAvatar from './ConversationAvatar';
idillon8fef7db2023-01-11 11:03:18 -050027import { ConversationSummaryList } from './ConversationSummaryList';
idillon847b4642022-12-29 14:28:38 -050028import { CustomListItemButton } from './CustomListItemButton';
idillon07d31cc2022-12-06 22:40:14 -050029import { useDialogHandler } from './Dialog';
idillon2ef2be92022-12-30 10:59:06 -050030import LoadingPage from './Loading';
idillon07d31cc2022-12-06 22:40:14 -050031
32type ContactSearchResultListProps = {
idillon2ef2be92022-12-30 10:59:06 -050033 searchFilter: string;
idillon07d31cc2022-12-06 22:40:14 -050034};
35
idillon2ef2be92022-12-30 10:59:06 -050036export default ({ searchFilter }: ContactSearchResultListProps) => {
37 const { t } = useTranslation();
38
39 const contactsSearchQuery = useContactsSearchQuery(searchFilter);
40 // TODO: Filter conversations
41 const conversationsSummariesQuery = useConversationsSummariesQuery();
42
43 const isLoading = contactsSearchQuery.isLoading && conversationsSummariesQuery.isLoading;
44
45 if (isLoading) {
46 return <LoadingPage />;
47 }
48
49 const conversationsSummaries = conversationsSummariesQuery.data;
50 const contactsSearchResult = contactsSearchQuery.data;
51
idillon07d31cc2022-12-06 22:40:14 -050052 return (
53 <List>
idillon2ef2be92022-12-30 10:59:06 -050054 {contactsSearchResult && contactsSearchResult.length > 0 && (
55 <>
56 <ListSubheader>{t('search_results')}</ListSubheader>
57 {contactsSearchResult?.map((contact) => (
58 <ContactSearchResultListItem key={contact.uri} contact={contact} />
59 ))}
60 </>
61 )}
62
63 {conversationsSummaries && conversationsSummaries.length > 0 && (
64 <>
65 <ListSubheader>{t('conversations')}</ListSubheader>
idillon8fef7db2023-01-11 11:03:18 -050066 <ConversationSummaryList conversationsSummaries={conversationsSummaries} />
idillon2ef2be92022-12-30 10:59:06 -050067 </>
68 )}
idillon07d31cc2022-12-06 22:40:14 -050069 </List>
70 );
71};
72
73type ContactSearchResultListItemProps = {
74 contact: Contact;
75};
76
77const ContactSearchResultListItem = ({ contact }: ContactSearchResultListItemProps) => {
78 const dialogHandler = useDialogHandler();
79
80 return (
81 <>
82 <AddContactDialog {...dialogHandler.props} contactId={contact.uri} />
idillon847b4642022-12-29 14:28:38 -050083 <CustomListItemButton
idillon07d31cc2022-12-06 22:40:14 -050084 key={contact.uri}
85 onClick={() => {
86 dialogHandler.openDialog();
87 }}
idillon847b4642022-12-29 14:28:38 -050088 icon={<ConversationAvatar displayName={contact.getDisplayName()} />}
89 primaryText={<Typography variant="body1">{contact.getDisplayName()}</Typography>}
90 />
idillon07d31cc2022-12-06 22:40:14 -050091 </>
92 );
93};
94
95type AddContactDialogProps = DialogProps & {
96 contactId: string;
97};
98
99const AddContactDialog = ({ contactId, ...props }: AddContactDialogProps) => {
idillon847b4642022-12-29 14:28:38 -0500100 const { t } = useTranslation();
101 const navigate = useNavigate();
102 const addContactMutation = useAddContactMutation();
103
104 const handleClick = async () => {
105 addContactMutation.mutate(contactId, {
106 onSuccess: (data) => navigate(`/conversation/${data.conversationId}`),
107 onSettled: () => props.onClose?.({}, 'escapeKeyDown'), // dummy arguments for 'onClose'
108 });
109 };
110
idillon07d31cc2022-12-06 22:40:14 -0500111 return (
112 <Dialog {...props}>
idillon847b4642022-12-29 14:28:38 -0500113 <Typography variant="h6">{t('jami_user_id')}</Typography>
114 <Typography variant="body1">{contactId}</Typography>
115 <Box style={{ textAlign: 'center', marginTop: 16 }}>
116 <Fab variant="extended" color="primary" onClick={handleClick}>
117 <GroupAddRounded />
118 {t('conversation_add_contact')}
119 </Fab>
120 </Box>
idillon07d31cc2022-12-06 22:40:14 -0500121 </Dialog>
122 );
123};