@@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useAnswers } from '../../../providers/AnswersProvider'
|
||||
import { InputBlock, InputBlockType } from '@typebot.io/schemas'
|
||||
import { InputBlock } from '@typebot.io/schemas'
|
||||
import { GuestBubble } from './bubbles/GuestBubble'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { InputSubmitContent } from '@/types'
|
||||
@@ -17,6 +17,9 @@ import { ChoiceForm } from '@/features/blocks/inputs/buttons'
|
||||
import { PaymentForm } from '@/features/blocks/inputs/payment'
|
||||
import { RatingForm } from '@/features/blocks/inputs/rating'
|
||||
import { FileUploadForm } from '@/features/blocks/inputs/fileUpload'
|
||||
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
|
||||
export const InputChatBlock = ({
|
||||
block,
|
||||
@@ -39,9 +42,11 @@ export const InputChatBlock = ({
|
||||
const [answer, setAnswer] = useState<string>()
|
||||
const [isEditting, setIsEditting] = useState(false)
|
||||
|
||||
const { variableId } = block.options
|
||||
const { variableId } = block.options ?? {}
|
||||
const defaultValue =
|
||||
(typebot.settings.general.isInputPrefillEnabled ?? true) && variableId
|
||||
(typebot.settings.general?.isInputPrefillEnabled ??
|
||||
defaultSettings.general.isInputPrefillEnabled) &&
|
||||
variableId
|
||||
? typebot.variables.find(
|
||||
(variable) =>
|
||||
variable.name === typebot.variables.find(byId(variableId))?.name
|
||||
@@ -51,14 +56,17 @@ export const InputChatBlock = ({
|
||||
const handleSubmit = async ({ label, value, itemId }: InputSubmitContent) => {
|
||||
setAnswer(label ?? value)
|
||||
const isRetry = !isInputValid(value, block.type)
|
||||
if (!isRetry && addAnswer)
|
||||
if (!isRetry && addAnswer) {
|
||||
const { group } = getBlockById(block.id, typebot.groups)
|
||||
await addAnswer(typebot.variables)({
|
||||
blockId: block.id,
|
||||
groupId: block.groupId,
|
||||
groupId: group.id,
|
||||
content: value,
|
||||
variableId,
|
||||
uploadedFiles: block.type === InputBlockType.FILE,
|
||||
})
|
||||
}
|
||||
|
||||
if (!isEditting) onTransitionEnd({ label, value, itemId }, isRetry)
|
||||
setIsEditting(false)
|
||||
}
|
||||
@@ -66,11 +74,11 @@ export const InputChatBlock = ({
|
||||
if (isLoading) return null
|
||||
|
||||
if (answer) {
|
||||
const avatarUrl = typebot.theme.chat.guestAvatar?.url
|
||||
const avatarUrl = typebot.theme.chat?.guestAvatar?.url
|
||||
return (
|
||||
<GuestBubble
|
||||
message={answer}
|
||||
showAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
|
||||
showAvatar={typebot.theme.chat?.guestAvatar?.isEnabled ?? false}
|
||||
avatarSrc={avatarUrl && parseVariables(typebot.variables)(avatarUrl)}
|
||||
/>
|
||||
)
|
||||
@@ -160,7 +168,7 @@ const Input = ({
|
||||
<PaymentForm
|
||||
options={block.options}
|
||||
onSuccess={() =>
|
||||
onSubmit({ value: block.options.labels.success ?? 'Success' })
|
||||
onSubmit({ value: block.options?.labels?.success ?? 'Success' })
|
||||
}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -3,7 +3,8 @@ import { EmbedBubble } from '@/features/blocks/bubbles/embed'
|
||||
import { ImageBubble } from '@/features/blocks/bubbles/image'
|
||||
import { TextBubble } from '@/features/blocks/bubbles/textBubble'
|
||||
import { VideoBubble } from '@/features/blocks/bubbles/video'
|
||||
import { BubbleBlock, BubbleBlockType } from '@typebot.io/schemas'
|
||||
import { BubbleBlock } from '@typebot.io/schemas'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
type Props = {
|
||||
block: BubbleBlock
|
||||
@@ -23,7 +24,7 @@ export const HostBubble = ({ block, onTransitionEnd }: Props) => {
|
||||
case BubbleBlockType.AUDIO:
|
||||
return (
|
||||
<AudioBubble
|
||||
url={block.content.url}
|
||||
url={block.content?.url}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
import {
|
||||
BubbleBlock,
|
||||
InputBlock,
|
||||
LogicBlockType,
|
||||
PublicTypebot,
|
||||
Block,
|
||||
} from '@typebot.io/schemas'
|
||||
@@ -30,6 +29,8 @@ import { executeIntegration } from '@/utils/executeIntegration'
|
||||
import { executeLogic } from '@/utils/executeLogic'
|
||||
import { blockCanBeRetried, parseRetryBlock } from '@/utils/inputs'
|
||||
import { PopupBlockedToast } from '../PopupBlockedToast'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
|
||||
type ChatGroupProps = {
|
||||
blocks: Block[]
|
||||
@@ -143,19 +144,20 @@ export const ChatGroup = ({
|
||||
if (blockedPopupUrl) setBlockedPopupUrl(blockedPopupUrl)
|
||||
const isRedirecting =
|
||||
currentBlock.type === LogicBlockType.REDIRECT &&
|
||||
currentBlock.options.isNewTab === false
|
||||
currentBlock.options?.isNewTab === false
|
||||
if (isRedirecting) return
|
||||
nextEdgeId
|
||||
? onGroupEnd({ edgeId: nextEdgeId, updatedTypebot: linkedTypebot })
|
||||
: displayNextBlock()
|
||||
}
|
||||
if (isIntegrationBlock(currentBlock)) {
|
||||
const { group } = getBlockById(currentBlock.id, typebot.groups)
|
||||
const nextEdgeId = await executeIntegration({
|
||||
block: currentBlock,
|
||||
context: {
|
||||
apiHost,
|
||||
typebotId: currentTypebotId,
|
||||
groupId: currentBlock.groupId,
|
||||
groupId: group.id,
|
||||
blockId: currentBlock.id,
|
||||
variables: typebot.variables,
|
||||
isPreview,
|
||||
@@ -181,10 +183,12 @@ export const ChatGroup = ({
|
||||
scroll()
|
||||
const currentBlock = [...processedBlocks].pop()
|
||||
if (currentBlock) {
|
||||
if (isRetry && blockCanBeRetried(currentBlock))
|
||||
if (isRetry && blockCanBeRetried(currentBlock)) {
|
||||
const { group } = getBlockById(currentBlock.id, typebot.groups)
|
||||
return insertBlockInStack(
|
||||
parseRetryBlock(currentBlock, typebot.variables, createEdge)
|
||||
parseRetryBlock(currentBlock, group.id, typebot.variables, createEdge)
|
||||
)
|
||||
}
|
||||
if (
|
||||
isInputBlock(currentBlock) &&
|
||||
currentBlock.options?.variableId &&
|
||||
@@ -196,7 +200,7 @@ export const ChatGroup = ({
|
||||
)
|
||||
}
|
||||
const isSingleChoiceBlock =
|
||||
isChoiceInput(currentBlock) && !currentBlock.options.isMultipleChoice
|
||||
isChoiceInput(currentBlock) && !currentBlock.options?.isMultipleChoice
|
||||
if (isSingleChoiceBlock) {
|
||||
const nextEdgeId = currentBlock.items.find(
|
||||
byId(answerContent?.itemId)
|
||||
@@ -214,7 +218,7 @@ export const ChatGroup = ({
|
||||
nextBlock ? insertBlockInStack(nextBlock) : onGroupEnd({})
|
||||
}
|
||||
|
||||
const avatarSrc = typebot.theme.chat.hostAvatar?.url
|
||||
const avatarSrc = typebot.theme.chat?.hostAvatar?.url
|
||||
|
||||
return (
|
||||
<div className="flex w-full" data-group-name={groupTitle}>
|
||||
@@ -224,10 +228,10 @@ export const ChatGroup = ({
|
||||
key={idx}
|
||||
displayChunk={chunk}
|
||||
hostAvatar={{
|
||||
isEnabled: typebot.theme.chat.hostAvatar?.isEnabled ?? true,
|
||||
isEnabled: typebot.theme.chat?.hostAvatar?.isEnabled ?? true,
|
||||
src: avatarSrc && parseVariables(typebot.variables)(avatarSrc),
|
||||
}}
|
||||
hasGuestAvatar={typebot.theme.chat.guestAvatar?.isEnabled ?? false}
|
||||
hasGuestAvatar={typebot.theme.chat?.guestAvatar?.isEnabled ?? false}
|
||||
onDisplayNextBlock={displayNextBlock}
|
||||
keepShowingHostAvatar={keepShowingHostAvatar}
|
||||
blockedPopupUrl={blockedPopupUrl}
|
||||
|
||||
@@ -57,7 +57,7 @@ export const ConversationContainer = ({
|
||||
if (!nextGroup) return
|
||||
onNewGroupVisible({
|
||||
id: 'edgeId',
|
||||
from: { groupId: 'block', blockId: 'block' },
|
||||
from: { blockId: 'block' },
|
||||
to: { groupId },
|
||||
})
|
||||
return setDisplayedGroups([
|
||||
|
||||
@@ -7,7 +7,6 @@ import { ConversationContainer } from './ConversationContainer'
|
||||
import { AnswersProvider } from '../providers/AnswersProvider'
|
||||
import {
|
||||
AnswerInput,
|
||||
BackgroundType,
|
||||
Edge,
|
||||
PublicTypebot,
|
||||
VariableWithValue,
|
||||
@@ -16,6 +15,7 @@ import { Log } from '@typebot.io/prisma'
|
||||
import { LiteBadge } from './LiteBadge'
|
||||
import { isNotEmpty } from '@typebot.io/lib'
|
||||
import { getViewerUrl } from '@typebot.io/lib/getViewerUrl'
|
||||
import { BackgroundType } from '@typebot.io/schemas/features/typebot/theme/constants'
|
||||
|
||||
export type TypebotViewerProps = {
|
||||
typebot: Omit<PublicTypebot, 'updatedAt' | 'createdAt'>
|
||||
@@ -78,7 +78,7 @@ export const TypebotViewer = ({
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `@import url('https://fonts.googleapis.com/css2?family=${
|
||||
typebot.theme.general.font ?? 'Open Sans'
|
||||
typebot.theme.general?.font ?? 'Open Sans'
|
||||
}:ital,wght@0,300;0,400;0,600;1,300;1,400;1,600&display=swap');`,
|
||||
}}
|
||||
/>
|
||||
@@ -112,7 +112,7 @@ export const TypebotViewer = ({
|
||||
startGroupId={startGroupId}
|
||||
/>
|
||||
</div>
|
||||
{typebot.settings.general.isBrandingEnabled && <LiteBadge />}
|
||||
{typebot.settings.general?.isBrandingEnabled && <LiteBadge />}
|
||||
</div>
|
||||
</AnswersProvider>
|
||||
</TypebotProvider>
|
||||
|
||||
Reference in New Issue
Block a user