import { makeStyles } from "@material-ui/core/styles"; import SendIcon from '@mui/icons-material/Send'; import MicNoneIcon from '@mui/icons-material/MicNone'; import VideocamIcon from '@mui/icons-material/Videocam'; import PauseIcon from '@mui/icons-material/Pause'; import AttachFileIcon from '@mui/icons-material/AttachFile'; import SentimentSatisfiedAltIcon from '@mui/icons-material/SentimentSatisfiedAlt'; import CloseIcon from '@mui/icons-material/Close'; import CommentIcon from '@mui/icons-material/Comment'; import Avatar from '@mui/material/Avatar'; import TextField from '@mui/material/TextField'; import Picker from 'emoji-picker-react'; import { useReactMediaRecorder } from "react-media-recorder"; import { useState } from "react"; import { useSelector } from "react-redux"; import FilesMenu from "../FilesMenu"; import { sentMessageById, sentImgMessageById, sentAudioMessageById, sentVideoMessageById,sentFileMessageById } from '../../../../../api-data' import { getChat } from '../../../../../redux/chat/selector' import { getRightIsOpen } from '../../../../../redux/control/selector' import { playNotification,prodBaseURL } from "../../../../../helpers"; import { typingChat } from "../../../../../api-data"; const useStyles = makeStyles({ container: { width: '35vw', height:'6vh', position: 'fixed', bottom: '2vh', borderRadius: 8, padding: 10, display: 'flex', flexWrap: 'nowrap', alignContent: 'start', alignItems: 'start', color: '#6b6b6b', border:'solid 2px #ffffff', backgroundColor: '#ffffff', }, containerActive: { width: '35vw', height:'6vh', position: 'fixed', bottom: '2vh', borderRadius: 8, padding: 10, display: 'flex', flexWrap: 'nowrap', alignContent: 'start', alignItems: 'start', border:'solid 2px rgb(41, 139, 231)', backgroundColor: '#ffffff', }, textarea: { width: '100%', height: '100%', outline: 'none', border:'none', padding: '0px 10px', marginLeft: 8, marginRight: 8, overflowY:'auto', resize: 'none', '&::placeholder': { color: 'inherit', fontWeight: 600, fontSize:20 } }, attachIcon: { transform:'rotate(30deg)', }, borderTop: { position: 'absolute', left: 0, top: '-2vh', width: '100%', height: 1, background:'#ffffff', }, filesMenu: { background: '#fdfdfd', position: 'absolute', width: '15vw', maxWidth: '100%', left: '61%', bottom:'10vh', zIndex: 10, visibility: 'visible', borderRadius: 10, padding: '4px 6px', }, emoji: { position: 'absolute', bottom:'10vh', zIndex: 10, visibility: 'visible', }, captionTextField: { position: 'absolute', bottom:'10vh', zIndex: 10, visibility: 'visible', backgroundColor: '#ffffff', padding: 10, borderRadius: 10, width: '20vw', }, iconCancel: { position: 'absolute', left: -72, bottom:-1, display:'flex', backgroundColor: '#ffffff', color: 'rgb(243, 69, 69)', border:'solid 4px rgb(243, 69, 69)', borderRadius: '50%', '&:hover': { backgroundColor: 'rgb(243, 69, 69)', color: '#ffffff', } }, avatarCamera: { position: 'absolute', left: -72, bottom:-1, display: 'flex', borderRadius: '50%', zIndex: 10, border: 'solid 14px #ffffff', '&:hover': { backgroundColor: 'rgb(41, 139, 231)', border:'solid 14px rgb(41, 139, 231)', color: '#ffffff', } }, avatarRight: { position: 'absolute', right: -72, bottom:-1, display: 'flex', borderRadius: '50%', zIndex: 10, border: 'solid 14px #ffffff', '&:hover': { backgroundColor: 'rgb(41, 139, 231)', border:'solid 14px rgb(41, 139, 231)', color: '#ffffff' } }, pauseLeft: { position: 'absolute', left: -72, bottom:-1, zIndex: 10, }, pauseRight: { position: 'absolute', right: -72, bottom:-1, zIndex: 10, }, avatarPause: { backgroundColor: '#ffffff', cursor: 'pointer', animation: `$shake 1s`, animationIterationCount:'infinite', '&:hover': { backgroundColor: 'rgb(41, 139, 231)', color: '#ffffff', } }, overlay: { position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh', zIndex:100 }, ringContainerLeft: { position: 'absolute', left: -25, top: -25, zIndex: 10, }, ringContainerRight: { position: 'absolute', right: -25, top: -25, zIndex: 10, }, circle: { width: 15, height: 15, backgroundColor: 'rgb(255, 4, 4)', borderRadius: '50%', position: 'relative' }, ringRing: { border: '3px solid rgb(255, 4, 4)', borderRadius: '50%', height: 25, width: 25, position: 'absolute', right: -5, top: -5, animation: `$pulsate 1s ease-out`, animationIterationCount: 'infinite', opacity: 0 }, '@keyframes pulsate': { '0%': {transform: 'scale(0.1, 0.1)', opacity: 0}, '50%': { opacity: 1}, '100%': {transform: 'scale(1.2, 1.2)', opacity: 0}, }, '@keyframes shake': { '0%': { transform: 'translate(0.5px, 0.5px) rotate(0deg)'}, '10%': { transform: 'translate(-0.5px, -1px) rotate(-1deg)'}, '20%': { transform: 'translate(-1.5px, 0px) rotate(1deg)'}, '30%': { transform: 'translate(1.5px, 1px) rotate(0deg)'}, '40%': { transform: 'translate(0.5px, -0.5px) rotate(1deg)'}, '50%': { transform: 'translate(-0.5px, 1px) rotate(-1deg)'}, '60%': { transform: 'translate(-1.5px, 0.5px) rotate(0deg)'}, '70%': { transform: 'translate(1.5px, 0.5px) rotate(-1deg)'}, '80%': { transform: 'translate(-0.5px, -0.5px) rotate(1deg)'}, '90%': { transform: 'translate(0.5px, 1px) rotate(0deg)'}, '100%': { transform: 'translate(0.5px, -1px) rotate(-1deg)'}, }, }); interface ISendMessage{ isArrow: boolean, } const SendMessage = ({isArrow }:ISendMessage) => { const classes = useStyles(); const { companionId } = useSelector(getChat) const rightIsOpen = useSelector(getRightIsOpen) const [value, setValue] = useState('') const [file, setFile] = useState(false) const [caption, setCaption] = useState('') const [isOpenCaption, setIsOpenCaption] = useState(false) const [isOpenMenu, setIsOpenMenu] = useState(false) const [isOpenEmoji, setIsOpenEmoji] = useState(false) const [isRecording, setIsRecording] = useState(false) const [isFilming, setIsFilming] = useState(false) const [type, setType] = useState('') const { status, startRecording, stopRecording, mediaBlobUrl, clearBlobUrl } = useReactMediaRecorder({ audio: true,blobPropertyBag:{type: "audio/mp3"}}); const { status: _status, startRecording: _startRecording, stopRecording: _stopRecording, mediaBlobUrl: _mediaBlobUrl, clearBlobUrl: _clearBlobUrl } = useReactMediaRecorder({ video: true,blobPropertyBag:{type: "video/mp4"}}); const onEmojiClick = (_e:any, emojiObject:any) => { setValue(prevValue => prevValue + emojiObject.emoji) setIsOpenEmoji(false) }; const clearMessage = () => { file &&setFile(false) isRecording && setIsRecording(false) isFilming && setIsFilming(false) value && setValue('') caption&& setCaption('') type && setType('') mediaBlobUrl && clearBlobUrl() _mediaBlobUrl && _clearBlobUrl() isOpenMenu && setIsOpenMenu(false) isOpenEmoji && setIsOpenEmoji(false) isOpenCaption && setIsOpenCaption(false) } const sentMessage = async () => { if (value) sentMessageById(companionId, value,caption.trim()) if (mediaBlobUrl && type === 'recording') { const audio = new XMLHttpRequest(); audio.open('GET', mediaBlobUrl, true); audio.responseType = 'blob'; audio.onload = () => { if (audio.status === 200) { const blob = audio.response const file = new File([blob], 'audio.mp3', { type: 'audio/mpeg' }) const formData: any = new FormData() formData.append("audio", file) sentAudioMessageById(companionId, formData,caption.trim()) clearBlobUrl() } } audio.send(); } if (_mediaBlobUrl && type === 'filming') { const video = new XMLHttpRequest(); video.open('GET', _mediaBlobUrl, true); video.responseType = 'blob'; video.onload = () => { if (video.status === 200) { const blob = video.response const file = new File([blob], 'video.mp4',{ type: "video/mp4" }) const formData: any = new FormData() formData.append("video", file) sentVideoMessageById(companionId, formData,caption.trim()) _clearBlobUrl() } } video.send(); } if (file && type) { if (file.type.includes('image') && type === 'content') { const formData: any = new FormData() formData.append("image", file); await sentImgMessageById(companionId, formData, caption.trim()) } if (file.type.includes('audio') && type === 'content') { const formData: any = new FormData() formData.append("audio", file); sentAudioMessageById(companionId, formData,caption.trim()) } if (file.type.includes('video') && type === 'content') { const formData: any = new FormData() formData.append("video", file); sentVideoMessageById(companionId, formData,caption.trim()) } if (file.type.includes('application') && type === 'application') { const formData: any = new FormData() formData.append("file", file); sentFileMessageById(companionId, formData,caption.trim()) } } clearMessage() playNotification(`${prodBaseURL}/send.mp3`) } const handleTextarea = (e: React.ChangeEvent) => setValue(e.target.value) const handleTextareaCaption = (e: React.ChangeEvent) => { if (caption.length >= 25) setCaption(e.target.value.slice(0,-1)) else setCaption(e.target.value) } const handleFocusTextarea = async () => await typingChat(companionId,true) const handleBlurTextarea = async () => await typingChat(companionId,false) const handleOpenFileMenu = () => !isOpenMenu&&setIsOpenMenu(true) const handleCloseFileMenu = (e:any) => e.target.id === 'overlay'&&isOpenMenu&&setIsOpenMenu(false) const handleOpenEmoji = () => !isOpenEmoji && setIsOpenEmoji(true) const handleCloseEmoji = (e: any) => e.target.id === 'overlay' && isOpenEmoji && setIsOpenEmoji(false) const handleOpenCaption = () => !isOpenCaption && setIsOpenCaption(true) const handleCloseCaption = (e: any) => e.target.id === 'overlay' && isOpenCaption && setIsOpenCaption(false) const handleRecording = () => { if (isRecording) return stopRecording() startRecording() setType('recording') setIsRecording(true) } const handleFilming = () => { if (isFilming) return _stopRecording() _startRecording() setType('filming') setIsFilming(true) } return (
{isArrow &&
} {isFilming && _status !== 'stopped' && <>
} {isRecording && status !== 'stopped' && <>
}
) } export default SendMessage