blob: f2bd7d6aacbdf6e0051bc4bb1f7ea2ee366d7e02 [file] [log] [blame]
simon2d3b6532022-11-08 21:01:57 -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 */
18
simonf929a362022-11-18 16:53:45 -050019import { Box, CircularProgress, Grid, IconButtonProps, Stack, Typography } from '@mui/material';
Gabriel Rochon61f82af2022-11-22 22:28:02 -050020import { ComponentType, ReactNode, useContext, useMemo } from 'react';
simon4e7445c2022-11-16 21:18:46 -050021import { useTranslation } from 'react-i18next';
simon2d3b6532022-11-08 21:01:57 -050022
23import {
24 CallingAnswerAudioButton,
25 CallingAnswerVideoButton,
simonf929a362022-11-18 16:53:45 -050026 CallingCancelButton,
simon2d3b6532022-11-08 21:01:57 -050027 CallingRefuseButton,
28} from '../components/CallButtons';
Gabriel Rochon61f82af2022-11-22 22:28:02 -050029import { ConversationContext } from '../contexts/ConversationProvider';
simon2d3b6532022-11-08 21:01:57 -050030
31export type CallPendingProps = {
32 pending: PendingStatus;
33 caller?: CallerStatus;
34 medium?: CommunicationMedium;
35};
36
37type PendingStatus = 'caller' | 'receiver';
38type CallerStatus = 'calling' | 'connecting';
39type CommunicationMedium = 'audio' | 'video';
40
simon2d3b6532022-11-08 21:01:57 -050041export const CallPending = (props: CallPendingProps) => {
42 return (
43 <Stack
44 direction="column"
45 justifyContent="center"
46 alignItems="center"
47 height="100%"
48 spacing={4}
simon9f814a32022-11-22 21:40:53 -050049 flexGrow={1}
simon2d3b6532022-11-08 21:01:57 -050050 sx={{
51 backgroundColor: 'black',
52 }}
53 >
54 <Box
55 sx={{
56 position: 'relative',
57 display: 'flex',
58 alignItems: 'center',
59 justifyContent: 'center',
60 width: '100%',
61 height: '30%',
62 }}
63 >
64 <Box
65 sx={{
66 aspectRatio: '1',
67 height: '100%',
68 position: 'absolute',
69 }}
70 >
71 <CircularProgress
72 disableShrink
73 thickness={1}
74 size="100%"
75 sx={{
76 position: 'absolute',
77 color: 'white',
78 zIndex: 1,
79 }}
80 />
81 <img
82 // TODO: Insert incoming caller icon here
simonf929a362022-11-18 16:53:45 -050083 alt="contact profile picture"
simon2d3b6532022-11-08 21:01:57 -050084 style={{
85 position: 'absolute',
86 objectFit: 'cover',
87 width: '100%',
88 height: '100%',
89 maxWidth: '100%',
90 borderRadius: '50%',
91 aspectRatio: '1',
92 }}
93 />
94 </Box>
95 </Box>
96 {props.pending === 'caller' ? (
97 <CallPendingCallerInterface {...props} />
98 ) : (
99 <CallPendingReceiverInterface {...props} />
100 )}
101 </Stack>
102 );
103};
104
simonf929a362022-11-18 16:53:45 -0500105const CallPendingDetails = ({
106 title,
107 buttons,
108}: {
109 title: ReactNode;
110 buttons: {
111 ButtonComponent: ComponentType<IconButtonProps>;
112 title: ReactNode;
113 }[];
114}) => {
simon2d3b6532022-11-08 21:01:57 -0500115 return (
simon4e7445c2022-11-16 21:18:46 -0500116 <>
simon2d3b6532022-11-08 21:01:57 -0500117 <Typography variant="h1" color="white">
simonf929a362022-11-18 16:53:45 -0500118 {title}
simon2d3b6532022-11-08 21:01:57 -0500119 </Typography>
simon4e7445c2022-11-16 21:18:46 -0500120 <Box width="50%">
simonf929a362022-11-18 16:53:45 -0500121 <Grid container justifyContent="center">
122 {buttons.map(({ ButtonComponent, title: buttonTitle }, i) => (
123 <Grid item key={i} xs={4}>
124 <Stack direction="column" alignItems="center" spacing={1} sx={{}}>
125 <ButtonComponent color="inherit" size="large" />
126 <Typography variant="body2" color="white" sx={{ opacity: 0.75 }}>
127 {buttonTitle}
128 </Typography>
129 </Stack>
130 </Grid>
131 ))}
132 </Grid>
simon4e7445c2022-11-16 21:18:46 -0500133 </Box>
134 </>
simon2d3b6532022-11-08 21:01:57 -0500135 );
136};
137
simonf929a362022-11-18 16:53:45 -0500138export const CallPendingCallerInterface = ({ caller }: CallPendingProps) => {
simon4e7445c2022-11-16 21:18:46 -0500139 const { t } = useTranslation();
Gabriel Rochon61f82af2022-11-22 22:28:02 -0500140 const { conversation } = useContext(ConversationContext);
141 const memberName = useMemo(() => conversation.getFirstMember().contact.getRegisteredName(), [conversation]);
simonf929a362022-11-18 16:53:45 -0500142
simon2d3b6532022-11-08 21:01:57 -0500143 return (
simonf929a362022-11-18 16:53:45 -0500144 <CallPendingDetails
145 title={
146 caller === 'calling'
147 ? t('calling', {
Gabriel Rochon61f82af2022-11-22 22:28:02 -0500148 member0: memberName,
simonf929a362022-11-18 16:53:45 -0500149 })
150 : t('connecting')
151 }
152 buttons={[
153 {
154 ButtonComponent: CallingCancelButton,
155 title: t('end_call'),
156 },
157 ]}
158 />
159 );
160};
161
162export const CallPendingReceiverInterface = ({ medium, caller }: CallPendingProps) => {
163 const { t } = useTranslation();
Gabriel Rochon61f82af2022-11-22 22:28:02 -0500164 const { conversation } = useContext(ConversationContext);
165 const memberName = useMemo(() => conversation.getFirstMember().contact.getRegisteredName(), [conversation]);
simonf929a362022-11-18 16:53:45 -0500166
167 return (
168 <CallPendingDetails
169 title={
170 caller === 'connecting'
171 ? t('connecting')
172 : t('incoming_call', {
173 context: medium,
Gabriel Rochon61f82af2022-11-22 22:28:02 -0500174 member0: memberName,
simonf929a362022-11-18 16:53:45 -0500175 })
176 }
177 buttons={[
178 {
179 ButtonComponent: CallingRefuseButton,
180 title: t('refuse_call'),
181 },
182 {
183 ButtonComponent: CallingAnswerAudioButton,
184 title: t('accept_call_audio'),
185 },
186 {
187 ButtonComponent: CallingAnswerVideoButton,
188 title: t('accept_call_video'),
189 },
190 ]}
191 />
simon2d3b6532022-11-08 21:01:57 -0500192 );
193};