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", "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",

View File

@@ -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)
onMount(() => { const autoPlay = () => {
typingTimeout = setTimeout(() => {
setIsTyping(false)
setTimeout(() => {
const audioElement = ref?.querySelector('audio')
if (audioElement) if (audioElement)
audioElement audioElement
.play() .play()
.catch((e) => console.warn('Could not autoplay the audio:', e)) .catch((e) => console.warn('Could not autoplay the audio:', e))
props.onTransitionEnd(ref?.offsetTop) props.onTransitionEnd(ref?.offsetTop)
}, showAnimationDuration) }
}, typingDuration)
onMount(() => {
typingTimeout = setTimeout(() => {
setIsTyping(false)
setTimeout(autoPlay, showAnimationDuration)
}, defaultTypingDuration)
if (audioElement)
audioElement.oncanplay = () => {
clearTimeout(typingTimeout)
setIsTyping(false)
setTimeout(autoPlay, showAnimationDuration)
}
}) })
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 ' +

View File

@@ -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
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd(ref?.offsetTop) 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,20 +61,6 @@ export const VideoBubble = (props: Props) => {
> >
{isTyping() && <TypingBubble />} {isTyping() && <TypingBubble />}
</div> </div>
<VideoContent content={props.content} isTyping={isTyping()} />
</div>
</div>
</div>
)
}
type VideoContentProps = {
content: VideoBubbleContent
isTyping: boolean
}
const VideoContent = (props: VideoContentProps) => {
return (
<Switch> <Switch>
<Match <Match
when={ when={
@@ -72,18 +69,17 @@ const VideoContent = (props: VideoContentProps) => {
} }
> >
<video <video
ref={videoElement}
src={props.content.url}
controls controls
class={ class={
'p-4 focus:outline-none w-full z-10 text-fade-in ' + 'p-4 focus:outline-none w-full z-10 text-fade-in rounded-md ' +
(props.isTyping ? 'opacity-0' : 'opacity-100') (isTyping() ? 'opacity-0' : 'opacity-100')
} }
style={{ style={{
height: props.isTyping ? '32px' : 'auto', height: isTyping() ? '32px' : 'auto',
}} }}
> />
<source src={props.content.url} type="video/mp4" />
Sorry, your browser doesn&apos;t support embedded videos.
</video>
</Match> </Match>
<Match <Match
when={ when={
@@ -102,13 +98,16 @@ const VideoContent = (props: VideoContentProps) => {
}/${props.content.id}`} }/${props.content.id}`}
class={ class={
'w-full p-4 text-fade-in z-10 ' + 'w-full p-4 text-fade-in z-10 ' +
(props.isTyping ? 'opacity-0' : 'opacity-100') (isTyping() ? 'opacity-0' : 'opacity-100')
} }
height={props.isTyping ? '32px' : '200px'} height={isTyping() ? '32px' : '200px'}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen allowfullscreen
/> />
</Match> </Match>
</Switch> </Switch>
</div>
</div>
</div>
) )
} }

View File

@@ -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",