41
apps/builder/src/features/blocks/bubbles/audio/audio.spec.ts
Normal file
41
apps/builder/src/features/blocks/bubbles/audio/audio.spec.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createTypebots } from 'utils/playwright/databaseActions'
|
||||
import { parseDefaultGroupWithBlock } from 'utils/playwright/databaseHelpers'
|
||||
import { BubbleBlockType, defaultAudioBubbleContent } from 'models'
|
||||
import cuid from 'cuid'
|
||||
import { getTestAsset } from '@/test/utils/playwright'
|
||||
import { typebotViewer } from 'utils/playwright/testHelpers'
|
||||
|
||||
const audioSampleUrl =
|
||||
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
|
||||
|
||||
test('should work as expected', async ({ page }) => {
|
||||
const typebotId = cuid()
|
||||
await createTypebots([
|
||||
{
|
||||
id: typebotId,
|
||||
...parseDefaultGroupWithBlock({
|
||||
type: BubbleBlockType.AUDIO,
|
||||
content: defaultAudioBubbleContent,
|
||||
}),
|
||||
},
|
||||
])
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/edit`)
|
||||
await page.getByText('Click to edit...').click()
|
||||
await page
|
||||
.getByPlaceholder('Paste the audio file link...')
|
||||
.fill(audioSampleUrl)
|
||||
await expect(page.locator('audio')).toHaveAttribute('src', audioSampleUrl)
|
||||
await page.getByRole('button', { name: 'Upload' }).click()
|
||||
await page.setInputFiles('input[type="file"]', getTestAsset('sample.mp3'))
|
||||
await expect(page.locator('audio')).toHaveAttribute(
|
||||
'src',
|
||||
RegExp(`/public/typebots/${typebotId}/blocks`, 'gm')
|
||||
)
|
||||
await page.getByRole('button', { name: 'Preview' }).click()
|
||||
await expect(typebotViewer(page).locator('audio')).toHaveAttribute(
|
||||
'src',
|
||||
RegExp(`/public/typebots/${typebotId}/blocks`, 'gm')
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Button, Flex, HStack, Stack, Text } from '@chakra-ui/react'
|
||||
import { AudioBubbleContent } from 'models'
|
||||
import { Input } from '@/components/inputs'
|
||||
import { useState } from 'react'
|
||||
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
|
||||
|
||||
type Props = {
|
||||
fileUploadPath: string
|
||||
content: AudioBubbleContent
|
||||
onSubmit: (content: AudioBubbleContent) => void
|
||||
}
|
||||
|
||||
export const AudioBubbleForm = ({
|
||||
fileUploadPath,
|
||||
content,
|
||||
onSubmit,
|
||||
}: Props) => {
|
||||
const [currentTab, setCurrentTab] = useState<'link' | 'upload'>('link')
|
||||
|
||||
const submit = (url: string) => onSubmit({ url })
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<HStack>
|
||||
<Button
|
||||
variant={currentTab === 'upload' ? 'solid' : 'ghost'}
|
||||
onClick={() => setCurrentTab('upload')}
|
||||
size="sm"
|
||||
>
|
||||
Upload
|
||||
</Button>
|
||||
<Button
|
||||
variant={currentTab === 'link' ? 'solid' : 'ghost'}
|
||||
onClick={() => setCurrentTab('link')}
|
||||
size="sm"
|
||||
>
|
||||
Embed link
|
||||
</Button>
|
||||
</HStack>
|
||||
<Stack p="2">
|
||||
{currentTab === 'upload' && (
|
||||
<Flex justify="center" py="2">
|
||||
<UploadButton
|
||||
fileType="audio"
|
||||
filePath={fileUploadPath}
|
||||
onFileUploaded={submit}
|
||||
colorScheme="blue"
|
||||
>
|
||||
Choose a file
|
||||
</UploadButton>
|
||||
</Flex>
|
||||
)}
|
||||
{currentTab === 'link' && (
|
||||
<>
|
||||
<Input
|
||||
placeholder="Paste the audio file link..."
|
||||
defaultValue={content.url ?? ''}
|
||||
onChange={submit}
|
||||
/>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
Works with .MP3s, .WAVs and .OGGs
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { featherIconsBaseProps } from '@/components/icons'
|
||||
import { Icon, IconProps } from '@chakra-ui/react'
|
||||
import React from 'react'
|
||||
|
||||
export const AudioBubbleIcon = (props: IconProps) => (
|
||||
<Icon color="blue.500" {...featherIconsBaseProps} {...props}>
|
||||
<path d="M3 18v-6a9 9 0 0 1 18 0v6"></path>
|
||||
<path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path>
|
||||
</Icon>
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Text } from '@chakra-ui/react'
|
||||
import { AudioBubbleContent } from 'models'
|
||||
import { isDefined } from 'utils'
|
||||
|
||||
type Props = {
|
||||
url: AudioBubbleContent['url']
|
||||
}
|
||||
|
||||
export const AudioBubbleNode = ({ url }: Props) =>
|
||||
isDefined(url) ? (
|
||||
<audio src={url} controls />
|
||||
) : (
|
||||
<Text color={'gray.500'}>Click to edit...</Text>
|
||||
)
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './AudioBubbleNode'
|
||||
export * from './AudioBubbleIcon'
|
||||
1
apps/builder/src/features/blocks/bubbles/audio/index.ts
Normal file
1
apps/builder/src/features/blocks/bubbles/audio/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './components'
|
||||
Reference in New Issue
Block a user