2
0

Improve old engine bubbles display robustness

This commit is contained in:
Baptiste Arnaud
2023-02-03 15:39:58 +01:00
parent 0b34321bf7
commit ae88d2cae1
7 changed files with 88 additions and 71 deletions

View File

@ -63,6 +63,7 @@ export const BlockNode = ({
setOpenedBlockId, setOpenedBlockId,
setFocusedGroupId, setFocusedGroupId,
previewingEdge, previewingEdge,
isReadOnly,
} = useGraph() } = useGraph()
const { mouseOverBlock, setMouseOverBlock } = useBlockDnd() const { mouseOverBlock, setMouseOverBlock } = useBlockDnd()
const { typebot, updateBlock } = useTypebot() const { typebot, updateBlock } = useTypebot()
@ -111,6 +112,7 @@ export const BlockNode = ({
} }
const handleMouseEnter = () => { const handleMouseEnter = () => {
if (isReadOnly) return
if (mouseOverBlock?.id !== block.id) if (mouseOverBlock?.id !== block.id)
setMouseOverBlock({ id: block.id, ref: blockRef }) setMouseOverBlock({ id: block.id, ref: blockRef })
if (connectingIds) if (connectingIds)

View File

@ -4,7 +4,6 @@ import { ImageBubble } from '@/features/blocks/bubbles/image'
import { TextBubble } from '@/features/blocks/bubbles/textBubble' import { TextBubble } from '@/features/blocks/bubbles/textBubble'
import { VideoBubble } from '@/features/blocks/bubbles/video' import { VideoBubble } from '@/features/blocks/bubbles/video'
import { BubbleBlock, BubbleBlockType } from 'models' import { BubbleBlock, BubbleBlockType } from 'models'
import React from 'react'
type Props = { type Props = {
block: BubbleBlock block: BubbleBlock

View File

@ -307,7 +307,7 @@ const ChatChunks = ({
unmountOnExit unmountOnExit
in={isDefined(input)} in={isDefined(input)}
> >
{input && ( {input ? (
<InputChatBlock <InputChatBlock
block={input} block={input}
onTransitionEnd={onDisplayNextBlock} onTransitionEnd={onDisplayNextBlock}
@ -315,6 +315,8 @@ const ChatChunks = ({
hasAvatar={hostAvatar.isEnabled} hasAvatar={hostAvatar.isEnabled}
hasGuestAvatar={hasGuestAvatar} hasGuestAvatar={hasGuestAvatar}
/> />
) : (
<div />
)} )}
</CSSTransition> </CSSTransition>
)} )}

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { EmbedBubbleBlock } from 'models' import { EmbedBubbleBlock } from 'models'
import { TypingBubble } from '../../../../../components/TypingBubble' import { TypingBubble } from '../../../../../components/TypingBubble'
import { parseVariables } from '@/features/variables' import { parseVariables } from '@/features/variables'
@ -21,25 +21,24 @@ export const EmbedBubble = ({ block, onTransitionEnd }: Props) => {
[block.content?.url, typebot.variables] [block.content?.url, typebot.variables]
) )
useEffect(() => { const onTypingEnd = useCallback(() => {
if (!isTyping || isLoading) return
showContentAfterMediaLoad()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading])
const showContentAfterMediaLoad = () => {
setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, 1000)
}
const onTypingEnd = () => {
setIsTyping(false) setIsTyping(false)
setTimeout(() => { setTimeout(() => {
onTransitionEnd() onTransitionEnd()
}, showAnimationDuration) }, showAnimationDuration)
} }, [onTransitionEnd])
useEffect(() => {
if (!isTyping || isLoading) return
const timeout = setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, 1000)
return () => {
clearTimeout(timeout)
}
}, [isLoading, isTyping, onTypingEnd])
return ( return (
<div className="flex flex-col w-full" ref={messageContainer}> <div className="flex flex-col w-full" ref={messageContainer}>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTypebot } from '@/providers/TypebotProvider' import { useTypebot } from '@/providers/TypebotProvider'
import { ImageBubbleBlock } from 'models' import { ImageBubbleBlock } from 'models'
import { TypingBubble } from '@/components/TypingBubble' import { TypingBubble } from '@/components/TypingBubble'
@ -24,31 +24,37 @@ export const ImageBubble = ({ block, onTransitionEnd }: Props) => {
[block.content?.url, typebot.variables] [block.content?.url, typebot.variables]
) )
useEffect(() => { const onTypingEnd = useCallback(() => {
if (!isTyping || isLoading) return
showContentAfterMediaLoad()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading])
const showContentAfterMediaLoad = () => {
if (!image.current) return
const timeout = setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, mediaLoadingFallbackTimeout)
image.current.onload = () => {
clearTimeout(timeout)
setIsTyping(false)
onTypingEnd()
}
}
const onTypingEnd = () => {
setIsTyping(false) setIsTyping(false)
setTimeout(() => { setTimeout(() => {
onTransitionEnd() onTransitionEnd()
}, showAnimationDuration) }, showAnimationDuration)
} }, [onTransitionEnd])
useEffect(() => {
if (!isTyping || isLoading) return
const timeout = setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, mediaLoadingFallbackTimeout)
return () => {
clearTimeout(timeout)
}
}, [isLoading, isTyping, onTypingEnd])
useEffect(() => {
const currentImage = image.current
if (!currentImage || isLoading || !isTyping) return
currentImage.onload = () => {
setIsTyping(false)
onTypingEnd()
}
return () => {
currentImage.onload = null
}
}, [isLoading, isTyping, onTypingEnd])
return ( return (
<div className="flex flex-col" ref={messageContainer}> <div className="flex flex-col" ref={messageContainer}>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react' import { useCallback, useEffect, useRef, useState } from 'react'
import { useTypebot } from '@/providers/TypebotProvider' import { useTypebot } from '@/providers/TypebotProvider'
import { BubbleBlockType, TextBubbleBlock } from 'models' import { BubbleBlockType, TextBubbleBlock } from 'models'
import { computeTypingDuration } from '../utils/computeTypingDuration' import { computeTypingDuration } from '../utils/computeTypingDuration'
@ -27,24 +27,34 @@ export const TextBubble = ({ block, onTransitionEnd }: Props) => {
parseVariables(typebot.variables)(block.content.html) parseVariables(typebot.variables)(block.content.html)
) )
useEffect(() => { const onTypingEnd = useCallback(() => {
if (!isTyping || isLoading) return
const typingTimeout = computeTypingDuration(
block.content.plainText,
typebot.settings?.typingEmulation ?? defaultTypingEmulation
)
setTimeout(() => {
onTypingEnd()
}, typingTimeout)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading])
const onTypingEnd = () => {
setIsTyping(false) setIsTyping(false)
setTimeout(() => { setTimeout(() => {
onTransitionEnd() onTransitionEnd()
}, showAnimationDuration) }, showAnimationDuration)
} }, [onTransitionEnd])
useEffect(() => {
if (!isTyping || isLoading) return
const typingTimeout = computeTypingDuration(
block.content.plainText,
typebot.settings?.typingEmulation ?? defaultTypingEmulation
)
const timeout = setTimeout(() => {
onTypingEnd()
}, typingTimeout)
return () => {
clearTimeout(timeout)
}
}, [
block.content.plainText,
isLoading,
isTyping,
onTypingEnd,
typebot.settings?.typingEmulation,
])
return ( return (
<div className="flex flex-col" ref={messageContainer}> <div className="flex flex-col" ref={messageContainer}>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTypebot } from '@/providers/TypebotProvider' import { useTypebot } from '@/providers/TypebotProvider'
import { import {
Variable, Variable,
@ -23,25 +23,24 @@ export const VideoBubble = ({ block, onTransitionEnd }: Props) => {
const messageContainer = useRef<HTMLDivElement | null>(null) const messageContainer = useRef<HTMLDivElement | null>(null)
const [isTyping, setIsTyping] = useState(true) const [isTyping, setIsTyping] = useState(true)
useEffect(() => { const onTypingEnd = useCallback(() => {
if (!isTyping || isLoading) return
showContentAfterMediaLoad()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading])
const showContentAfterMediaLoad = () => {
setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, 1000)
}
const onTypingEnd = () => {
setIsTyping(false) setIsTyping(false)
setTimeout(() => { setTimeout(() => {
onTransitionEnd() onTransitionEnd()
}, showAnimationDuration) }, showAnimationDuration)
} }, [onTransitionEnd])
useEffect(() => {
if (!isTyping || isLoading) return
const timeout = setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, 1000)
return () => {
clearTimeout(timeout)
}
}, [isLoading, isTyping, onTypingEnd])
return ( return (
<div className="flex flex-col" ref={messageContainer}> <div className="flex flex-col" ref={messageContainer}>