myems-web/src/components/chat/content/MessageTextArea.js
import React, { useState, useContext, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { Input, Label, Form, Button } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import 'emoji-mart/css/emoji-mart.css';
import { Picker } from 'emoji-mart';
import AppContext, { ChatContext } from '../../../context/Context';
import classNames from 'classnames';
import { getGrays } from '../../../helpers/utils';
const formatDate = date => {
const options = {
weekday: 'short',
day: 'numeric',
month: 'long',
year: 'numeric',
hour: 'numeric',
minute: 'numeric'
};
const now = date
.toLocaleString('en-US', options)
.split(',')
.map(item => item.trim());
return {
day: now[0],
hour: now[3],
date: now[1] + ', ' + now[2]
};
};
const MessageTextArea = ({ thread }) => {
const { isDark, isRTL } = useContext(AppContext);
const { messages, messagesDispatch, threadsDispatch, textAreaInitialHeight, setTextAreaInitialHeight } = useContext(
ChatContext
);
const [previewEmoji, setPreviewEmoji] = useState(false);
const [message, setMessage] = useState('');
const isMountedRef = useRef(null);
//Emoji box hiding Controller
useEffect(() => {
const handleClickOutsideEmojiBox = e => {
if (e.target.closest('.emoji-mart') || e.target.closest('.textarea')) return;
setPreviewEmoji(false);
};
if (previewEmoji) {
document.addEventListener('click', handleClickOutsideEmojiBox, false);
} else {
document.removeEventListener('click', handleClickOutsideEmojiBox, false);
}
return () => document.removeEventListener('click', handleClickOutsideEmojiBox, false);
}, [previewEmoji]);
useEffect(() => {
//TextBox and message body height controlling
isMountedRef.current = true;
let textAreaPreviousHeight = textAreaInitialHeight;
const autoExpand = function(field) {
// Reset field height
field.style.height = '2rem';
// Calculate the height
const textAreaCurrentHeight = field.scrollHeight;
if (textAreaCurrentHeight <= 160 && document.querySelector('.card-chat-pane')) {
if (textAreaPreviousHeight !== textAreaCurrentHeight && isMountedRef.current) {
document.querySelector('.card-chat-pane').style.height = `calc(100% - ${textAreaCurrentHeight}px)`;
setTextAreaInitialHeight((textAreaPreviousHeight = textAreaCurrentHeight));
}
}
field.style.height = textAreaCurrentHeight + 'px';
};
if (document.querySelector('.textarea')) {
document.addEventListener(
'input',
function(event) {
if (event.target.className === 'textarea');
autoExpand(event.target);
},
false
);
}
return () => {
isMountedRef.current = false;
};
}, [textAreaInitialHeight, setTextAreaInitialHeight]);
const addEmoji = e => {
let emoji = e.native;
setMessage(message + emoji);
};
const handleSubmit = e => {
e.preventDefault();
const date = new Date();
let newMessage = {
senderUserId: 3,
message: `${message.replace(/(?:\r\n|\r|\n)/g, '<br>')}`,
status: 'delivered',
time: formatDate(date)
};
const { content } = messages.find(({ id }) => id === thread.messagesId);
if (message) {
messagesDispatch({
type: 'EDIT',
payload: { id: thread.messagesId, content: [...content, newMessage] },
id: thread.messagesId
});
threadsDispatch({
type: 'EDIT',
payload: thread,
id: thread.id,
isUpdatedStart: true
});
}
setMessage('');
document.querySelector('.textarea').style.height = '2rem';
document.querySelector('.card-chat-pane').style.height = `calc(100% - 2rem)`;
};
return (
<Form className="chat-editor-area bg-white" onSubmit={handleSubmit}>
<Input className="d-none" type="file" id="chat-file-upload" />
<Label for="chat-file-upload" className="mb-0 p-1 chat-file-upload cursor-pointer">
<FontAwesomeIcon icon="paperclip" />
</Label>
<Input
className="border-0 outline-none shadow-none resize-none textarea bg-white"
type="textarea"
placeholder="Type your message"
bsSize="sm"
value={message}
onChange={({ target }) => setMessage(target.value)}
style={{
height: '2rem',
maxHeight: '10rem',
paddingRight: isRTL ? '0.75rem' : '7rem',
paddingLeft: isRTL ? '7rem' : '0.75rem'
}}
/>
<FontAwesomeIcon
icon={['far', 'laugh-beam']}
transform="grow-5"
className="emoji-icon"
onClick={() => setPreviewEmoji(!previewEmoji)}
/>
{previewEmoji && (
<Picker
set="google"
onSelect={addEmoji}
sheetSize={20}
style={{
position: 'absolute',
bottom: '100%',
left: isRTL ? '2%' : 'auto',
right: isRTL ? 'auto' : '2%',
padding: 0,
zIndex: 1,
backgroundColor: getGrays(isDark)[100]
}}
theme={isDark ? 'dark' : 'light'}
showPreview={false}
showSkinTones={false}
/>
)}
<Button
color="transparent"
size="sm"
className={classNames(`btn-send outline-none ml-1`, {
'text-primary': message.length > 0
})}
type="submit"
>
Send
</Button>
</Form>
);
};
MessageTextArea.propTypes = {
thread: PropTypes.object.isRequired
};
export default MessageTextArea;