Skip to content

Commit

Permalink
🐛 (js) Improve bubbles callback reliability
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Mar 1, 2023
1 parent 5024c1b commit f6e128b
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 33 deletions.
20 changes: 18 additions & 2 deletions apps/builder/sentry.client.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
})
16 changes: 12 additions & 4 deletions apps/viewer/sentry.client.config.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
},
})
2 changes: 1 addition & 1 deletion packages/js/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
Expand Down
Original file line number Diff line number Diff line change
@@ -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']
Expand All @@ -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()
Expand All @@ -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">
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -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()
Expand All @@ -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 (
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 (
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down

3 comments on commit f6e128b

@vercel
Copy link

@vercel vercel bot commented on f6e128b Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs-git-main-typebot-io.vercel.app
docs-typebot-io.vercel.app
docs.typebot.io

@vercel
Copy link

@vercel vercel bot commented on f6e128b Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on f6e128b Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

ns8.vn
1stop.au
yobot.me
klujo.com
247987.com
8jours.top
myrentalhost.com
stan.vselise.com
start.taxtree.io
typebot.aloe.bot
voicehelp.cr8.ai
zap.fundviser.in
app.chatforms.net
bot.hostnation.de
bot.maitempah.com
bot.phuonghub.com
bot.reviewzer.com
bot.rihabilita.it
cares.urlabout.me
chat.gaswadern.de
fmm.wpwakanda.com
gentleman-shop.fr
k1.kandabrand.com
kp.pedroknoll.com
lb.ticketfute.com
ov1.wpwakanda.com
ov2.wpwakanda.com
ov3.wpwakanda.com
support.triplo.ai
viewer.typebot.io
welcome.triplo.ai
1988.bouclidom.com
andreimayer.com.br
bot.danyservice.it
bot.iconicbrows.it
bot.megafox.com.br
bot.neferlopez.com
bots.robomotion.io
cadu.uninta.edu.br
dicanatural.online
digitalhelp.com.au
goalsettingbot.com
pant.maxbot.com.br
positivobra.com.br
survey.digienge.io
this-is-a-test.com
zap.techadviser.in
bot.boston-voip.com
bot.cabinpromos.com
bot.digitalbled.com
bot.dsignagency.com
bot.eventhub.com.au
bot.jepierre.com.br
bot.hotelplayarimini.it
bot.upgradesolutions.eu
bots.baptiste-arnaud.fr
help.comebackreward.com
link.venturasuceder.com
mainmenu.diddancing.com
manualhandlingcourse.ie
register.kandabrand.com
signup.hypemarketing.in
subfooter.wpwakanda.com
survey.hypemarketing.in
testbot.afterorigin.com
typebot.influencer.love
91181264.your-access.one
ai.chromebookstoreph.com
contextone.wpwakanda.com
form.sergiolimajr.com.br
hunterbot.saleshunter.ai
invite.bridesquadapp.com
link.cascadigital.com.br
onboarding.growthside.io
reward.onlinebotdemo.xyz
stap.venturemarketing.in
type.opaulovieira.com.br
aibot.angrybranding.co.uk
bot.aidigitalmarketing.kr
bot.amicidisanfaustino.it
bot.arraesecenteno.com.br
bot.blackboxsports.com.br
bot.cabinrentalagency.com
bot.fusionstarreviews.com
boyfriend-breakup.riku.ai
brigadeirosemdrama.com.br
chat.ertcrebateportal.com
chat.thehomebuyersusa.com
chat.thisiscrushhouse.com
forms.hiabhaykulkarni.com
healthandsafetycourses.uk
sellmyharleylouisiana.com
testbot.sharemyreview.net
typebot-viewer.vercel.app
verfica.botmachine.com.br
bot.adventureconsulting.hu
bot2.fusionstarreviews.com
casestudyemb.wpwakanda.com
chat.atlasoutfittersk9.com
configurator.bouclidom.com

Please sign in to comment.