🐛 (bot) Fix audio and video autoplay when loading take some time
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/js",
|
"name": "@typebot.io/js",
|
||||||
"version": "0.0.74",
|
"version": "0.0.75",
|
||||||
"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",
|
||||||
|
@ -8,26 +8,34 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const showAnimationDuration = 400
|
const showAnimationDuration = 400
|
||||||
const typingDuration = 500
|
const defaultTypingDuration = 5000
|
||||||
|
|
||||||
let typingTimeout: NodeJS.Timeout
|
let typingTimeout: NodeJS.Timeout
|
||||||
|
|
||||||
export const AudioBubble = (props: Props) => {
|
export const AudioBubble = (props: Props) => {
|
||||||
let ref: HTMLDivElement | undefined
|
let ref: HTMLDivElement | undefined
|
||||||
|
let audioElement: HTMLAudioElement | undefined
|
||||||
const [isTyping, setIsTyping] = createSignal(true)
|
const [isTyping, setIsTyping] = createSignal(true)
|
||||||
|
|
||||||
|
const autoPlay = () => {
|
||||||
|
if (audioElement)
|
||||||
|
audioElement
|
||||||
|
.play()
|
||||||
|
.catch((e) => console.warn('Could not autoplay the audio:', e))
|
||||||
|
props.onTransitionEnd(ref?.offsetTop)
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
typingTimeout = setTimeout(() => {
|
typingTimeout = setTimeout(() => {
|
||||||
setIsTyping(false)
|
setIsTyping(false)
|
||||||
setTimeout(() => {
|
setTimeout(autoPlay, showAnimationDuration)
|
||||||
const audioElement = ref?.querySelector('audio')
|
}, defaultTypingDuration)
|
||||||
if (audioElement)
|
if (audioElement)
|
||||||
audioElement
|
audioElement.oncanplay = () => {
|
||||||
.play()
|
clearTimeout(typingTimeout)
|
||||||
.catch((e) => console.warn('Could not autoplay the audio:', e))
|
setIsTyping(false)
|
||||||
props.onTransitionEnd(ref?.offsetTop)
|
setTimeout(autoPlay, showAnimationDuration)
|
||||||
}, showAnimationDuration)
|
}
|
||||||
}, typingDuration)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
@ -48,6 +56,7 @@ export const AudioBubble = (props: Props) => {
|
|||||||
{isTyping() && <TypingBubble />}
|
{isTyping() && <TypingBubble />}
|
||||||
</div>
|
</div>
|
||||||
<audio
|
<audio
|
||||||
|
ref={audioElement}
|
||||||
src={props.url}
|
src={props.url}
|
||||||
class={
|
class={
|
||||||
'z-10 text-fade-in m-2 ' +
|
'z-10 text-fade-in m-2 ' +
|
||||||
|
@ -9,28 +9,39 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const showAnimationDuration = 400
|
export const showAnimationDuration = 400
|
||||||
|
const defaultTypingDuration = 5000
|
||||||
|
|
||||||
let typingTimeout: NodeJS.Timeout
|
let typingTimeout: NodeJS.Timeout
|
||||||
|
|
||||||
export const VideoBubble = (props: Props) => {
|
export const VideoBubble = (props: Props) => {
|
||||||
let ref: HTMLDivElement | undefined
|
let ref: HTMLDivElement | undefined
|
||||||
|
let videoElement: HTMLVideoElement | undefined
|
||||||
const [isTyping, setIsTyping] = createSignal(true)
|
const [isTyping, setIsTyping] = createSignal(true)
|
||||||
|
|
||||||
const onTypingEnd = () => {
|
const autoPlay = () => {
|
||||||
const videoElement = ref?.querySelector('video')
|
console.log(videoElement)
|
||||||
if (videoElement)
|
if (videoElement)
|
||||||
videoElement
|
videoElement
|
||||||
.play()
|
.play()
|
||||||
.catch((e) => console.warn('Could not autoplay the video:', e))
|
.catch((e) => console.warn('Could not autoplay the video:', e))
|
||||||
if (!isTyping()) return
|
props.onTransitionEnd(ref?.offsetTop)
|
||||||
setIsTyping(false)
|
|
||||||
setTimeout(() => {
|
|
||||||
props.onTransitionEnd(ref?.offsetTop)
|
|
||||||
}, showAnimationDuration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
typingTimeout = setTimeout(onTypingEnd, 2000)
|
console.log(videoElement)
|
||||||
|
typingTimeout = setTimeout(
|
||||||
|
() => {
|
||||||
|
setIsTyping(false)
|
||||||
|
setTimeout(autoPlay, showAnimationDuration)
|
||||||
|
},
|
||||||
|
videoElement ? defaultTypingDuration : 2000
|
||||||
|
)
|
||||||
|
if (videoElement)
|
||||||
|
videoElement.oncanplay = () => {
|
||||||
|
clearTimeout(typingTimeout)
|
||||||
|
setIsTyping(false)
|
||||||
|
setTimeout(autoPlay, showAnimationDuration)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
@ -50,65 +61,53 @@ export const VideoBubble = (props: Props) => {
|
|||||||
>
|
>
|
||||||
{isTyping() && <TypingBubble />}
|
{isTyping() && <TypingBubble />}
|
||||||
</div>
|
</div>
|
||||||
<VideoContent content={props.content} isTyping={isTyping()} />
|
<Switch>
|
||||||
|
<Match
|
||||||
|
when={
|
||||||
|
props.content?.type &&
|
||||||
|
props.content.type === VideoBubbleContentType.URL
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<video
|
||||||
|
ref={videoElement}
|
||||||
|
src={props.content.url}
|
||||||
|
controls
|
||||||
|
class={
|
||||||
|
'p-4 focus:outline-none w-full z-10 text-fade-in rounded-md ' +
|
||||||
|
(isTyping() ? 'opacity-0' : 'opacity-100')
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
height: isTyping() ? '32px' : 'auto',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Match>
|
||||||
|
<Match
|
||||||
|
when={
|
||||||
|
props.content?.type &&
|
||||||
|
[
|
||||||
|
VideoBubbleContentType.VIMEO,
|
||||||
|
VideoBubbleContentType.YOUTUBE,
|
||||||
|
].includes(props.content.type)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
src={`${
|
||||||
|
props.content.type === VideoBubbleContentType.VIMEO
|
||||||
|
? 'https://player.vimeo.com/video'
|
||||||
|
: 'https://www.youtube.com/embed'
|
||||||
|
}/${props.content.id}`}
|
||||||
|
class={
|
||||||
|
'w-full p-4 text-fade-in z-10 ' +
|
||||||
|
(isTyping() ? 'opacity-0' : 'opacity-100')
|
||||||
|
}
|
||||||
|
height={isTyping() ? '32px' : '200px'}
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||||
|
allowfullscreen
|
||||||
|
/>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type VideoContentProps = {
|
|
||||||
content: VideoBubbleContent
|
|
||||||
isTyping: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const VideoContent = (props: VideoContentProps) => {
|
|
||||||
return (
|
|
||||||
<Switch>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
props.content?.type &&
|
|
||||||
props.content.type === VideoBubbleContentType.URL
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<video
|
|
||||||
controls
|
|
||||||
class={
|
|
||||||
'p-4 focus:outline-none w-full z-10 text-fade-in ' +
|
|
||||||
(props.isTyping ? 'opacity-0' : 'opacity-100')
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
height: props.isTyping ? '32px' : 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<source src={props.content.url} type="video/mp4" />
|
|
||||||
Sorry, your browser doesn't support embedded videos.
|
|
||||||
</video>
|
|
||||||
</Match>
|
|
||||||
<Match
|
|
||||||
when={
|
|
||||||
props.content?.type &&
|
|
||||||
[
|
|
||||||
VideoBubbleContentType.VIMEO,
|
|
||||||
VideoBubbleContentType.YOUTUBE,
|
|
||||||
].includes(props.content.type)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<iframe
|
|
||||||
src={`${
|
|
||||||
props.content.type === VideoBubbleContentType.VIMEO
|
|
||||||
? 'https://player.vimeo.com/video'
|
|
||||||
: 'https://www.youtube.com/embed'
|
|
||||||
}/${props.content.id}`}
|
|
||||||
class={
|
|
||||||
'w-full p-4 text-fade-in z-10 ' +
|
|
||||||
(props.isTyping ? 'opacity-0' : 'opacity-100')
|
|
||||||
}
|
|
||||||
height={props.isTyping ? '32px' : '200px'}
|
|
||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
||||||
allowfullscreen
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/react",
|
"name": "@typebot.io/react",
|
||||||
"version": "0.0.74",
|
"version": "0.0.75",
|
||||||
"description": "React library to display typebots on your website",
|
"description": "React library to display typebots on your website",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
Reference in New Issue
Block a user