2
0

refactor(♻️ Add defaults everywhere (+ settings page)):

This commit is contained in:
Baptiste Arnaud
2022-01-25 18:19:37 +01:00
parent 21448bcc8a
commit c5aaa323d1
115 changed files with 1436 additions and 720 deletions

View File

@ -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 (

View File

@ -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 () => {

View File

@ -42,6 +42,7 @@ const InputChatStep = ({
useEffect(() => {
addNewAvatarOffset()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const handleSubmit = (value: string) => {

View File

@ -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>

View File

@ -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 = () => {

View File

@ -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 <></>

View File

@ -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={

View File

@ -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...'

View File

@ -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 (

View File

@ -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>

View File

@ -4,16 +4,11 @@ import React, { createContext, ReactNode, useContext, useState } from 'react'
const answersContext = createContext<{
answers: Answer[]
addAnswer: (answer: Answer) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})
export const AnswersContext = ({
children,
typebotId,
}: {
children: ReactNode
typebotId: string
}) => {
export const AnswersContext = ({ children }: { children: ReactNode }) => {
const [answers, setAnswers] = useState<Answer[]>([])
const addAnswer = (answer: Answer) =>

View File

@ -5,6 +5,7 @@ const hostAvatarsContext = createContext<{
lastBubblesTopOffset: number[]
addNewAvatarOffset: () => void
updateLastAvatarOffset: (newOffset: number) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})

View File

@ -4,6 +4,7 @@ import React, { createContext, ReactNode, useContext, useState } from 'react'
const typebotContext = createContext<{
typebot: PublicTypebot
updateVariableValue: (variableId: string, value: string) => void
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
}>({})

View File

@ -1,8 +1,8 @@
import { TypingEmulationSettings } from 'models'
import { TypingEmulation } from 'models'
export const computeTypingTimeout = (
bubbleContent: string,
typingSettings: TypingEmulationSettings
typingSettings: TypingEmulation
) => {
const wordCount = bubbleContent.match(/(\w+)/g)?.length ?? 0
const typedWordsPerMinute = typingSettings.speed

View File

@ -1,4 +1,4 @@
import { ChoiceInputStep, ChoiceItem, Table, Target } from 'models'
import { ChoiceInputStep, ChoiceItem, Table } from 'models'
export const getSingleChoiceTargetId = (
currentStep: ChoiceInputStep,

View File

@ -10,7 +10,6 @@ import {
Cell,
GoogleSheetsGetOptions,
GoogleAnalyticsStep,
Webhook,
WebhookStep,
} from 'models'
import { stringify } from 'qs'

View File

@ -28,7 +28,7 @@ export const isMathFormula = (str?: string) =>
['*', '/', '+', '-'].some((val) => str && str.includes(val))
export const evaluateExpression = (str: string) => {
let result = replaceCommasWithDots(str)
const result = replaceCommasWithDots(str)
try {
const evaluatedNumber = safeEval(result) as number
if (countDecimals(evaluatedNumber) > 2) {