2
0

🐛 (js) Improve bubbles callback reliability

This commit is contained in:
Baptiste Arnaud
2023-03-01 08:42:47 +01:00
parent 5024c1b22b
commit f6e128be37
8 changed files with 68 additions and 33 deletions

View File

@ -4,7 +4,23 @@ const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN
Sentry.init({
dsn: SENTRY_DSN,
ignoreErrors: ['ResizeObserver loop limit exceeded'],
debug: true,
ignoreErrors: [
'ResizeObserver loop limit exceeded',
'ResizeObserver loop completed with undelivered notifications.',
'ResizeObserver is not defined',
"Can't find variable: ResizeObserver",
],
release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA + '-builder',
beforeBreadcrumb(breadcrumb, hint) {
try {
if (breadcrumb.category.startsWith('ui')) {
breadcrumb.message = `${hint.event.target.tagName.toLowerCase()}: ${
hint.event.target.innerText
}`
}
} catch (e) {
/* empty */
}
return breadcrumb
},
})

View File

@ -1,7 +1,3 @@
// This file configures the initialization of Sentry on the browser.
// The config you add here will be used whenever a page is visited.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from '@sentry/nextjs'
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN
@ -15,4 +11,16 @@ Sentry.init({
"Can't find variable: ResizeObserver",
],
release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA + '-viewer',
beforeBreadcrumb(breadcrumb, hint) {
try {
if (breadcrumb.category.startsWith('ui')) {
breadcrumb.message = `${hint.event.target.tagName.toLowerCase()}: ${
hint.event.target.innerText
}`
}
} catch (e) {
/* empty */
}
return breadcrumb
},
})

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.0.16",
"version": "0.0.17",
"description": "Javascript library to display typebots on your website",
"type": "module",
"main": "dist/index.js",

View File

@ -1,24 +1,30 @@
import { TypingBubble } from '@/components'
import type { EmbedBubbleContent } from 'models'
import { createSignal, onMount } from 'solid-js'
import { createSignal, onCleanup, onMount } from 'solid-js'
type Props = {
content: EmbedBubbleContent
onTransitionEnd: () => void
}
let typingTimeout: NodeJS.Timeout
export const showAnimationDuration = 400
export const EmbedBubble = (props: Props) => {
const [isTyping, setIsTyping] = createSignal(true)
onMount(() => {
setTimeout(() => {
typingTimeout = setTimeout(() => {
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd()
}, showAnimationDuration)
}, 1000)
}, 2000)
})
onCleanup(() => {
if (typingTimeout) clearTimeout(typingTimeout)
})
return (

View File

@ -1,6 +1,6 @@
import { TypingBubble } from '@/components'
import type { ImageBubbleContent } from 'models'
import { createSignal, onMount } from 'solid-js'
import { createSignal, onCleanup, onMount } from 'solid-js'
type Props = {
url: ImageBubbleContent['url']
@ -11,11 +11,14 @@ export const showAnimationDuration = 400
export const mediaLoadingFallbackTimeout = 5000
let typingTimeout: NodeJS.Timeout
export const ImageBubble = (props: Props) => {
let image: HTMLImageElement | undefined
const [isTyping, setIsTyping] = createSignal(true)
const onTypingEnd = () => {
if (!isTyping()) return
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd()
@ -24,17 +27,17 @@ export const ImageBubble = (props: Props) => {
onMount(() => {
if (!image) return
const timeout = setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, mediaLoadingFallbackTimeout)
typingTimeout = setTimeout(onTypingEnd, mediaLoadingFallbackTimeout)
image.onload = () => {
clearTimeout(timeout)
setIsTyping(false)
clearTimeout(typingTimeout)
onTypingEnd()
}
})
onCleanup(() => {
if (typingTimeout) clearTimeout(typingTimeout)
})
return (
<div class="flex flex-col animate-fade-in">
<div class="flex mb-2 w-full lg:w-11/12 items-center">

View File

@ -1,6 +1,6 @@
import { TypingBubble } from '@/components'
import type { TextBubbleContent, TypingEmulation } from 'models'
import { createSignal, onMount } from 'solid-js'
import { createSignal, onCleanup, onMount } from 'solid-js'
import { computeTypingDuration } from '../utils/computeTypingDuration'
type Props = {
@ -17,10 +17,13 @@ const defaultTypingEmulation = {
maxDelay: 1.5,
}
let typingTimeout: NodeJS.Timeout
export const TextBubble = (props: Props) => {
const [isTyping, setIsTyping] = createSignal(true)
const onTypingEnd = () => {
if (!isTyping()) return
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd()
@ -36,9 +39,11 @@ export const TextBubble = (props: Props) => {
props.content.plainText,
props.typingEmulation ?? defaultTypingEmulation
)
setTimeout(() => {
onTypingEnd()
}, typingDuration)
typingTimeout = setTimeout(onTypingEnd, typingDuration)
})
onCleanup(() => {
if (typingTimeout) clearTimeout(typingTimeout)
})
return (

View File

@ -1,7 +1,7 @@
import { TypingBubble } from '@/components'
import type { VideoBubbleContent } from 'models'
import { VideoBubbleContentType } from 'models/features/blocks/bubbles/video/enums'
import { createSignal, Match, onMount, Switch } from 'solid-js'
import { createSignal, Match, onCleanup, onMount, Switch } from 'solid-js'
type Props = {
content: VideoBubbleContent
@ -10,28 +10,25 @@ type Props = {
export const showAnimationDuration = 400
export const mediaLoadingFallbackTimeout = 5000
let typingTimeout: NodeJS.Timeout
export const VideoBubble = (props: Props) => {
const [isTyping, setIsTyping] = createSignal(true)
const onTypingEnd = () => {
if (!isTyping()) return
setIsTyping(false)
setTimeout(() => {
props.onTransitionEnd()
}, showAnimationDuration)
}
const showContentAfterMediaLoad = () => {
setTimeout(() => {
setIsTyping(false)
onTypingEnd()
}, 1000)
}
onMount(() => {
if (!isTyping) return
showContentAfterMediaLoad()
typingTimeout = setTimeout(onTypingEnd, 2000)
})
onCleanup(() => {
if (typingTimeout) clearTimeout(typingTimeout)
})
return (

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.0.16",
"version": "0.0.17",
"description": "React library to display typebots on your website",
"main": "dist/index.js",
"types": "dist/index.d.ts",