|
@@ -1,6 +1,7 @@
|
|
|
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 AttachFileIcon from '@mui/icons-material/AttachFile';
|
|
|
import SentimentSatisfiedAltIcon from '@mui/icons-material/SentimentSatisfiedAlt';
|
|
|
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
|
@@ -117,6 +118,19 @@ const useStyles = makeStyles({
|
|
|
color: '#ffffff',
|
|
|
}
|
|
|
},
|
|
|
+ avatarCamera: {
|
|
|
+ position: 'absolute',
|
|
|
+ left:-65,
|
|
|
+ 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',
|
|
|
+ }
|
|
|
+ },
|
|
|
avatarArrow: {
|
|
|
left: 120,
|
|
|
bottom:200,
|
|
@@ -127,12 +141,11 @@ const useStyles = makeStyles({
|
|
|
},
|
|
|
iconCancel: {
|
|
|
position: 'absolute',
|
|
|
- left:-45,
|
|
|
+ left:-65,
|
|
|
display:'flex',
|
|
|
- backgroundColor: '#945353',
|
|
|
- width: 56,
|
|
|
- height: 56,
|
|
|
- color: '#6b6b6b',
|
|
|
+ backgroundColor: '#ffffff',
|
|
|
+ color: 'rgb(218, 18, 18)',
|
|
|
+ border:'solid 4px rgb(218, 18, 18)',
|
|
|
borderRadius: '50%',
|
|
|
'&:hover': {
|
|
|
backgroundColor: 'rgb(218, 18, 18)',
|
|
@@ -146,7 +159,7 @@ const useStyles = makeStyles({
|
|
|
width: '100vw',
|
|
|
height: '100vh',
|
|
|
zIndex:100
|
|
|
- },
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
interface ISendMessage{
|
|
@@ -163,40 +176,62 @@ const SendMessage = ({isArrow,handleScrollTo}:ISendMessage) => {
|
|
|
const [isOpenMenu, setIsOpenMenu] = useState<boolean>(false)
|
|
|
const [isOpenEmoji, setIsOpenEmoji] = useState<boolean>(false)
|
|
|
const [isRecording, setIsRecording] = useState<boolean>(false)
|
|
|
+ const [isFilming, setIsFilming] = useState<boolean>(false)
|
|
|
const [type, setType] = useState<string>('')
|
|
|
const { status, startRecording, stopRecording, mediaBlobUrl, clearBlobUrl } = useReactMediaRecorder({ audio: true });
|
|
|
+ const { status: _status, startRecording: _startRecording, stopRecording: _stopRecording,
|
|
|
+ mediaBlobUrl: _mediaBlobUrl,clearBlobUrl:_clearBlobUrl } = useReactMediaRecorder({ video: true });
|
|
|
const handleClearMessage = () => {
|
|
|
file && setFile(null)
|
|
|
- isRecording&&setIsRecording(false)
|
|
|
+ isRecording && setIsRecording(false)
|
|
|
+ isFilming&&setIsFilming(false)
|
|
|
value&&setValue('')
|
|
|
type && setType('')
|
|
|
mediaBlobUrl && clearBlobUrl()
|
|
|
+ _mediaBlobUrl && _clearBlobUrl()
|
|
|
isOpenMenu&&setIsOpenMenu(false)
|
|
|
isOpenEmoji && setIsOpenEmoji(false)
|
|
|
}
|
|
|
const sentMessage = async () => {
|
|
|
if (value) sentMessageById(companionId, value)
|
|
|
- if (mediaBlobUrl && type) {
|
|
|
- if (type === 'recording') {
|
|
|
+ if (mediaBlobUrl && type === 'recording') {
|
|
|
const audio = new XMLHttpRequest();
|
|
|
audio.open('GET', mediaBlobUrl, true);
|
|
|
- audio.responseType = 'blob';
|
|
|
- audio.onload = () => {
|
|
|
- if (audio.status === 200) {
|
|
|
- const name = `audioMessage${new Date().getSeconds()}.mp3`
|
|
|
- const blob = audio.response
|
|
|
- const file = new File([blob], name, {
|
|
|
- type: 'audio/mpeg'
|
|
|
- })
|
|
|
- const formData: any = new FormData()
|
|
|
- formData.append("audio", file)
|
|
|
- sentAudioMessageById(companionId, formData)
|
|
|
- clearBlobUrl()
|
|
|
- }
|
|
|
- }
|
|
|
+ audio.responseType = 'blob';
|
|
|
+ audio.onload = () => {
|
|
|
+ if (audio.status === 200) {
|
|
|
+ const name = `audioMessage${new Date().getSeconds()}.mp3`
|
|
|
+ const blob = audio.response
|
|
|
+ const file = new File([blob], name, {
|
|
|
+ type: 'audio/mpeg'
|
|
|
+ })
|
|
|
+ const formData: any = new FormData()
|
|
|
+ formData.append("audio", file)
|
|
|
+ sentAudioMessageById(companionId, formData)
|
|
|
+ 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 name = `videoMessage${new Date().getSeconds()}.mp4`
|
|
|
+ const blob = video.response
|
|
|
+ const file = new File([blob], name, {
|
|
|
+ type: 'video/mp4'
|
|
|
+ })
|
|
|
+ const formData: any = new FormData()
|
|
|
+ formData.append("video", file)
|
|
|
+ sentVideoMessageById(companionId, formData)
|
|
|
+ _clearBlobUrl()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ video.send();
|
|
|
+ }
|
|
|
if (file && type) {
|
|
|
if (file.type.includes('image') && type === 'content') {
|
|
|
const formData: any = new FormData()
|
|
@@ -247,18 +282,29 @@ const SendMessage = ({isArrow,handleScrollTo}:ISendMessage) => {
|
|
|
setIsRecording(true)
|
|
|
}
|
|
|
}
|
|
|
+ const handleFilming = () => {
|
|
|
+ if (isFilming) {
|
|
|
+ _stopRecording()
|
|
|
+ } else {
|
|
|
+ _startRecording()
|
|
|
+ setType('filming')
|
|
|
+ setIsFilming(true)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return (
|
|
|
<div className={classes.container} style={{borderTop:isArrow?'solid 1px #ffffff':'none'}} >
|
|
|
<div onKeyPress={handleKeyPres} className={classes.inputContainer}>
|
|
|
<CloseIcon onClick={handleClearMessage} fontSize="small" className={classes.iconCancel}
|
|
|
- sx={{backgroundColor: '#ffffff', width: 36, height: 36, color: '#949393',
|
|
|
- display: file || value || status === 'stopped' ? 'inline-block' : 'none'}} />
|
|
|
+ sx={{width: 56, height: 56, display: file || value || status === 'stopped'
|
|
|
+ || _status === 'stopped' ? 'inline-block' : 'none'}} />
|
|
|
+ <VideocamIcon onClick={handleFilming} className={classes.avatarCamera}
|
|
|
+ sx={{ backgroundColor: '#ffffff', color: '#7c7c7c', width: 56, height: 56 }}
|
|
|
+ style={{animation: isFilming ? 'ripple 1.5s infinite ease-in-out' : 'none',
|
|
|
+ display: status !== 'idle' || _status === 'stopped' || file || value ? 'none':'block'}} />
|
|
|
<SentimentSatisfiedAltIcon onClick={handleOpenEmoji}
|
|
|
- fontSize='medium' sx={{
|
|
|
- color: isOpenEmoji ? 'rgb(41, 139, 231)' : '#6b6b6b', cursor: 'pointer',
|
|
|
- '&:hover': { color: 'rgb(41, 139, 231)' }
|
|
|
- }} />
|
|
|
+ fontSize='medium' sx={{color: isOpenEmoji ? 'rgb(41, 139, 231)' : '#6b6b6b', cursor: 'pointer',
|
|
|
+ '&:hover': { color: 'rgb(41, 139, 231)'}}}/>
|
|
|
<div onClick={handleCloseEmoji} className={classes.overlay} id='overlay'
|
|
|
style={{ display: isOpenEmoji ? 'block':'none'}}>
|
|
|
<div className={classes.emoji} style={{left: isOpen&&isOpen !== 'menu'?'31%':'44%'}}>
|
|
@@ -267,8 +313,8 @@ const SendMessage = ({isArrow,handleScrollTo}:ISendMessage) => {
|
|
|
</div>
|
|
|
<textarea disabled={file ? true : false} value={value} onBlur={handleBlurTextarea}
|
|
|
onFocus={handleFocusTextarea} onChange={handleTextarea} className={classes.textarea}
|
|
|
- placeholder={file ? 'The File is ready to send' : status === 'idle' ? 'Message' :
|
|
|
- `${status === 'recording'?'Recording':'Audio message Recorded'}`} rows={1}>
|
|
|
+ placeholder={file ? 'The File is ready to send' : status === 'idle' && _status === 'idle' ? 'Message ' :
|
|
|
+ `${status === 'stopped' || _status === 'stopped' ?'Recorded':'Recording in progress'}`} rows={1}>
|
|
|
</textarea>
|
|
|
<AttachFileIcon onClick={handleOpenFileMenu} className={classes.attachIcon}
|
|
|
fontSize='medium' sx={{
|
|
@@ -287,19 +333,17 @@ const SendMessage = ({isArrow,handleScrollTo}:ISendMessage) => {
|
|
|
<ArrowDownwardIcon fontSize="medium" />
|
|
|
</Avatar>
|
|
|
</div>
|
|
|
- {value || file || mediaBlobUrl ?
|
|
|
+ {value || file || mediaBlobUrl || _mediaBlobUrl ?
|
|
|
<Avatar onClick={sentMessage} className={classes.avatar} sx={{
|
|
|
- backgroundColor: '#ffffff', width: 56, height: 56, color: 'rgb(41, 139, 231)',
|
|
|
- }}>
|
|
|
- <SendIcon fontSize="medium" />
|
|
|
+ backgroundColor: '#ffffff',color: 'rgb(41, 139, 231)', width: 56, height: 56}}>
|
|
|
+ <SendIcon fontSize="medium" />
|
|
|
</Avatar> :
|
|
|
<Avatar onClick={handleRecording} className={!isRecording ? classes.avatar : undefined}
|
|
|
sx={{backgroundColor: isRecording ? 'rgb(41, 139, 231)' : '#ffffff',
|
|
|
color: isRecording ? '#ffffff' : '#6b6b6b', width: 56, height: 56}}
|
|
|
- style={{animation: isRecording ? 'ripple 1.5s infinite ease-in-out' : 'none',
|
|
|
- border: isRecording?'solid 5px #ffffff':'none'}}>
|
|
|
- <MicNoneIcon fontSize="medium" />
|
|
|
- </Avatar>}
|
|
|
+ style={{animation: isRecording ? 'ripple 1.5s infinite ease-in-out' : 'none'}}>
|
|
|
+ <MicNoneIcon fontSize="medium" />
|
|
|
+ </Avatar>}
|
|
|
</div>
|
|
|
)
|
|
|
}
|