@ -62,3 +62,7 @@ The generated URL will be stored in the defined variable.
|
|||||||
## Allow audio clips
|
## Allow audio clips
|
||||||
|
|
||||||
This option, if enabled, displays a microphone button when the text input is empty. This allows users to record a voice message and send it to the bot.
|
This option, if enabled, displays a microphone button when the text input is empty. This allows users to record a voice message and send it to the bot.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
If supported, the recorded file will be a WebM file. If not, it will be an MP4 file (i.e. Safari).
|
||||||
|
</Note>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/js",
|
"name": "@typebot.io/js",
|
||||||
"version": "0.3.11",
|
"version": "0.3.12",
|
||||||
"description": "Javascript library to display typebots on your website",
|
"description": "Javascript library to display typebots on your website",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
@ -15,6 +15,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/ui-utils": "0.0.36",
|
"@ai-sdk/ui-utils": "0.0.36",
|
||||||
"@ark-ui/solid": "3.3.0",
|
"@ark-ui/solid": "3.3.0",
|
||||||
|
"@fix-webm-duration/fix": "1.0.1",
|
||||||
"@stripe/stripe-js": "1.54.1",
|
"@stripe/stripe-js": "1.54.1",
|
||||||
"@udecode/plate-common": "30.4.5",
|
"@udecode/plate-common": "30.4.5",
|
||||||
"dompurify": "3.0.6",
|
"dompurify": "3.0.6",
|
||||||
|
@ -26,6 +26,7 @@ import { guessApiHost } from '@/utils/guessApiHost'
|
|||||||
import { VoiceRecorder } from './VoiceRecorder'
|
import { VoiceRecorder } from './VoiceRecorder'
|
||||||
import { Button } from '@/components/Button'
|
import { Button } from '@/components/Button'
|
||||||
import { MicrophoneIcon } from '@/components/icons/MicrophoneIcon'
|
import { MicrophoneIcon } from '@/components/icons/MicrophoneIcon'
|
||||||
|
import { fixWebmDuration } from '@fix-webm-duration/fix'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
block: TextInputBlock
|
block: TextInputBlock
|
||||||
@ -163,20 +164,39 @@ export const TextInput = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleRecordingConfirmed = (stream: MediaStream) => {
|
const handleRecordingConfirmed = (stream: MediaStream) => {
|
||||||
mediaRecorder = new MediaRecorder(stream)
|
let startTime: number
|
||||||
|
const mimeType = MediaRecorder.isTypeSupported('audio/webm')
|
||||||
|
? 'audio/webm'
|
||||||
|
: 'video/mp4'
|
||||||
|
|
||||||
|
mediaRecorder = new MediaRecorder(stream, { mimeType })
|
||||||
mediaRecorder.ondataavailable = (event) => {
|
mediaRecorder.ondataavailable = (event) => {
|
||||||
if (event.data.size === 0) return
|
if (event.data.size === 0) return
|
||||||
recordedChunks.push(event.data)
|
recordedChunks.push(event.data)
|
||||||
}
|
}
|
||||||
|
mediaRecorder.onstart = () => {
|
||||||
|
startTime = Date.now()
|
||||||
|
}
|
||||||
mediaRecorder.onstop = async () => {
|
mediaRecorder.onstop = async () => {
|
||||||
if (recordingStatus() !== 'started' || recordedChunks.length === 0) return
|
if (recordingStatus() !== 'started' || recordedChunks.length === 0) return
|
||||||
|
|
||||||
|
const duration = Date.now() - startTime
|
||||||
|
|
||||||
|
const blob = await fixWebmDuration(
|
||||||
|
new Blob(recordedChunks, { type: mimeType }),
|
||||||
|
duration
|
||||||
|
)
|
||||||
|
|
||||||
const audioFile = new File(
|
const audioFile = new File(
|
||||||
recordedChunks,
|
[blob],
|
||||||
`rec-${props.block.id}-${Date.now()}.mp3`,
|
`rec-${props.block.id}-${Date.now()}.${
|
||||||
|
mimeType === 'audio/webm' ? 'webm' : 'mp4'
|
||||||
|
}`,
|
||||||
{
|
{
|
||||||
type: 'audio/mp3',
|
type: mimeType,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
setUploadProgress(undefined)
|
setUploadProgress(undefined)
|
||||||
const urls = (
|
const urls = (
|
||||||
await uploadFiles({
|
await uploadFiles({
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/nextjs",
|
"name": "@typebot.io/nextjs",
|
||||||
"version": "0.3.11",
|
"version": "0.3.12",
|
||||||
"description": "Convenient library to display typebots on your Next.js website",
|
"description": "Convenient library to display typebots on your Next.js website",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/react",
|
"name": "@typebot.io/react",
|
||||||
"version": "0.3.11",
|
"version": "0.3.12",
|
||||||
"description": "Convenient library to display typebots on your React app",
|
"description": "Convenient library to display typebots on your React app",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@ -1033,6 +1033,9 @@ importers:
|
|||||||
'@ark-ui/solid':
|
'@ark-ui/solid':
|
||||||
specifier: 3.3.0
|
specifier: 3.3.0
|
||||||
version: 3.3.0(@internationalized/date@3.5.4)(solid-js@1.7.8)
|
version: 3.3.0(@internationalized/date@3.5.4)(solid-js@1.7.8)
|
||||||
|
'@fix-webm-duration/fix':
|
||||||
|
specifier: ^1.0.1
|
||||||
|
version: 1.0.1
|
||||||
'@stripe/stripe-js':
|
'@stripe/stripe-js':
|
||||||
specifier: 1.54.1
|
specifier: 1.54.1
|
||||||
version: 1.54.1
|
version: 1.54.1
|
||||||
@ -4084,6 +4087,12 @@ packages:
|
|||||||
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||||
|
|
||||||
|
'@fix-webm-duration/fix@1.0.1':
|
||||||
|
resolution: {integrity: sha512-rRN4CpWQaXRbCXYqKIxnsUq8OSWSGq/SVlnxxkx0HxMZZ1u0qnB24P766o8QS5YaMMqAOFAzmsMmfZ2OWucOLQ==}
|
||||||
|
|
||||||
|
'@fix-webm-duration/parser@1.0.1':
|
||||||
|
resolution: {integrity: sha512-Z6el7ohBBpym4iOmxDxumN715cHzLcAbtOtYfIbvoyToVtAuxvHt3ELXGff83iAXEU1Yj7g+obQBdiKJYVhbWw==}
|
||||||
|
|
||||||
'@floating-ui/core@1.6.7':
|
'@floating-ui/core@1.6.7':
|
||||||
resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==}
|
resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==}
|
||||||
|
|
||||||
@ -15886,6 +15895,15 @@ snapshots:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
|
||||||
|
'@fix-webm-duration/fix@1.0.1':
|
||||||
|
dependencies:
|
||||||
|
'@fix-webm-duration/parser': 1.0.1
|
||||||
|
tslib: 2.6.0
|
||||||
|
|
||||||
|
'@fix-webm-duration/parser@1.0.1':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.6.0
|
||||||
|
|
||||||
'@floating-ui/core@1.6.7':
|
'@floating-ui/core@1.6.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/utils': 0.2.7
|
'@floating-ui/utils': 0.2.7
|
||||||
|
Reference in New Issue
Block a user