blob: 7230dd05486b082993957bb8a5f9d0bce41c9de7 [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 */
idillonae655dd2022-10-14 18:11:02 -040018import { InputBase } from '@mui/material';
simon07b4eb02022-09-29 17:50:26 -040019import { Stack } from '@mui/system';
idillonae655dd2022-10-14 18:11:02 -040020import { Account, ConversationMember } from 'jami-web-common';
21import { ChangeEvent, FormEvent, useCallback, useMemo, useState } from 'react';
22import { useTranslation } from 'react-i18next';
simon07b4eb02022-09-29 17:50:26 -040023
idillonae655dd2022-10-14 18:11:02 -040024import { translateEnumeration, TranslateEnumerationOptions } from '../utils/translations';
simond47ef9e2022-09-28 22:24:28 -040025import {
26 RecordVideoMessageButton,
27 RecordVoiceMessageButton,
28 SelectEmojiButton,
29 SendMessageButton,
30 UploadFileButton,
simon6b9ddfb2022-10-03 00:04:50 -040031} from './Button';
Larbi Gharibe9af9732021-03-31 15:08:01 +010032
simon6b9ddfb2022-10-03 00:04:50 -040033type SendMessageFormProps = {
idillonae655dd2022-10-14 18:11:02 -040034 account: Account;
35 members: ConversationMember[];
simon6b9ddfb2022-10-03 00:04:50 -040036 onSend: (message: string) => void;
37};
38
39export default function SendMessageForm(props: SendMessageFormProps) {
simond47ef9e2022-09-28 22:24:28 -040040 const [currentMessage, setCurrentMessage] = useState('');
idillonae655dd2022-10-14 18:11:02 -040041 const placeholder = usePlaceholder(props.account, props.members);
Adrien Béraud35e7d7c2021-04-13 03:28:39 -040042
simon6b9ddfb2022-10-03 00:04:50 -040043 const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
simond47ef9e2022-09-28 22:24:28 -040044 e.preventDefault();
Adrien Béraud88a52442021-04-26 12:11:41 -040045 if (currentMessage) {
simond47ef9e2022-09-28 22:24:28 -040046 props.onSend(currentMessage);
47 setCurrentMessage('');
Adrien Béraud88a52442021-04-26 12:11:41 -040048 }
simond47ef9e2022-09-28 22:24:28 -040049 };
simon6b9ddfb2022-10-03 00:04:50 -040050 const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => setCurrentMessage(event.target.value);
idillonaedab942022-09-01 14:29:43 -040051
Adrien Béraud023f7cf2022-09-18 14:57:53 -040052 const onEmojiSelected = useCallback(
simon6b9ddfb2022-10-03 00:04:50 -040053 (emoji: string) => setCurrentMessage((currentMessage) => currentMessage + emoji),
simond47ef9e2022-09-28 22:24:28 -040054 [setCurrentMessage]
55 );
Larbi Gharibe9af9732021-03-31 15:08:01 +010056
Adrien Béraud8a438f82021-04-14 16:18:57 -040057 return (
idillonae655dd2022-10-14 18:11:02 -040058 <Stack component="form" onSubmit={handleSubmit} direction="row" alignItems="center" spacing="20px">
59 <UploadFileButton />
60 <RecordVoiceMessageButton />
61 <RecordVideoMessageButton />
62 <Stack flexGrow={1}>
63 <InputBase
64 placeholder={placeholder}
65 value={currentMessage}
66 onChange={handleInputChange}
67 sx={{
68 fontSize: '15px',
69 color: 'black',
70 '& ::placeholder': {
71 color: '#7E7E7E',
72 opacity: 1,
73 textOverflow: 'ellipsis',
74 },
75 }}
76 />
idillonaedab942022-09-01 14:29:43 -040077 </Stack>
idillonae655dd2022-10-14 18:11:02 -040078 <SelectEmojiButton onEmojiSelected={onEmojiSelected} />
79 {currentMessage && <SendMessageButton type="submit" />}
idillonaedab942022-09-01 14:29:43 -040080 </Stack>
Adrien Béraudab519ff2022-05-03 15:34:48 -040081 );
Larbi Gharibe9af9732021-03-31 15:08:01 +010082}
idillonae655dd2022-10-14 18:11:02 -040083
84const usePlaceholder = (account: Account, members: ConversationMember[]) => {
85 const { t } = useTranslation();
86
87 return useMemo(() => {
88 const options: TranslateEnumerationOptions<ConversationMember> = {
89 elementPartialKey: 'member',
90 getElementValue: (member) => getMemberName(member),
91 translaters: [
92 () =>
93 // The user is chatting with themself
94 t('message_input_placeholder_one', { member0: account?.getDisplayName() }),
95 (interpolations) => t('message_input_placeholder_one', interpolations),
96 (interpolations) => t('message_input_placeholder_two', interpolations),
97 (interpolations) => t('message_input_placeholder_three', interpolations),
98 (interpolations) => t('message_input_placeholder_four', interpolations),
99 (interpolations) => t('message_input_placeholder_more', interpolations),
100 ],
101 };
102
103 return translateEnumeration<ConversationMember>(members, options);
104 }, [account, members, t]);
105};
106
107const getMemberName = (member: ConversationMember) => {
108 const contact = member.contact;
109 return contact.getDisplayName();
110};