2022-12-22 17:02:34 +01:00
|
|
|
import { BotContext } from '@/types'
|
2023-03-07 17:11:24 +01:00
|
|
|
import { isMobile } from '@/utils/isMobileSignal'
|
2023-03-15 08:35:16 +01:00
|
|
|
import type { ChatReply, Settings, Theme } from '@typebot.io/schemas'
|
2023-01-25 11:27:47 +01:00
|
|
|
import { createSignal, For, onMount, Show } from 'solid-js'
|
2022-12-22 17:02:34 +01:00
|
|
|
import { HostBubble } from '../bubbles/HostBubble'
|
|
|
|
import { InputChatBlock } from '../InputChatBlock'
|
|
|
|
import { AvatarSideContainer } from './AvatarSideContainer'
|
|
|
|
|
|
|
|
type Props = Pick<ChatReply, 'messages' | 'input'> & {
|
|
|
|
theme: Theme
|
|
|
|
settings: Settings
|
|
|
|
inputIndex: number
|
|
|
|
context: BotContext
|
2023-01-27 10:54:59 +01:00
|
|
|
isLoadingBubbleDisplayed: boolean
|
2023-04-03 18:14:32 +02:00
|
|
|
hasError: boolean
|
2023-01-27 10:54:59 +01:00
|
|
|
onNewBubbleDisplayed: (blockId: string) => Promise<void>
|
2023-01-16 12:13:21 +01:00
|
|
|
onScrollToBottom: () => void
|
2022-12-22 17:02:34 +01:00
|
|
|
onSubmit: (input: string) => void
|
|
|
|
onSkip: () => void
|
2023-01-26 15:26:42 +01:00
|
|
|
onAllBubblesDisplayed: () => void
|
2022-12-22 17:02:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export const ChatChunk = (props: Props) => {
|
|
|
|
const [displayedMessageIndex, setDisplayedMessageIndex] = createSignal(0)
|
|
|
|
|
2023-01-25 11:27:47 +01:00
|
|
|
onMount(() => {
|
2023-01-26 15:26:42 +01:00
|
|
|
if (props.messages.length === 0) {
|
|
|
|
props.onAllBubblesDisplayed()
|
|
|
|
}
|
2023-01-25 11:27:47 +01:00
|
|
|
props.onScrollToBottom()
|
|
|
|
})
|
|
|
|
|
2023-01-27 10:54:59 +01:00
|
|
|
const displayNextMessage = async () => {
|
|
|
|
const lastBubbleBlockId = props.messages[displayedMessageIndex()].id
|
|
|
|
await props.onNewBubbleDisplayed(lastBubbleBlockId)
|
2022-12-22 17:02:34 +01:00
|
|
|
setDisplayedMessageIndex(
|
|
|
|
displayedMessageIndex() === props.messages.length
|
|
|
|
? displayedMessageIndex()
|
|
|
|
: displayedMessageIndex() + 1
|
|
|
|
)
|
2023-01-16 12:13:21 +01:00
|
|
|
props.onScrollToBottom()
|
2023-01-26 15:26:42 +01:00
|
|
|
if (displayedMessageIndex() === props.messages.length) {
|
|
|
|
props.onAllBubblesDisplayed()
|
|
|
|
}
|
2022-12-22 17:02:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div class="flex w-full">
|
2023-03-23 08:59:08 +01:00
|
|
|
<div class="flex flex-col w-full min-w-0">
|
2022-12-22 17:02:34 +01:00
|
|
|
<div class="flex">
|
|
|
|
<Show
|
|
|
|
when={
|
|
|
|
props.theme.chat.hostAvatar?.isEnabled &&
|
|
|
|
props.messages.length > 0
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<AvatarSideContainer
|
|
|
|
hostAvatarSrc={props.theme.chat.hostAvatar?.url}
|
|
|
|
/>
|
|
|
|
</Show>
|
|
|
|
<div
|
|
|
|
class="flex-1"
|
|
|
|
style={{
|
|
|
|
'margin-right': props.theme.chat.guestAvatar?.isEnabled
|
2023-03-07 17:11:24 +01:00
|
|
|
? isMobile()
|
|
|
|
? '32px'
|
|
|
|
: '48px'
|
|
|
|
: undefined,
|
2022-12-22 17:02:34 +01:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
<For each={props.messages.slice(0, displayedMessageIndex() + 1)}>
|
|
|
|
{(message) => (
|
|
|
|
<HostBubble
|
|
|
|
message={message}
|
2023-02-23 07:42:45 +01:00
|
|
|
typingEmulation={props.settings.typingEmulation}
|
2022-12-22 17:02:34 +01:00
|
|
|
onTransitionEnd={displayNextMessage}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</For>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{props.input && displayedMessageIndex() === props.messages.length && (
|
|
|
|
<InputChatBlock
|
|
|
|
block={props.input}
|
|
|
|
inputIndex={props.inputIndex}
|
|
|
|
onSubmit={props.onSubmit}
|
|
|
|
onSkip={props.onSkip}
|
2023-03-07 17:11:24 +01:00
|
|
|
hasHostAvatar={props.theme.chat.hostAvatar?.isEnabled ?? false}
|
2022-12-22 17:02:34 +01:00
|
|
|
guestAvatar={props.theme.chat.guestAvatar}
|
|
|
|
context={props.context}
|
2023-01-25 11:27:47 +01:00
|
|
|
isInputPrefillEnabled={
|
|
|
|
props.settings.general.isInputPrefillEnabled ?? true
|
|
|
|
}
|
2023-04-03 18:14:32 +02:00
|
|
|
hasError={props.hasError}
|
2022-12-22 17:02:34 +01:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|