2
0

🐛 (bot) Fix audio and video autoplay when loading take some time

This commit is contained in:
Baptiste Arnaud
2023-07-12 12:00:23 +02:00
parent 5644a0c8e0
commit ba3a2b711e
4 changed files with 85 additions and 77 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.0.74",
"version": "0.0.75",
"description": "Javascript library to display typebots on your website",
"type": "module",
"main": "dist/index.js",

View File

@ -8,26 +8,34 @@ type Props = {
}
const showAnimationDuration = 400
const typingDuration = 500
const defaultTypingDuration = 5000
let typingTimeout: NodeJS.Timeout
export const AudioBubble = (props: Props) => {
let ref: HTMLDivElement | undefined
let audioElement: HTMLAudioElement | undefined
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(() => {
typingTimeout = setTimeout(() => {
setIsTyping(false)
setTimeout(() => {
const audioElement = ref?.querySelector('audio')
if (audioElement)
audioElement
.play()
.catch((e) => console.warn('Could not autoplay the audio:', e))
props.onTransitionEnd(ref?.offsetTop)
}, showAnimationDuration)
}, typingDuration)
setTimeout(autoPlay, showAnimationDuration)
}, defaultTypingDuration)
if (audioElement)
audioElement.oncanplay = () => {
clearTimeout(typingTimeout)
setIsTyping(false)
setTimeout(autoPlay, showAnimationDuration)
}
})
onCleanup(() => {
@ -48,6 +56,7 @@ export const AudioBubble = (props: Props) => {
{isTyping() && <TypingBubble />}
</div>
<audio
ref={audioElement}
src={props.url}
class={
'z-10 text-fade-in m-2 ' +

View File

@ -9,28 +9,39 @@ type Props = {
}
export const showAnimationDuration = 400
const defaultTypingDuration = 5000
let typingTimeout: NodeJS.Timeout
export const VideoBubble = (props: Props) => {
let ref: HTMLDivElement | undefined
let videoElement: HTMLVideoElement | undefined
const [isTyping, setIsTyping] = createSignal(true)
const onTypingEnd = () => {
const videoElement = ref?.querySelector('video')
const autoPlay = () => {
console.log(videoElement)
if (videoElement)
videoElement
.play()
.catch((e) => console.warn('Could not autoplay the video:', e))
if (!isTyping()) return
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd(ref?.offsetTop)
}, showAnimationDuration)
props.onTransitionEnd(ref?.offsetTop)
}
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(() => {
@ -50,65 +61,53 @@ export const VideoBubble = (props: Props) => {
>
{isTyping() && <TypingBubble />}
</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>
)
}
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&apos;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>
)
}

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.0.74",
"version": "0.0.75",
"description": "React library to display typebots on your website",
"main": "dist/index.js",
"types": "dist/index.d.ts",