2
0

🐛 Fix potential infinite redirect when session is remembered

Closes #1404
This commit is contained in:
Baptiste Arnaud
2024-04-02 13:31:43 +02:00
parent 89dec4a6dc
commit 50d515cf37
5 changed files with 31 additions and 11 deletions

View File

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

View File

@ -70,7 +70,7 @@ type Props = {
export const ConversationContainer = (props: Props) => {
let chatContainer: HTMLDivElement | undefined
const [chatChunks, setChatChunks] = persist(
const [chatChunks, setChatChunks, isRecovered] = persist(
createSignal<ChatChunkType[]>([
{
input: props.initialChatReply.input,
@ -81,6 +81,11 @@ export const ConversationContainer = (props: Props) => {
{
key: `typebot-${props.context.typebot.id}-chatChunks`,
storage: props.context.storage,
onRecovered: () => {
setTimeout(() => {
chatContainer?.scrollTo(0, chatContainer.scrollHeight)
}, 200)
},
}
)
const [dynamicTheme, setDynamicTheme] = createSignal<
@ -297,7 +302,10 @@ export const ConversationContainer = (props: Props) => {
(chatChunk.messages.length > 0 && isSending()))
}
hasError={hasError() && index() === chatChunks().length - 1}
isTransitionDisabled={index() !== chatChunks().length - 1}
isTransitionDisabled={
index() !== chatChunks().length - 1 ||
(!chatChunk.input && isRecovered())
}
onNewBubbleDisplayed={handleNewBubbleDisplayed}
onAllBubblesDisplayed={handleAllBubblesDisplayed}
onSubmit={sendMessage}

View File

@ -1,19 +1,24 @@
// Copied from https://github.com/solidjs-community/solid-primitives/blob/main/packages/storage/src/types.ts
// Simplifying and adding a `isEnabled` prop
// Simplified version
/* eslint-disable @typescript-eslint/no-explicit-any */
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
import type { Setter, Signal } from 'solid-js'
import { untrack } from 'solid-js'
import { createSignal, untrack } from 'solid-js'
import { reconcile } from 'solid-js/store'
type Params = {
key: string
storage: 'local' | 'session' | undefined
onRecovered?: () => void
}
export function persist<T>(signal: Signal<T>, params: Params): Signal<T> {
if (!params.storage) return signal
export function persist<T>(
signal: Signal<T>,
params: Params
): [...Signal<T>, () => boolean] {
const [isRecovered, setIsRecovered] = createSignal(false)
if (!params.storage) return [...signal, () => false]
const storage = parseRememberUserStorage(
params.storage || defaultSettings.general.rememberUser.storage
@ -26,12 +31,17 @@ export function persist<T>(signal: Signal<T>, params: Params): Signal<T> {
? (data: string) => (signal[1] as any)(() => deserialize(data))
: (data: string) => (signal[1] as any)(reconcile(deserialize(data)))
if (init) set(init)
if (init) {
set(init)
setIsRecovered(true)
params.onRecovered?.()
}
return [
signal[0],
typeof signal[0] === 'function'
? (value?: T | ((prev: T) => T)) => {
setIsRecovered(false)
const output = (signal[1] as Setter<T>)(value as any)
if (value) storage.setItem(params.key, serialize(output))
@ -39,11 +49,13 @@ export function persist<T>(signal: Signal<T>, params: Params): Signal<T> {
return output
}
: (...args: any[]) => {
setIsRecovered(false)
;(signal[1] as any)(...args)
const value = serialize(untrack(() => signal[0] as any))
storage.setItem(params.key, value)
},
] as typeof signal
isRecovered,
] as [...typeof signal, () => boolean]
}
const parseRememberUserStorage = (

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/nextjs",
"version": "0.2.58",
"version": "0.2.59",
"description": "Convenient library to display typebots on your Next.js website",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

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