|
@@ -46,29 +46,7 @@ const useStyles = makeStyles({
|
|
backgroundColor: '#ffffff',
|
|
backgroundColor: '#ffffff',
|
|
borderRadius: 8,
|
|
borderRadius: 8,
|
|
padding: 10,
|
|
padding: 10,
|
|
- marginRight: 10,
|
|
|
|
- "&:after": {
|
|
|
|
- content: "''",
|
|
|
|
- position: "absolute",
|
|
|
|
- width: "0",
|
|
|
|
- height: "0",
|
|
|
|
- borderBottom: "15px solid #ffffff",
|
|
|
|
- borderLeft: "15px solid transparent",
|
|
|
|
- borderRight: "15px solid transparent",
|
|
|
|
- bottom: "0",
|
|
|
|
- right: "-15px"
|
|
|
|
- },
|
|
|
|
- "&:before": {
|
|
|
|
- content: "''",
|
|
|
|
- position: "absolute",
|
|
|
|
- width: "0",
|
|
|
|
- height: "0",
|
|
|
|
- borderBottom: "17px solid #ffffff",
|
|
|
|
- borderLeft: "16px solid transparent",
|
|
|
|
- borderRight: "16px solid transparent",
|
|
|
|
- bottom: "0px",
|
|
|
|
- right: "-17px"
|
|
|
|
- }
|
|
|
|
|
|
+ marginRight: 15,
|
|
},
|
|
},
|
|
textarea: {
|
|
textarea: {
|
|
minWidth: 550,
|
|
minWidth: 550,
|
|
@@ -111,7 +89,21 @@ const useStyles = makeStyles({
|
|
visibility: 'visible',
|
|
visibility: 'visible',
|
|
borderRadius: 10,
|
|
borderRadius: 10,
|
|
padding: '0px 6px',
|
|
padding: '0px 6px',
|
|
- },
|
|
|
|
|
|
+ },
|
|
|
|
+ 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',
|
|
|
|
+ }
|
|
|
|
+ },
|
|
avatar: {
|
|
avatar: {
|
|
'&:hover': {
|
|
'&:hover': {
|
|
backgroundColor: 'rgb(41, 139, 231)',
|
|
backgroundColor: 'rgb(41, 139, 231)',
|
|
@@ -120,7 +112,8 @@ const useStyles = makeStyles({
|
|
},
|
|
},
|
|
avatarCamera: {
|
|
avatarCamera: {
|
|
position: 'absolute',
|
|
position: 'absolute',
|
|
- left:-65,
|
|
|
|
|
|
+ left: -72,
|
|
|
|
+ bottom:-1,
|
|
display: 'flex',
|
|
display: 'flex',
|
|
borderRadius: '50%',
|
|
borderRadius: '50%',
|
|
zIndex: 10,
|
|
zIndex: 10,
|
|
@@ -130,7 +123,7 @@ const useStyles = makeStyles({
|
|
border:'solid 14px rgb(41, 139, 231)',
|
|
border:'solid 14px rgb(41, 139, 231)',
|
|
color: '#ffffff',
|
|
color: '#ffffff',
|
|
}
|
|
}
|
|
- },
|
|
|
|
|
|
+ },
|
|
avatarArrowWrapper: {
|
|
avatarArrowWrapper: {
|
|
position:'absolute',
|
|
position:'absolute',
|
|
right: -140,
|
|
right: -140,
|
|
@@ -144,11 +137,10 @@ const useStyles = makeStyles({
|
|
color: '#ffffff',
|
|
color: '#ffffff',
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- listSeenIconMute: {
|
|
|
|
|
|
+ listSeenIcon: {
|
|
position: 'absolute',
|
|
position: 'absolute',
|
|
top: -8,
|
|
top: -8,
|
|
left: 16,
|
|
left: 16,
|
|
- background: '#a7aaa7',
|
|
|
|
borderRadius: '50%',
|
|
borderRadius: '50%',
|
|
color: '#ffffff',
|
|
color: '#ffffff',
|
|
border: 'none',
|
|
border: 'none',
|
|
@@ -162,39 +154,7 @@ const useStyles = makeStyles({
|
|
fontSize: 12,
|
|
fontSize: 12,
|
|
zIndex: 10,
|
|
zIndex: 10,
|
|
cursor:'pointer',
|
|
cursor:'pointer',
|
|
- },
|
|
|
|
- listSeenIcon: {
|
|
|
|
- position: 'absolute',
|
|
|
|
- top: -8,
|
|
|
|
- left: 16,
|
|
|
|
- background: '#0ac40a',
|
|
|
|
- borderRadius: '50%',
|
|
|
|
- color: '#ffffff',
|
|
|
|
- border: 'none',
|
|
|
|
- height: 24,
|
|
|
|
- width: 24,
|
|
|
|
- textAlign: 'center',
|
|
|
|
- display: 'flex',
|
|
|
|
- alignItems: 'center',
|
|
|
|
- justifyContent: 'center',
|
|
|
|
- alignContent: 'center',
|
|
|
|
- fontSize: 12,
|
|
|
|
- zIndex: 10,
|
|
|
|
- cursor:'pointer'
|
|
|
|
- },
|
|
|
|
- iconCancel: {
|
|
|
|
- position: 'absolute',
|
|
|
|
- left:-65,
|
|
|
|
- display:'flex',
|
|
|
|
- backgroundColor: '#ffffff',
|
|
|
|
- color: 'rgb(218, 18, 18)',
|
|
|
|
- border:'solid 4px rgb(218, 18, 18)',
|
|
|
|
- borderRadius: '50%',
|
|
|
|
- '&:hover': {
|
|
|
|
- backgroundColor: 'rgb(218, 18, 18)',
|
|
|
|
- color: '#ffffff',
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
|
|
+ },
|
|
overlay: {
|
|
overlay: {
|
|
position: 'fixed',
|
|
position: 'fixed',
|
|
top: 0,
|
|
top: 0,
|
|
@@ -202,7 +162,7 @@ const useStyles = makeStyles({
|
|
width: '100vw',
|
|
width: '100vw',
|
|
height: '100vh',
|
|
height: '100vh',
|
|
zIndex:100
|
|
zIndex:100
|
|
- },
|
|
|
|
|
|
+ },
|
|
});
|
|
});
|
|
|
|
|
|
interface ISendMessage{
|
|
interface ISendMessage{
|
|
@@ -216,7 +176,7 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
const { companionId } = useSelector(getChat)
|
|
const { companionId } = useSelector(getChat)
|
|
const isOpen = useSelector(getIsOpen)
|
|
const isOpen = useSelector(getIsOpen)
|
|
const [value, setValue] = useState<string>('')
|
|
const [value, setValue] = useState<string>('')
|
|
- const [file, setFile] = useState<any>(null)
|
|
|
|
|
|
+ const [file, setFile] = useState<any>(false)
|
|
const [isOpenMenu, setIsOpenMenu] = useState<boolean>(false)
|
|
const [isOpenMenu, setIsOpenMenu] = useState<boolean>(false)
|
|
const [isOpenEmoji, setIsOpenEmoji] = useState<boolean>(false)
|
|
const [isOpenEmoji, setIsOpenEmoji] = useState<boolean>(false)
|
|
const [isRecording, setIsRecording] = useState<boolean>(false)
|
|
const [isRecording, setIsRecording] = useState<boolean>(false)
|
|
@@ -225,17 +185,17 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
const { status, startRecording, stopRecording, mediaBlobUrl, clearBlobUrl } = useReactMediaRecorder({ audio: true });
|
|
const { status, startRecording, stopRecording, mediaBlobUrl, clearBlobUrl } = useReactMediaRecorder({ audio: true });
|
|
const { status: _status, startRecording: _startRecording, stopRecording: _stopRecording,
|
|
const { status: _status, startRecording: _startRecording, stopRecording: _stopRecording,
|
|
mediaBlobUrl: _mediaBlobUrl,clearBlobUrl:_clearBlobUrl } = useReactMediaRecorder({ video: true });
|
|
mediaBlobUrl: _mediaBlobUrl,clearBlobUrl:_clearBlobUrl } = useReactMediaRecorder({ video: true });
|
|
- const handleClearMessage = () => {
|
|
|
|
- file && setFile(null)
|
|
|
|
|
|
+ const clearMessage = () => {
|
|
|
|
+ file &&setFile(false)
|
|
isRecording && setIsRecording(false)
|
|
isRecording && setIsRecording(false)
|
|
- isFilming&&setIsFilming(false)
|
|
|
|
- value&&setValue('')
|
|
|
|
|
|
+ isFilming && setIsFilming(false)
|
|
|
|
+ value && setValue('')
|
|
type && setType('')
|
|
type && setType('')
|
|
mediaBlobUrl && clearBlobUrl()
|
|
mediaBlobUrl && clearBlobUrl()
|
|
_mediaBlobUrl && _clearBlobUrl()
|
|
_mediaBlobUrl && _clearBlobUrl()
|
|
- isOpenMenu&&setIsOpenMenu(false)
|
|
|
|
|
|
+ isOpenMenu && setIsOpenMenu(false)
|
|
isOpenEmoji && setIsOpenEmoji(false)
|
|
isOpenEmoji && setIsOpenEmoji(false)
|
|
- handleScrollTo()
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
const sentMessage = async () => {
|
|
const sentMessage = async () => {
|
|
if (value) sentMessageById(companionId, value)
|
|
if (value) sentMessageById(companionId, value)
|
|
@@ -245,7 +205,7 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
audio.responseType = 'blob';
|
|
audio.responseType = 'blob';
|
|
audio.onload = () => {
|
|
audio.onload = () => {
|
|
if (audio.status === 200) {
|
|
if (audio.status === 200) {
|
|
- const name = `audioMessage${new Date().getSeconds()}.mp3`
|
|
|
|
|
|
+ const name = `audioMessage${new Date().getTime()}.mp3`
|
|
const blob = audio.response
|
|
const blob = audio.response
|
|
const file = new File([blob], name, {
|
|
const file = new File([blob], name, {
|
|
type: 'audio/mpeg'
|
|
type: 'audio/mpeg'
|
|
@@ -264,11 +224,12 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
video.responseType = 'blob';
|
|
video.responseType = 'blob';
|
|
video.onload = () => {
|
|
video.onload = () => {
|
|
if (video.status === 200) {
|
|
if (video.status === 200) {
|
|
- const name = `videoMessage${new Date().getSeconds()}.mp4`
|
|
|
|
|
|
+ const name = `videoMessage${new Date().getTime()}.mp4`
|
|
const blob = video.response
|
|
const blob = video.response
|
|
const file = new File([blob], name, {
|
|
const file = new File([blob], name, {
|
|
type: 'video/mp4'
|
|
type: 'video/mp4'
|
|
})
|
|
})
|
|
|
|
+ console.log(blob,file,name)
|
|
const formData: any = new FormData()
|
|
const formData: any = new FormData()
|
|
formData.append("video", file)
|
|
formData.append("video", file)
|
|
sentVideoMessageById(companionId, formData)
|
|
sentVideoMessageById(companionId, formData)
|
|
@@ -299,53 +260,42 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
sentFileMessageById(companionId, formData)
|
|
sentFileMessageById(companionId, formData)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ clearMessage()
|
|
playNotification('http://localhost:3000/send.mp3')
|
|
playNotification('http://localhost:3000/send.mp3')
|
|
- setTimeout(handleClearMessage, 3000);
|
|
|
|
|
|
+ setTimeout(handleScrollTo, 3000);
|
|
}
|
|
}
|
|
- const handleTextarea = (e: React.ChangeEvent<HTMLTextAreaElement>) => setValue(e.target.value)
|
|
|
|
|
|
+ const handleTextarea = (e: React.ChangeEvent<HTMLTextAreaElement>) => setValue(e.target.value.trim())
|
|
const handleFocusTextarea = async () => await typingChat(companionId,true)
|
|
const handleFocusTextarea = async () => await typingChat(companionId,true)
|
|
const handleBlurTextarea = async () => await typingChat(companionId,false)
|
|
const handleBlurTextarea = async () => await typingChat(companionId,false)
|
|
-
|
|
|
|
- const handleKeyPres = (e: any) => {
|
|
|
|
- if(e.code === 'Enter'&& value) sentMessage()
|
|
|
|
- }
|
|
|
|
|
|
+ const handleKeyPres = (e: any) => e.code === 'Enter'&& sentMessage()
|
|
const handleOpenFileMenu = () => !isOpenMenu&&setIsOpenMenu(true)
|
|
const handleOpenFileMenu = () => !isOpenMenu&&setIsOpenMenu(true)
|
|
- const handleCloseFileMenu = (e:any) => {
|
|
|
|
- if (e.target.id === 'overlay'&&isOpenMenu) setIsOpenMenu(false)
|
|
|
|
- }
|
|
|
|
|
|
+ const handleCloseFileMenu = (e:any) => e.target.id === 'overlay'&&isOpenMenu&&setIsOpenMenu(false)
|
|
const handleOpenEmoji = () => !isOpenEmoji&&setIsOpenEmoji(true)
|
|
const handleOpenEmoji = () => !isOpenEmoji&&setIsOpenEmoji(true)
|
|
- const handleCloseEmoji = (e: any) => {
|
|
|
|
- if (e.target.id === 'overlay'&&isOpenEmoji) setIsOpenEmoji(false)
|
|
|
|
- }
|
|
|
|
|
|
+ const handleCloseEmoji = (e: any) => e.target.id === 'overlay'&&isOpenEmoji&&setIsOpenEmoji(false)
|
|
const handleRecording = () => {
|
|
const handleRecording = () => {
|
|
- if (isRecording) {
|
|
|
|
- stopRecording()
|
|
|
|
- } else {
|
|
|
|
- startRecording()
|
|
|
|
- setType('recording')
|
|
|
|
- setIsRecording(true)
|
|
|
|
- }
|
|
|
|
|
|
+ if (isRecording) return stopRecording()
|
|
|
|
+ startRecording()
|
|
|
|
+ setType('recording')
|
|
|
|
+ setIsRecording(true)
|
|
}
|
|
}
|
|
const handleFilming = () => {
|
|
const handleFilming = () => {
|
|
- if (isFilming) {
|
|
|
|
- _stopRecording()
|
|
|
|
- } else {
|
|
|
|
- _startRecording()
|
|
|
|
- setType('filming')
|
|
|
|
- setIsFilming(true)
|
|
|
|
- }
|
|
|
|
|
|
+ if (isFilming) return _stopRecording()
|
|
|
|
+ _startRecording()
|
|
|
|
+ setType('filming')
|
|
|
|
+ setIsFilming(true)
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
return (
|
|
return (
|
|
<div className={classes.container} style={{borderTop:isArrow?'solid 1px #ffffff':'none'}} >
|
|
<div className={classes.container} style={{borderTop:isArrow?'solid 1px #ffffff':'none'}} >
|
|
<div onKeyPress={handleKeyPres} className={classes.inputContainer}>
|
|
<div onKeyPress={handleKeyPres} className={classes.inputContainer}>
|
|
- <CloseIcon onClick={handleClearMessage} fontSize="small" className={classes.iconCancel}
|
|
|
|
|
|
+ <CloseIcon onClick={clearMessage} fontSize="small" className={classes.iconCancel}
|
|
sx={{width: 56, height: 56, display: file || value || status === 'stopped'
|
|
sx={{width: 56, height: 56, display: file || value || status === 'stopped'
|
|
|| _status === 'stopped' ? 'inline-block' : 'none'}} />
|
|
|| _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'}} />
|
|
|
|
|
|
+ <VideocamIcon onClick={handleFilming} className={classes.avatarCamera}
|
|
|
|
+ sx={{backgroundColor: '#ffffff', color: '#7c7c7c', width: 56, height: 56}}
|
|
|
|
+ style={{display: status !== 'idle' || _status === 'stopped' || file || value ? 'none' : 'block',
|
|
|
|
+ animation:isFilming ? 'ripple 1.2s infinite ease-in-out': 'none'}} />
|
|
<SentimentSatisfiedAltIcon onClick={handleOpenEmoji}
|
|
<SentimentSatisfiedAltIcon onClick={handleOpenEmoji}
|
|
fontSize='medium' sx={{color: isOpenEmoji ? 'rgb(41, 139, 231)' : '#6b6b6b', cursor: 'pointer',
|
|
fontSize='medium' sx={{color: isOpenEmoji ? 'rgb(41, 139, 231)' : '#6b6b6b', cursor: 'pointer',
|
|
'&:hover': { color: 'rgb(41, 139, 231)'}}}/>
|
|
'&:hover': { color: 'rgb(41, 139, 231)'}}}/>
|
|
@@ -372,25 +322,26 @@ const SendMessage = ({isArrow,isNew,handleScrollTo}:ISendMessage) => {
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className={classes.avatarArrowWrapper} style={{display: isArrow ? 'block' : 'none'}}>
|
|
<div className={classes.avatarArrowWrapper} style={{display: isArrow ? 'block' : 'none'}}>
|
|
- <button onClick={handleScrollTo} style={{display: isNew.new ? 'block' : 'none'}}
|
|
|
|
- className={isNew.mute ? classes.listSeenIconMute : classes.listSeenIcon}>{isNew.new}</button>
|
|
|
|
|
|
+ <button onClick={handleScrollTo} style={{display: isNew.new ? 'block' : 'none',
|
|
|
|
+ background: isNew.mute ? '#a7aaa7' : '#0ac40a'}}
|
|
|
|
+ className={classes.listSeenIcon}>{isNew.new}</button>
|
|
<Avatar onClick={handleScrollTo} className={classes.avatarArrow}
|
|
<Avatar onClick={handleScrollTo} className={classes.avatarArrow}
|
|
sx={{backgroundColor: '#ffffff', width: 56, height: 56,color: '#6b6b6b'}}>
|
|
sx={{backgroundColor: '#ffffff', width: 56, height: 56,color: '#6b6b6b'}}>
|
|
<ArrowDownwardIcon fontSize="medium" />
|
|
<ArrowDownwardIcon fontSize="medium" />
|
|
</Avatar>
|
|
</Avatar>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- {value || file || mediaBlobUrl || _mediaBlobUrl ?
|
|
|
|
|
|
+ {value || file || status === 'stopped' || _status === 'stopped' ?
|
|
<Avatar onClick={sentMessage} className={classes.avatar} sx={{
|
|
<Avatar onClick={sentMessage} className={classes.avatar} sx={{
|
|
backgroundColor: '#ffffff',color: 'rgb(41, 139, 231)', width: 56, height: 56}}>
|
|
backgroundColor: '#ffffff',color: 'rgb(41, 139, 231)', width: 56, height: 56}}>
|
|
<SendIcon fontSize="medium" />
|
|
<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'}}>
|
|
|
|
- <MicNoneIcon fontSize="medium" />
|
|
|
|
- </Avatar>}
|
|
|
|
|
|
+ </Avatar> : null}
|
|
|
|
+ {!value && !file && status !== 'stopped' && _status === 'idle' ? <Avatar onClick={handleRecording}
|
|
|
|
+ className={classes.avatar} style={{animation:isRecording ? 'ripple 1.2s infinite ease-in-out': 'none'}}
|
|
|
|
+ sx={{backgroundColor: isRecording ? 'rgb(41, 139, 231)' : '#ffffff',
|
|
|
|
+ color: isRecording ? '#ffffff' : '#6b6b6b', width: 56, height: 56}}>
|
|
|
|
+ <MicNoneIcon fontSize="medium" />
|
|
|
|
+ </Avatar>:null}
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|
|
}
|
|
}
|