Update audio recording ui in internal chat

This commit is contained in:
Ilango
2024-01-22 19:03:05 +05:30
parent 7d0ae5286c
commit f384ad9086
2 changed files with 145 additions and 151 deletions
+118 -92
View File
@@ -23,7 +23,7 @@ import {
Typography Typography
} from '@mui/material' } from '@mui/material'
import { useTheme } from '@mui/material/styles' import { useTheme } from '@mui/material/styles'
import { IconDownload, IconSend, IconMicrophone, IconPhotoPlus, IconCircleDot, IconTrash } from '@tabler/icons' import { IconCircleDot, IconDownload, IconSend, IconMicrophone, IconPhotoPlus, IconSquare, IconTrash, IconX } from '@tabler/icons'
import robotPNG from 'assets/images/robot.png' import robotPNG from 'assets/images/robot.png'
import userPNG from 'assets/images/account.png' import userPNG from 'assets/images/account.png'
import audioUploadSVG from 'assets/images/wave-sound.jpg' import audioUploadSVG from 'assets/images/wave-sound.jpg'
@@ -608,41 +608,6 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
})} })}
</Box> </Box>
)} )}
{isRecording && (
<Box className='drop-overlay'>
<div className={'audio-recording-container'}>
<Typography variant='h2'>Recording</Typography>
<div className='recording-control-buttons-container'>
<i className='cancel-recording-button'>
<Button variant='outlined' color='error' onClick={onRecordingCancelled}>
Cancel
</Button>
</i>
<div className='recording-elapsed-time'>
<i className='red-recording-dot'>
<IconCircleDot />
</i>
<p id='elapsed-time'>00:00</p>
</div>
<i className='stop-recording-button'>
<Button variant='outlined' color='primary' onClick={onRecordingStopped}>
Send
</Button>
</i>
</div>
</div>
{recordingNotSupported && (
<div className='overlay hide'>
<div className='browser-not-supporting-audio-recording-box'>
<p>To record audio, use browsers like Chrome and Firefox that support audio recording.</p>
<button type='button' onClick={() => onRecordingCancelled()}>
Ok.
</button>
</div>
</div>
)}
</Box>
)}
<div className={`${isDialog ? 'cloud-dialog' : 'cloud'}`}> <div className={`${isDialog ? 'cloud-dialog' : 'cloud'}`}>
<div ref={ps} id='messagelist' className={'messagelist'}> <div ref={ps} id='messagelist' className={'messagelist'}>
{messages && {messages &&
@@ -829,6 +794,8 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
<Divider /> <Divider />
</div> </div>
<Divider sx={{ width: '100%' }} />
<div className='center'> <div className='center'>
{previews && previews.length > 0 && ( {previews && previews.length > 0 && (
<Box sx={{ width: '100%', mb: 1.5 }}> <Box sx={{ width: '100%', mb: 1.5 }}>
@@ -882,70 +849,129 @@ export const ChatMessage = ({ open, chatflowid, isDialog }) => {
))} ))}
</Box> </Box>
)} )}
<form style={{ width: '100%' }} onSubmit={handleSubmit}> {isRecording ? (
<OutlinedInput <>
inputRef={inputRef} {recordingNotSupported && (
// eslint-disable-next-line <div className='overlay hide'>
autoFocus <div className='browser-not-supporting-audio-recording-box'>
sx={{ width: '100%' }} <p>To record audio, use modern browsers like Chrome or Firefox that support audio recording.</p>
disabled={loading || !chatflowid} <Button
onKeyDown={handleEnter} variant='contained'
id='userInput' color='error'
name='userInput' size='small'
placeholder={loading ? 'Waiting for response...' : 'Type your question...'} type='button'
value={userInput} onClick={() => onRecordingCancelled()}
onChange={onChange} >
multiline={true} Okay
maxRows={isDialog ? 7 : 2} </Button>
startAdornment={ </div>
isChatFlowAvailableForUploads && ( </div>
<InputAdornment position='start' sx={{ pl: 2 }}> )}
<IconButton onClick={handleUploadClick} type='button' disabled={loading || !chatflowid} edge='start'> <Box
<IconPhotoPlus sx={{
color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'} width: '100%',
/> height: '54px',
</IconButton> px: 2,
</InputAdornment> borderRadius: 1.5,
) backgroundColor: '#32353b',
} display: 'flex',
endAdornment={ alignItems: 'center',
<> justifyContent: 'space-between'
{isChatFlowAvailableForUploads && ( }}
<InputAdornment position='end'> >
<div className='recording-elapsed-time'>
<i className='red-recording-dot'>
<IconCircleDot />
</i>
<p id='elapsed-time'>00:00</p>
</div>
<div className='recording-control-buttons-container'>
<IconButton onClick={onRecordingCancelled} size='small'>
<IconX color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'} />
</IconButton>
<IconButton onClick={onRecordingStopped} size='small'>
<IconSquare
color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'}
/>
</IconButton>
</div>
</Box>
</>
) : (
<form style={{ width: '100%' }} onSubmit={handleSubmit}>
<OutlinedInput
inputRef={inputRef}
// eslint-disable-next-line
autoFocus
sx={{ width: '100%' }}
disabled={loading || !chatflowid}
onKeyDown={handleEnter}
id='userInput'
name='userInput'
placeholder={loading ? 'Waiting for response...' : 'Type your question...'}
value={userInput}
onChange={onChange}
multiline={true}
maxRows={isDialog ? 7 : 2}
startAdornment={
isChatFlowAvailableForUploads && (
<InputAdornment position='start' sx={{ pl: 2 }}>
<IconButton <IconButton
onClick={() => onMicrophonePressed()} onClick={handleUploadClick}
type='button' type='button'
disabled={loading || !chatflowid} disabled={loading || !chatflowid}
edge='end' edge='start'
> >
<IconMicrophone <IconPhotoPlus
className={'start-recording-button'}
color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'} color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'}
/> />
</IconButton> </IconButton>
</InputAdornment> </InputAdornment>
)} )
<InputAdornment position='end' sx={{ padding: '15px' }}> }
<IconButton type='submit' disabled={loading || !chatflowid} edge='end'> endAdornment={
{loading ? ( <>
<div> {isChatFlowAvailableForUploads && (
<CircularProgress color='inherit' size={20} /> <InputAdornment position='end'>
</div> <IconButton
) : ( onClick={() => onMicrophonePressed()}
// Send icon SVG in input field type='button'
<IconSend disabled={loading || !chatflowid}
color={loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'} edge='end'
/> >
)} <IconMicrophone
</IconButton> className={'start-recording-button'}
</InputAdornment> color={
</> loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'
} }
/> />
{isChatFlowAvailableForUploads && ( </IconButton>
<input style={{ display: 'none' }} multiple ref={fileUploadRef} type='file' onChange={handleFileChange} /> </InputAdornment>
)} )}
</form> <InputAdornment position='end' sx={{ padding: '15px' }}>
<IconButton type='submit' disabled={loading || !chatflowid} edge='end'>
{loading ? (
<div>
<CircularProgress color='inherit' size={20} />
</div>
) : (
// Send icon SVG in input field
<IconSend
color={
loading || !chatflowid ? '#9e9e9e' : customization.isDarkMode ? 'white' : '#1e88e5'
}
/>
)}
</IconButton>
</InputAdornment>
</>
}
/>
{isChatFlowAvailableForUploads && (
<input style={{ display: 'none' }} multiple ref={fileUploadRef} type='file' onChange={handleFileChange} />
)}
</form>
)}
</div> </div>
<SourceDocDialog show={sourceDialogOpen} dialogProps={sourceDialogProps} onCancel={() => setSourceDialogOpen(false)} /> <SourceDocDialog show={sourceDialogOpen} dialogProps={sourceDialogProps} onCancel={() => setSourceDialogOpen(false)} />
</div> </div>
@@ -8,20 +8,6 @@
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
.audio-recording-container {
width: 100%;
/* view port height*/
/*targeting Chrome & Safari*/
display: -webkit-flex;
/*targeting IE10*/
display: -ms-flex;
display: flex;
flex-direction: column;
justify-content: center;
/*horizontal centering*/
align-items: center;
background-color: white;
}
.start-recording-button { .start-recording-button {
font-size: 70px; font-size: 70px;
color: #435f7a; color: #435f7a;
@@ -36,34 +22,13 @@
/*targeting IE10*/ /*targeting IE10*/
display: -ms-flex; display: -ms-flex;
display: flex; display: flex;
justify-content: space-evenly; justify-content: center;
/*horizontal centering*/ /*horizontal centering*/
align-items: center; align-items: center;
width: 334px; gap: 12px;
margin-bottom: 30px;
background-color: white;
}
.cancel-recording-button,
.stop-recording-button {
font-size: 70px;
cursor: pointer;
}
.cancel-recording-button {
color: red;
opacity: 0.7;
}
.cancel-recording-button:hover {
color: rgb(206, 4, 4);
}
.stop-recording-button {
color: #33cc33;
opacity: 0.7;
}
.stop-recording-button:hover {
color: #27a527;
} }
.recording-elapsed-time { .recording-elapsed-time {
font-size: 32px; font-size: 16px;
/*targeting Chrome & Safari*/ /*targeting Chrome & Safari*/
display: -webkit-flex; display: -webkit-flex;
/*targeting IE10*/ /*targeting IE10*/
@@ -73,6 +38,15 @@
/*horizontal centering*/ /*horizontal centering*/
align-items: center; align-items: center;
} }
.recording-elapsed-time #elapsed-time {
margin: 0;
}
.recording-indicator-wrapper {
position: relative;
display: flex;
width: 16px;
height: 16px;
}
.red-recording-dot { .red-recording-dot {
font-size: 25px; font-size: 25px;
color: red; color: red;
@@ -136,17 +110,11 @@
opacity: 1; opacity: 1;
} }
} }
.elapsed-time {
font-size: 32px;
}
.recording-control-buttons-container.hide { .recording-control-buttons-container.hide {
display: none; display: none;
} }
.overlay { .overlay {
position: absolute;
top: 0;
width: 100%; width: 100%;
background-color: rgba(82, 76, 76, 0.35);
/*targeting Chrome & Safari*/ /*targeting Chrome & Safari*/
display: -webkit-flex; display: -webkit-flex;
/*targeting IE10*/ /*targeting IE10*/
@@ -155,6 +123,7 @@
justify-content: center; justify-content: center;
/*horizontal centering*/ /*horizontal centering*/
align-items: center; align-items: center;
margin-bottom: 12px;
} }
.overlay.hide { .overlay.hide {
display: none; display: none;
@@ -165,16 +134,15 @@
/*targeting IE10*/ /*targeting IE10*/
display: -ms-flex; display: -ms-flex;
display: flex; display: flex;
flex-direction: column;
justify-content: space-between; justify-content: space-between;
/*horizontal centering*/ /*horizontal centering*/
align-items: center; align-items: center;
width: 317px; width: 100%;
height: 119px;
background-color: white;
border-radius: 10px;
padding: 15px;
font-size: 16px; font-size: 16px;
gap: 12px;
}
.browser-not-supporting-audio-recording-box > p {
margin: 0;
} }
.close-browser-not-supported-box { .close-browser-not-supported-box {
cursor: pointer; cursor: pointer;
@@ -219,16 +187,16 @@
-o-animation-iteration-count: infinite; -o-animation-iteration-count: infinite;
} }
.text-indication-of-audio-playing span:nth-child(2) { .text-indication-of-audio-playing span:nth-child(2) {
animation-delay: .4s; animation-delay: 0.4s;
-webkit-animation-delay: .4s; -webkit-animation-delay: 0.4s;
-moz-animation-delay: .4s; -moz-animation-delay: 0.4s;
-o-animation-delay: .4s; -o-animation-delay: 0.4s;
} }
.text-indication-of-audio-playing span:nth-child(3) { .text-indication-of-audio-playing span:nth-child(3) {
animation-delay: .8s; animation-delay: 0.8s;
-webkit-animation-delay: .8s; -webkit-animation-delay: 0.8s;
-moz-animation-delay: .8s; -moz-animation-delay: 0.8s;
-o-animation-delay: .8s; -o-animation-delay: 0.8s;
} }
/* The animation code */ /* The animation code */
@keyframes blinking-dot { @keyframes blinking-dot {