♻️ Simplify text bubble content shape
Remove html and plainText field because it was redundant Closes #386
This commit is contained in:
@ -30,7 +30,7 @@ export const HostBubble = (props: Props) => {
|
||||
<Switch>
|
||||
<Match when={props.message.type === BubbleBlockType.TEXT}>
|
||||
<TextBubble
|
||||
content={props.message.content as Omit<TextBubbleContent, 'richText'>}
|
||||
content={props.message.content as TextBubbleContent}
|
||||
typingEmulation={props.typingEmulation}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
/>
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { TypingBubble } from '@/components'
|
||||
import type { TextBubbleContent, TypingEmulation } from '@typebot.io/schemas'
|
||||
import { createSignal, onCleanup, onMount } from 'solid-js'
|
||||
import { computeTypingDuration } from '../utils/computeTypingDuration'
|
||||
import { For, createSignal, onCleanup, onMount } from 'solid-js'
|
||||
import { computeTypingDuration } from '../helpers/computeTypingDuration'
|
||||
import { PlateBlock } from './plate/PlateBlock'
|
||||
import { computePlainText } from '../helpers/convertRichTextToPlainText'
|
||||
|
||||
type Props = {
|
||||
content: Pick<TextBubbleContent, 'html' | 'plainText'>
|
||||
content: TextBubbleContent
|
||||
typingEmulation: TypingEmulation
|
||||
onTransitionEnd: () => void
|
||||
}
|
||||
@ -32,11 +34,12 @@ export const TextBubble = (props: Props) => {
|
||||
|
||||
onMount(() => {
|
||||
if (!isTyping) return
|
||||
const plainText = computePlainText(props.content.richText)
|
||||
const typingDuration =
|
||||
props.typingEmulation?.enabled === false
|
||||
? 0
|
||||
: computeTypingDuration(
|
||||
props.content.plainText,
|
||||
plainText,
|
||||
props.typingEmulation ?? defaultTypingEmulation
|
||||
)
|
||||
typingTimeout = setTimeout(onTypingEnd, typingDuration)
|
||||
@ -60,13 +63,16 @@ export const TextBubble = (props: Props) => {
|
||||
>
|
||||
{isTyping() && <TypingBubble />}
|
||||
</div>
|
||||
<p
|
||||
<div
|
||||
class={
|
||||
'overflow-hidden text-fade-in mx-4 my-2 whitespace-pre-wrap slate-html-container relative text-ellipsis ' +
|
||||
(isTyping() ? 'opacity-0 h-6' : 'opacity-100 h-full')
|
||||
}
|
||||
innerHTML={props.content.html}
|
||||
/>
|
||||
>
|
||||
<For each={props.content.richText}>
|
||||
{(element) => <PlateBlock element={element} />}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,30 @@
|
||||
import type { TElement, TText, TDescendant } from '@udecode/plate-common'
|
||||
import { PlateText, PlateTextProps } from './PlateText'
|
||||
import { For, Match, Show, Switch } from 'solid-js'
|
||||
|
||||
type Props = { element: TElement | TText }
|
||||
|
||||
export const PlateBlock = (props: Props) => (
|
||||
<Show
|
||||
when={!props.element.text}
|
||||
fallback={<PlateText {...(props.element as PlateTextProps)} />}
|
||||
>
|
||||
<Switch
|
||||
fallback={
|
||||
<div>
|
||||
<For each={props.element.children as TDescendant[]}>
|
||||
{(child) => <PlateBlock element={child} />}
|
||||
</For>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Match when={props.element.type === 'a'}>
|
||||
<a href={props.element.url as string} target="_blank" class="slate-a">
|
||||
<For each={props.element.children as TDescendant[]}>
|
||||
{(child) => <PlateBlock element={child} />}
|
||||
</For>
|
||||
</a>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Show>
|
||||
)
|
@ -0,0 +1,30 @@
|
||||
import { Show } from 'solid-js'
|
||||
|
||||
export type PlateTextProps = {
|
||||
text: string
|
||||
bold?: boolean
|
||||
italic?: boolean
|
||||
underline?: boolean
|
||||
}
|
||||
|
||||
const computeClassNames = (
|
||||
bold: boolean | undefined,
|
||||
italic: boolean | undefined,
|
||||
underline: boolean | undefined
|
||||
) => {
|
||||
let className = ''
|
||||
if (bold) className += 'slate-bold'
|
||||
if (italic) className += ' slate-italic'
|
||||
if (underline) className += ' slate-underline'
|
||||
return className
|
||||
}
|
||||
|
||||
export const PlateText = (props: PlateTextProps) => (
|
||||
<Show
|
||||
when={computeClassNames(props.bold, props.italic, props.underline)}
|
||||
keyed
|
||||
fallback={<>{props.text}</>}
|
||||
>
|
||||
{(className) => <span class={className}>{props.text}</span>}
|
||||
</Show>
|
||||
)
|
@ -0,0 +1,9 @@
|
||||
import type { TDescendant } from '@udecode/plate-common'
|
||||
|
||||
export const computePlainText = (elements: TDescendant[]): string =>
|
||||
elements
|
||||
.map(
|
||||
(element) =>
|
||||
element.text ?? computePlainText(element.children as TDescendant[])
|
||||
)
|
||||
.join('')
|
Reference in New Issue
Block a user