fix(engine): 🐛 Properly handle variable avatars
This commit is contained in:
@@ -34,6 +34,8 @@ export const AvatarForm = ({
|
|||||||
onAvatarChange({ ...avatarProps, isEnabled: !isChecked })
|
onAvatarChange({ ...avatarProps, isEnabled: !isChecked })
|
||||||
const handleImageUrl = (url: string) =>
|
const handleImageUrl = (url: string) =>
|
||||||
onAvatarChange({ isEnabled: isChecked, url })
|
onAvatarChange({ isEnabled: isChecked, url })
|
||||||
|
|
||||||
|
const isDefaultAvatar = !avatarProps?.url || avatarProps.url.includes('{{')
|
||||||
return (
|
return (
|
||||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||||
<Flex justifyContent="space-between">
|
<Flex justifyContent="space-between">
|
||||||
@@ -46,7 +48,14 @@ export const AvatarForm = ({
|
|||||||
{isChecked && (
|
{isChecked && (
|
||||||
<Popover isLazy>
|
<Popover isLazy>
|
||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
{avatarProps?.url ? (
|
{isDefaultAvatar ? (
|
||||||
|
<Box>
|
||||||
|
<DefaultAvatar
|
||||||
|
cursor="pointer"
|
||||||
|
_hover={{ filter: 'brightness(.9)' }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
<Image
|
<Image
|
||||||
src={avatarProps.url}
|
src={avatarProps.url}
|
||||||
alt="Website image"
|
alt="Website image"
|
||||||
@@ -57,13 +66,6 @@ export const AvatarForm = ({
|
|||||||
boxSize="40px"
|
boxSize="40px"
|
||||||
objectFit="cover"
|
objectFit="cover"
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<Box>
|
|
||||||
<DefaultAvatar
|
|
||||||
cursor="pointer"
|
|
||||||
_hover={{ filter: 'brightness(.9)' }}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
)}
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<Portal>
|
<Portal>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const SendIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 512 512"
|
viewBox="0 0 512 512"
|
||||||
width="19px"
|
width="19px"
|
||||||
|
color="white"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<path d="M476.59 227.05l-.16-.07L49.35 49.84A23.56 23.56 0 0027.14 52 24.65 24.65 0 0016 72.59v113.29a24 24 0 0019.52 23.57l232.93 43.07a4 4 0 010 7.86L35.53 303.45A24 24 0 0016 327v113.31A23.57 23.57 0 0026.59 460a23.94 23.94 0 0013.22 4 24.55 24.55 0 009.52-1.93L476.4 285.94l.19-.09a32 32 0 000-58.8z" />
|
<path d="M476.59 227.05l-.16-.07L49.35 49.84A23.56 23.56 0 0027.14 52 24.65 24.65 0 0016 72.59v113.29a24 24 0 0019.52 23.57l232.93 43.07a4 4 0 010 7.86L35.53 303.45A24 24 0 0016 327v113.31A23.57 23.57 0 0026.59 460a23.94 23.94 0 0013.22 4 24.55 24.55 0 009.52-1.93L476.4 285.94l.19-.09a32 32 0 000-58.8z" />
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.typebot-button > .send-icon {
|
.typebot-button > .send-icon {
|
||||||
fill: var(--typebot-button-active-color);
|
fill: var(--typebot-button-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.typebot-chat-view {
|
.typebot-chat-view {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useHostAvatars } from '../../contexts/HostAvatarsContext'
|
|||||||
export const AvatarSideContainer = ({
|
export const AvatarSideContainer = ({
|
||||||
hostAvatarSrc,
|
hostAvatarSrc,
|
||||||
}: {
|
}: {
|
||||||
hostAvatarSrc: string
|
hostAvatarSrc?: string
|
||||||
}) => {
|
}) => {
|
||||||
const { lastBubblesTopOffset } = useHostAvatars()
|
const { lastBubblesTopOffset } = useHostAvatars()
|
||||||
const { window, document } = useFrame()
|
const { window, document } = useFrame()
|
||||||
|
|||||||
@@ -110,17 +110,18 @@ export const ChatBlock = ({
|
|||||||
if (nextStep) setDisplayedSteps([...displayedSteps, nextStep])
|
if (nextStep) setDisplayedSteps([...displayedSteps, nextStep])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const avatarSrc = typebot.theme.chat.hostAvatar?.url
|
||||||
return (
|
return (
|
||||||
<div className="flex">
|
<div className="flex w-full">
|
||||||
<HostAvatarsContext>
|
<HostAvatarsContext>
|
||||||
{(typebot.theme.chat.hostAvatar?.isEnabled ?? true) && (
|
{(typebot.theme.chat.hostAvatar?.isEnabled ?? true) && (
|
||||||
<AvatarSideContainer
|
<AvatarSideContainer
|
||||||
hostAvatarSrc={parseVariables(typebot.variables)(
|
hostAvatarSrc={
|
||||||
typebot.theme.chat.hostAvatar?.url
|
avatarSrc && parseVariables(typebot.variables)(avatarSrc)
|
||||||
)}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col w-full">
|
<div className="flex flex-col w-full min-w-0">
|
||||||
<TransitionGroup>
|
<TransitionGroup>
|
||||||
{displayedSteps
|
{displayedSteps
|
||||||
.filter((step) => isInputStep(step) || isBubbleStep(step))
|
.filter((step) => isInputStep(step) || isBubbleStep(step))
|
||||||
|
|||||||
@@ -68,13 +68,12 @@ const InputChatStep = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (answer) {
|
if (answer) {
|
||||||
|
const avatarUrl = typebot.theme.chat.guestAvatar?.url
|
||||||
return (
|
return (
|
||||||
<GuestBubble
|
<GuestBubble
|
||||||
message={answer}
|
message={answer}
|
||||||
showAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
|
showAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
|
||||||
avatarSrc={parseVariables(typebot.variables)(
|
avatarSrc={avatarUrl && parseVariables(typebot.variables)(avatarUrl)}
|
||||||
typebot.theme.chat.guestAvatar?.url
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { CSSTransition } from 'react-transition-group'
|
|||||||
interface Props {
|
interface Props {
|
||||||
message: string
|
message: string
|
||||||
showAvatar: boolean
|
showAvatar: boolean
|
||||||
avatarSrc: string
|
avatarSrc?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GuestBubble = ({
|
export const GuestBubble = ({
|
||||||
@@ -15,16 +15,14 @@ export const GuestBubble = ({
|
|||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<CSSTransition classNames="bubble" timeout={1000}>
|
<CSSTransition classNames="bubble" timeout={1000}>
|
||||||
<div className="flex justify-end mb-2 items-center">
|
<div className="flex justify-end mb-2 items-end">
|
||||||
<div className="flex items-end w-11/12 lg:w-4/6 justify-end">
|
<span
|
||||||
<div
|
className="px-4 py-2 rounded-lg mr-2 whitespace-pre-wrap max-w-full typebot-guest-bubble"
|
||||||
className="inline-flex px-4 py-2 rounded-lg mr-2 whitespace-pre-wrap max-w-full typebot-guest-bubble"
|
data-testid="guest-bubble"
|
||||||
data-testid="guest-bubble"
|
>
|
||||||
>
|
{message}
|
||||||
{message}
|
</span>
|
||||||
</div>
|
{showAvatar && <Avatar avatarSrc={avatarSrc} />}
|
||||||
{showAvatar && <Avatar avatarSrc={avatarSrc} />}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</CSSTransition>
|
</CSSTransition>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export const TextBubble = ({ step, onTransitionEnd }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col" ref={messageContainer}>
|
<div className="flex flex-col" ref={messageContainer}>
|
||||||
<div className="flex mb-2 w-full lg:w-11/12 items-center">
|
<div className="flex mb-2 w-full items-center">
|
||||||
<div className={'flex relative z-10 items-start typebot-host-bubble'}>
|
<div className={'flex relative z-10 items-start typebot-host-bubble'}>
|
||||||
<div
|
<div
|
||||||
className="flex items-center absolute px-4 py-2 rounded-lg bubble-typing z-10 "
|
className="flex items-center absolute px-4 py-2 rounded-lg bubble-typing z-10 "
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { isDefined } from 'utils'
|
||||||
import { DefaultAvatar } from './DefaultAvatar'
|
import { DefaultAvatar } from './DefaultAvatar'
|
||||||
|
|
||||||
export const Avatar = ({ avatarSrc }: { avatarSrc: string }): JSX.Element => {
|
export const Avatar = ({ avatarSrc }: { avatarSrc?: string }): JSX.Element => {
|
||||||
|
if (avatarSrc === '') return <></>
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full rounded-full text-2xl md:text-4xl text-center xs:w-10 xs:h-10">
|
<div className="w-full h-full rounded-full text-2xl md:text-4xl text-center xs:w-10 xs:h-10 flex-shrink-0">
|
||||||
{avatarSrc !== '' ? (
|
{isDefined(avatarSrc) ? (
|
||||||
<figure
|
<figure
|
||||||
className={
|
className={
|
||||||
'flex justify-center items-center rounded-full text-white w-6 h-6 text-sm relative xs:w-full xs:h-full xs:text-xl'
|
'flex justify-center items-center rounded-full text-white w-6 h-6 text-sm relative xs:w-full xs:h-full xs:text-xl'
|
||||||
|
|||||||
Reference in New Issue
Block a user