blob: cfbc0ec01369c4c5631183a8e13775daa6920661 [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 { AddCircle, DeleteRounded, GroupRounded, PhoneCallbackRounded } from '@mui/icons-material';
simond47ef9e2022-09-28 22:24:28 -040019import {
simon07b4eb02022-09-29 17:50:26 -040020 Card,
21 CardContent,
22 Grid,
23 IconButton,
simond47ef9e2022-09-28 22:24:28 -040024 List,
25 ListItem,
simon07b4eb02022-09-29 17:50:26 -040026 ListItemAvatar,
simond47ef9e2022-09-28 22:24:28 -040027 ListItemIcon,
28 ListItemSecondaryAction,
29 ListItemText,
30 ListSubheader,
simond47ef9e2022-09-28 22:24:28 -040031 Paper,
simon07b4eb02022-09-29 17:50:26 -040032 Switch,
simond47ef9e2022-09-28 22:24:28 -040033 TextField,
simon07b4eb02022-09-29 17:50:26 -040034 Toolbar,
35 Typography,
simond47ef9e2022-09-28 22:24:28 -040036} from '@mui/material';
simon07b4eb02022-09-29 17:50:26 -040037import { motion } from 'framer-motion';
38import { useState } from 'react';
Adrien Béraud6ecaa402021-04-06 17:37:25 -040039
simond47ef9e2022-09-28 22:24:28 -040040import Account from '../../../model/Account';
simonfe1de722022-10-02 00:21:43 -040041import AccountDetails from '../../../model/AccountDetails';
simon07b4eb02022-09-29 17:50:26 -040042import authManager from '../AuthManager';
simond47ef9e2022-09-28 22:24:28 -040043import ConversationAvatar from './ConversationAvatar';
44import ConversationsOverviewCard from './ConversationsOverviewCard';
simon07b4eb02022-09-29 17:50:26 -040045import JamiIdCard from './JamiIdCard';
Adrien Béraud4e287b92021-04-24 16:15:56 -040046
simond47ef9e2022-09-28 22:24:28 -040047const transition = { duration: 0.3, ease: [0.43, 0.13, 0.23, 0.96] };
Adrien Béraud6c934962021-06-07 10:13:26 -040048
49const thumbnailVariants = {
50 initial: { scale: 0.9, opacity: 0 },
51 enter: { scale: 1, opacity: 1, transition },
52 exit: {
53 scale: 0.5,
54 opacity: 0,
simonfe1de722022-10-02 00:21:43 -040055 transition: { ...transition, duration: 1.5 },
simond47ef9e2022-09-28 22:24:28 -040056 },
57};
Adrien Béraud6c934962021-06-07 10:13:26 -040058
simonfe1de722022-10-02 00:21:43 -040059type AccountPreferencesProps = {
60 account: Account;
61 onAccountChanged?: (account: Account) => void;
62};
63
64export default function AccountPreferences({ account }: AccountPreferencesProps) {
65 const devices: string[][] = [];
66 const accountDevices = account.getDevices();
67 for (const i in accountDevices) devices.push([i, accountDevices[i]]);
Adrien Béraud4e287b92021-04-24 16:15:56 -040068
simond47ef9e2022-09-28 22:24:28 -040069 console.log(devices);
ervinanohf1758a42022-09-14 14:52:51 -040070
71 const isJamiAccount = account.getType() === Account.TYPE_JAMI;
simond47ef9e2022-09-28 22:24:28 -040072 const alias = isJamiAccount ? 'Jami account' : 'SIP account';
ervinanohf1758a42022-09-14 14:52:51 -040073 const moderators = account.getDefaultModerators();
simond47ef9e2022-09-28 22:24:28 -040074 const [defaultModeratorUri, setDefaultModeratorUri] = useState('');
ervinanohf1758a42022-09-14 14:52:51 -040075
76 const [details, setDetails] = useState(account.getDetails());
Adrien Béraud86986032021-04-25 12:04:53 -040077
Adrien Béraud4e287b92021-04-24 16:15:56 -040078 const addModerator = () => {
79 if (defaultModeratorUri) {
simond47ef9e2022-09-28 22:24:28 -040080 authManager.fetch(`/api/accounts/${account.getId()}/defaultModerators/${defaultModeratorUri}`, { method: 'PUT' });
81 setDefaultModeratorUri('');
Adrien Béraud4e287b92021-04-24 16:15:56 -040082 }
ervinanohf1758a42022-09-14 14:52:51 -040083 };
Adrien Béraud4e287b92021-04-24 16:15:56 -040084
simonfe1de722022-10-02 00:21:43 -040085 const removeModerator = (uri: string) =>
simond47ef9e2022-09-28 22:24:28 -040086 authManager.fetch(`/api/accounts/${account.getId()}/defaultModerators/${uri}`, { method: 'DELETE' });
Adrien Béraud4e287b92021-04-24 16:15:56 -040087
simonfe1de722022-10-02 00:21:43 -040088 const handleToggle = (key: keyof AccountDetails, value: boolean) => {
ervinanohf1758a42022-09-14 14:52:51 -040089 console.log(`handleToggle ${key} ${value}`);
simonfe1de722022-10-02 00:21:43 -040090 const newDetails: Partial<AccountDetails> = {};
simond47ef9e2022-09-28 22:24:28 -040091 newDetails[key] = value ? 'true' : 'false';
ervinanohf1758a42022-09-14 14:52:51 -040092 console.log(newDetails);
Adrien Béraud86986032021-04-25 12:04:53 -040093 authManager.fetch(`/api/accounts/${account.getId()}`, {
simond47ef9e2022-09-28 22:24:28 -040094 method: 'POST',
Adrien Béraud86986032021-04-25 12:04:53 -040095 headers: {
simond47ef9e2022-09-28 22:24:28 -040096 Accept: 'application/json',
97 'Content-Type': 'application/json',
Adrien Béraud86986032021-04-25 12:04:53 -040098 },
ervinanohf1758a42022-09-14 14:52:51 -040099 body: JSON.stringify(newDetails),
100 });
101 setDetails({ ...account.updateDetails(newDetails) });
102 };
Adrien Béraud86986032021-04-25 12:04:53 -0400103
Adrien Béraud150b4782021-04-21 19:40:59 -0400104 return (
Adrien Béraud6c934962021-06-07 10:13:26 -0400105 <motion.div
ervinanohf1758a42022-09-14 14:52:51 -0400106 initial="initial"
107 animate="enter"
108 exit="exit"
109 variants={{
110 enter: { transition: { staggerChildren: 0.05 } },
111 exit: { transition: { staggerChildren: 0.02 } },
112 }}
113 >
114 <motion.div variants={thumbnailVariants}>
115 <Typography variant="h2" component="h2" gutterBottom>
116 {alias}
117 </Typography>
118 </motion.div>
Adrien Béraud21c53cf2021-04-22 00:04:32 -0400119 <Grid container spacing={3} style={{ marginBottom: 16 }}>
ervinanohf1758a42022-09-14 14:52:51 -0400120 {isJamiAccount && (
121 <Grid item xs={12}>
122 <motion.div variants={thumbnailVariants}>
123 <JamiIdCard account={account} />
124 </motion.div>
125 </Grid>
126 )}
Adrien Béraud150b4782021-04-21 19:40:59 -0400127
128 <Grid item xs={12} sm={6}>
ervinanohf1758a42022-09-14 14:52:51 -0400129 <motion.div variants={thumbnailVariants}>
130 <ConversationsOverviewCard accountId={account.getId()} />
Adrien Béraud6c934962021-06-07 10:13:26 -0400131 </motion.div>
Adrien Béraud150b4782021-04-21 19:40:59 -0400132 </Grid>
133
134 <Grid item xs={12} sm={6}>
ervinanohf1758a42022-09-14 14:52:51 -0400135 <motion.div variants={thumbnailVariants}>
136 <Card>
137 <CardContent>
138 <Typography color="textSecondary" gutterBottom>
139 Current calls
140 </Typography>
141 <Typography gutterBottom variant="h5" component="h2">
142 0
143 </Typography>
144 </CardContent>
145 </Card>
Adrien Béraud6c934962021-06-07 10:13:26 -0400146 </motion.div>
Adrien Béraud150b4782021-04-21 19:40:59 -0400147 </Grid>
Adrien Béraud6c934962021-06-07 10:13:26 -0400148
ervinanohf1758a42022-09-14 14:52:51 -0400149 <Grid item xs={12} sm={6}>
150 <motion.div variants={thumbnailVariants}>
151 <Card>
152 <CardContent>
153 <Typography color="textSecondary" gutterBottom>
154 Appareils associés
155 </Typography>
156 <Typography gutterBottom variant="h5" component="h2">
simon80b7b3b2022-09-28 17:50:10 -0400157 {devices.map((device, i) => (
158 <ListItem key={i}>
ervinanohf1758a42022-09-14 14:52:51 -0400159 <GroupRounded />
simond47ef9e2022-09-28 22:24:28 -0400160 <ListItemText id="switch-list-label-rendezvous" primary={device[1]} secondary={device[0]} />
ervinanohf1758a42022-09-14 14:52:51 -0400161 </ListItem>
162 ))}
163 {/* <ListItemTextsion> */}
164 </Typography>
165 </CardContent>
166 </Card>
167 </motion.div>
168 </Grid>
Adrien Béraud150b4782021-04-21 19:40:59 -0400169 </Grid>
170
ervinanohf1758a42022-09-14 14:52:51 -0400171 <List
172 subheader={
173 <motion.div variants={thumbnailVariants}>
174 <ListSubheader>Settings</ListSubheader>
175 </motion.div>
176 }
177 >
178 <motion.div variants={thumbnailVariants}>
179 <ListItem>
180 <ListItemIcon>
181 <GroupRounded />
182 </ListItemIcon>
simond47ef9e2022-09-28 22:24:28 -0400183 <ListItemText id="switch-list-label-rendezvous" primary="Rendez-Vous point" />
ervinanohf1758a42022-09-14 14:52:51 -0400184 <ListItemSecondaryAction>
185 <Switch
186 edge="end"
simond47ef9e2022-09-28 22:24:28 -0400187 onChange={(e) => handleToggle('Account.rendezVous', e.target.checked)}
188 checked={details['Account.rendezVous'] === 'true'}
ervinanohf1758a42022-09-14 14:52:51 -0400189 inputProps={{
simond47ef9e2022-09-28 22:24:28 -0400190 'aria-labelledby': 'switch-list-label-rendezvous',
ervinanohf1758a42022-09-14 14:52:51 -0400191 }}
192 />
193 </ListItemSecondaryAction>
194 </ListItem>
Adrien Béraud6c934962021-06-07 10:13:26 -0400195 </motion.div>
196 <motion.div variants={thumbnailVariants}>
ervinanohf1758a42022-09-14 14:52:51 -0400197 <ListItem>
198 <ListItemIcon>
199 <PhoneCallbackRounded />
200 </ListItemIcon>
simond47ef9e2022-09-28 22:24:28 -0400201 <ListItemText id="switch-list-label-publicin" primary="Allow connection from unkown peers" />
ervinanohf1758a42022-09-14 14:52:51 -0400202 <ListItemSecondaryAction>
203 <Switch
204 edge="end"
simond47ef9e2022-09-28 22:24:28 -0400205 onChange={(e) => handleToggle('DHT.PublicInCalls', e.target.checked)}
206 checked={details['DHT.PublicInCalls'] === 'true'}
207 inputProps={{ 'aria-labelledby': 'switch-list-label-publicin' }}
ervinanohf1758a42022-09-14 14:52:51 -0400208 />
209 </ListItemSecondaryAction>
210 </ListItem>
Adrien Béraud6c934962021-06-07 10:13:26 -0400211 </motion.div>
212 <motion.div variants={thumbnailVariants}>
ervinanohf1758a42022-09-14 14:52:51 -0400213 <Paper>
214 <Toolbar>
215 <Typography variant="h6">Default moderators</Typography>
216 </Toolbar>
217 <List>
218 <ListItem key="add">
219 <TextField
220 variant="outlined"
221 value={defaultModeratorUri}
222 onChange={(e) => setDefaultModeratorUri(e.target.value)}
223 label="Add new default moderator"
224 placeholder="Enter new moderator name or URI"
225 fullWidth
226 />
227 <ListItemSecondaryAction>
228 <IconButton onClick={addModerator} size="large">
229 <AddCircle />
230 </IconButton>
231 </ListItemSecondaryAction>
232 </ListItem>
233 {!moderators || moderators.length === 0 ? (
234 <ListItem key="placeholder">
235 <ListItemText primary="No default moderator" />
Adrien Béraud21c53cf2021-04-22 00:04:32 -0400236 </ListItem>
ervinanohf1758a42022-09-14 14:52:51 -0400237 ) : (
238 moderators.map((moderator) => (
simonfe1de722022-10-02 00:21:43 -0400239 <ListItem key={moderator.getUri()}>
ervinanohf1758a42022-09-14 14:52:51 -0400240 <ListItemAvatar>
simonfe1de722022-10-02 00:21:43 -0400241 <ConversationAvatar displayName={moderator.getDisplayName()} />
ervinanohf1758a42022-09-14 14:52:51 -0400242 </ListItemAvatar>
243 <ListItemText primary={moderator.getDisplayName()} />
244 <ListItemSecondaryAction>
simonfe1de722022-10-02 00:21:43 -0400245 <IconButton onClick={(e) => removeModerator(moderator.getUri())} size="large">
ervinanohf1758a42022-09-14 14:52:51 -0400246 <DeleteRounded />
247 </IconButton>
248 </ListItemSecondaryAction>
249 </ListItem>
250 ))
251 )}
252 </List>
253 </Paper>
Adrien Béraud6c934962021-06-07 10:13:26 -0400254 </motion.div>
Adrien Béraud150b4782021-04-21 19:40:59 -0400255 </List>
Adrien Béraudab519ff2022-05-03 15:34:48 -0400256 </motion.div>
257 );
Adrien Béraud150b4782021-04-21 19:40:59 -0400258}