import React, { useEffect, useRef, useState } from 'react' import { ChatBlock } from './ChatBlock/ChatBlock' import { useFrame } from 'react-frame-component' import { setCssVariablesValue } from '../services/theme' import { useAnswers } from '../contexts/AnswersContext' import { deepEqual } from 'fast-equals' import { Answer, Block, PublicTypebot } from 'models' type Props = { typebot: PublicTypebot onNewBlockVisible: (edgeId: string) => void onNewAnswer: (answer: Answer) => void onCompleted: () => void } export const ConversationContainer = ({ typebot, onNewBlockVisible, onNewAnswer, onCompleted, }: Props) => { const { document: frameDocument } = useFrame() const [displayedBlocks, setDisplayedBlocks] = useState< { block: Block; startStepId?: string }[] >([]) const [localAnswer, setLocalAnswer] = useState() const { answers } = useAnswers() const bottomAnchor = useRef(null) const displayNextBlock = (edgeId?: string) => { const edge = typebot.edges.byId[edgeId ?? ''] if (!edge) return onCompleted() const nextBlock = { block: typebot.blocks.byId[edge.to.blockId], startStepId: edge.to.stepId, } if (!nextBlock) return onCompleted() onNewBlockVisible(edge.id) setDisplayedBlocks([...displayedBlocks, nextBlock]) } useEffect(() => { const blocks = typebot.blocks const firstEdgeId = typebot.steps.byId[blocks.byId[blocks.allIds[0]].stepIds[0]].edgeId if (!firstEdgeId) return displayNextBlock(firstEdgeId) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { setCssVariablesValue(typebot.theme, frameDocument.body.style) }, [typebot.theme, frameDocument]) useEffect(() => { const answer = [...answers].pop() if (!answer || deepEqual(localAnswer, answer)) return setLocalAnswer(answer) onNewAnswer(answer) // eslint-disable-next-line react-hooks/exhaustive-deps }, [answers]) return (
{displayedBlocks.map((displayedBlock, idx) => ( ))} {/* We use a block to simulate padding because it makes iOS scroll flicker */}
) }