blob: d0593aee4387d98052c20ede8ddf8bf61c825881 [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 */
idillon847b4642022-12-29 14:28:38 -050018import { GroupAddRounded } from '@mui/icons-material';
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';
idillon2ef2be92022-12-30 10:59:06 -050027import ConversationListItem from './ConversationListItem';
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>
66 {conversationsSummaries.map((conversationSummary) => (
67 <ConversationListItem key={conversationSummary.id} conversationSummary={conversationSummary} />
68 ))}
69 </>
70 )}
idillon07d31cc2022-12-06 22:40:14 -050071 </List>
72 );
73};
74
75type ContactSearchResultListItemProps = {
76 contact: Contact;
77};
78
79const ContactSearchResultListItem = ({ contact }: ContactSearchResultListItemProps) => {
80 const dialogHandler = useDialogHandler();
81
82 return (
83 <>
84 <AddContactDialog {...dialogHandler.props} contactId={contact.uri} />
idillon847b4642022-12-29 14:28:38 -050085 <CustomListItemButton
idillon07d31cc2022-12-06 22:40:14 -050086 key={contact.uri}
87 onClick={() => {
88 dialogHandler.openDialog();
89 }}
idillon847b4642022-12-29 14:28:38 -050090 icon={<ConversationAvatar displayName={contact.getDisplayName()} />}
91 primaryText={<Typography variant="body1">{contact.getDisplayName()}</Typography>}
92 />
idillon07d31cc2022-12-06 22:40:14 -050093 </>
94 );
95};
96
97type AddContactDialogProps = DialogProps & {
98 contactId: string;
99};
100
101const AddContactDialog = ({ contactId, ...props }: AddContactDialogProps) => {
idillon847b4642022-12-29 14:28:38 -0500102 const { t } = useTranslation();
103 const navigate = useNavigate();
104 const addContactMutation = useAddContactMutation();
105
106 const handleClick = async () => {
107 addContactMutation.mutate(contactId, {
108 onSuccess: (data) => navigate(`/conversation/${data.conversationId}`),
109 onSettled: () => props.onClose?.({}, 'escapeKeyDown'), // dummy arguments for 'onClose'
110 });
111 };
112
idillon07d31cc2022-12-06 22:40:14 -0500113 return (
114 <Dialog {...props}>
idillon847b4642022-12-29 14:28:38 -0500115 <Typography variant="h6">{t('jami_user_id')}</Typography>
116 <Typography variant="body1">{contactId}</Typography>
117 <Box style={{ textAlign: 'center', marginTop: 16 }}>
118 <Fab variant="extended" color="primary" onClick={handleClick}>
119 <GroupAddRounded />
120 {t('conversation_add_contact')}
121 </Fab>
122 </Box>
idillon07d31cc2022-12-06 22:40:14 -0500123 </Dialog>
124 );
125};