refactor(♻️ Add defaults everywhere (+ settings page)):
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useTypebot } from '../../contexts/TypebotContext'
|
||||
import { HostAvatar } from '../avatars/HostAvatar'
|
||||
import { useFrame } from 'react-frame-component'
|
||||
@ -22,6 +22,7 @@ export const AvatarSideContainer = () => {
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
@ -35,11 +35,13 @@ export const ChatBlock = ({
|
||||
const nextStep =
|
||||
typebot.steps.byId[startStepId ?? stepIds[displayedSteps.length]]
|
||||
if (nextStep) setDisplayedSteps([...displayedSteps, nextStep])
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
autoScrollToBottom()
|
||||
onNewStepDisplayed()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [displayedSteps])
|
||||
|
||||
const onNewStepDisplayed = async () => {
|
||||
|
@ -42,6 +42,7 @@ const InputChatStep = ({
|
||||
|
||||
useEffect(() => {
|
||||
addNewAvatarOffset()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const handleSubmit = (value: string) => {
|
||||
|
@ -24,11 +24,12 @@ export const ImageBubble = ({ step, onTransitionEnd }: Props) => {
|
||||
const url = useMemo(
|
||||
() =>
|
||||
parseVariables({ text: step.content?.url, variables: typebot.variables }),
|
||||
[typebot.variables]
|
||||
[step.content?.url, typebot.variables]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
showContentAfterMediaLoad()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const showContentAfterMediaLoad = () => {
|
||||
@ -83,6 +84,7 @@ export const ImageBubble = ({ step, onTransitionEnd }: Props) => {
|
||||
height: isTyping ? '2rem' : 'auto',
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
alt="Bubble image"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,6 +28,7 @@ export const TextBubble = ({ step, onTransitionEnd }: Props) => {
|
||||
const content = useMemo(
|
||||
() =>
|
||||
parseVariables({ text: step.content.html, variables: typebot.variables }),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[typebot.variables]
|
||||
)
|
||||
|
||||
@ -40,6 +41,7 @@ export const TextBubble = ({ step, onTransitionEnd }: Props) => {
|
||||
setTimeout(() => {
|
||||
onTypingEnd()
|
||||
}, typingTimeout)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const onTypingEnd = () => {
|
||||
|
@ -28,6 +28,7 @@ export const VideoBubble = ({ step, onTransitionEnd }: Props) => {
|
||||
|
||||
useEffect(() => {
|
||||
showContentAfterMediaLoad()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const showContentAfterMediaLoad = () => {
|
||||
@ -86,6 +87,7 @@ const VideoContent = ({
|
||||
}) => {
|
||||
const url = useMemo(
|
||||
() => parseVariables({ text: content?.url, variables: variables }),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[variables]
|
||||
)
|
||||
if (!content?.type) return <></>
|
||||
|
@ -13,6 +13,7 @@ export const ChoiceForm = ({ options, onSubmit }: ChoiceFormProps) => {
|
||||
const { typebot } = useTypebot()
|
||||
const items = useMemo(
|
||||
() => filterTable(options?.itemIds ?? [], typebot.choiceItems),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
)
|
||||
const [selectedIds, setSelectedIds] = useState<string[]>([])
|
||||
@ -41,6 +42,7 @@ export const ChoiceForm = ({ options, onSubmit }: ChoiceFormProps) => {
|
||||
<div className="flex flex-wrap">
|
||||
{options?.itemIds.map((itemId) => (
|
||||
<button
|
||||
key={itemId}
|
||||
role={options?.isMultipleChoice ? 'checkbox' : 'button'}
|
||||
onClick={handleClick(itemId)}
|
||||
className={
|
||||
|
@ -26,7 +26,7 @@ type TextInputProps = {
|
||||
}
|
||||
|
||||
export const TextInput = ({ step, onChange }: TextInputProps) => {
|
||||
const inputRef = useRef<any>(null)
|
||||
const inputRef = useRef<HTMLInputElement & HTMLTextAreaElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!inputRef.current) return
|
||||
@ -102,7 +102,8 @@ export const TextInput = ({ step, onChange }: TextInputProps) => {
|
||||
case InputStepType.PHONE: {
|
||||
return (
|
||||
<PhoneInput
|
||||
ref={inputRef}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
ref={inputRef as any}
|
||||
onChange={handlePhoneNumberChange}
|
||||
placeholder={
|
||||
step.options?.labels?.placeholder ?? 'Your phone number...'
|
||||
|
@ -5,7 +5,7 @@ import { useFrame } from 'react-frame-component'
|
||||
import { setCssVariablesValue } from '../services/theme'
|
||||
import { useAnswers } from '../contexts/AnswersContext'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { Answer, Block, Edge, PublicTypebot } from 'models'
|
||||
import { Answer, Block, PublicTypebot } from 'models'
|
||||
|
||||
type Props = {
|
||||
typebot: PublicTypebot
|
||||
@ -45,6 +45,7 @@ export const ConversationContainer = ({
|
||||
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(() => {
|
||||
@ -56,6 +57,7 @@ export const ConversationContainer = ({
|
||||
if (!answer || deepEqual(localAnswer, answer)) return
|
||||
setLocalAnswer(answer)
|
||||
onNewAnswer(answer)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [answers])
|
||||
|
||||
return (
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import React, { useMemo } from 'react'
|
||||
import { TypebotContext } from '../contexts/TypebotContext'
|
||||
import Frame from 'react-frame-component'
|
||||
@ -61,7 +62,7 @@ export const TypebotViewer = ({
|
||||
}}
|
||||
/>
|
||||
<TypebotContext typebot={typebot}>
|
||||
<AnswersContext typebotId={typebot.id}>
|
||||
<AnswersContext>
|
||||
<div
|
||||
className="flex text-base overflow-hidden bg-cover h-screen w-screen flex-col items-center typebot-container"
|
||||
style={{
|
||||
@ -78,6 +79,17 @@ export const TypebotViewer = ({
|
||||
onCompleted={handleCompleted}
|
||||
/>
|
||||
</div>
|
||||
{typebot.settings.general.isBrandingEnabled && (
|
||||
<a
|
||||
href={'https://www.typebot.io/?utm_source=litebadge'}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="fixed py-1 px-2 bg-white z-50 rounded shadow-md"
|
||||
style={{ bottom: '20px' }}
|
||||
>
|
||||
Made with <span className="text-blue-500">Typebot</span>.
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</AnswersContext>
|
||||
</TypebotContext>
|
||||
|
Reference in New Issue
Block a user