🐛 Fix potential infinite redirect when session is remembered
Closes #1404
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/js",
|
"name": "@typebot.io/js",
|
||||||
"version": "0.2.58",
|
"version": "0.2.59",
|
||||||
"description": "Javascript library to display typebots on your website",
|
"description": "Javascript library to display typebots on your website",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
@ -70,7 +70,7 @@ type Props = {
|
|||||||
|
|
||||||
export const ConversationContainer = (props: Props) => {
|
export const ConversationContainer = (props: Props) => {
|
||||||
let chatContainer: HTMLDivElement | undefined
|
let chatContainer: HTMLDivElement | undefined
|
||||||
const [chatChunks, setChatChunks] = persist(
|
const [chatChunks, setChatChunks, isRecovered] = persist(
|
||||||
createSignal<ChatChunkType[]>([
|
createSignal<ChatChunkType[]>([
|
||||||
{
|
{
|
||||||
input: props.initialChatReply.input,
|
input: props.initialChatReply.input,
|
||||||
@ -81,6 +81,11 @@ export const ConversationContainer = (props: Props) => {
|
|||||||
{
|
{
|
||||||
key: `typebot-${props.context.typebot.id}-chatChunks`,
|
key: `typebot-${props.context.typebot.id}-chatChunks`,
|
||||||
storage: props.context.storage,
|
storage: props.context.storage,
|
||||||
|
onRecovered: () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
chatContainer?.scrollTo(0, chatContainer.scrollHeight)
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const [dynamicTheme, setDynamicTheme] = createSignal<
|
const [dynamicTheme, setDynamicTheme] = createSignal<
|
||||||
@ -297,7 +302,10 @@ export const ConversationContainer = (props: Props) => {
|
|||||||
(chatChunk.messages.length > 0 && isSending()))
|
(chatChunk.messages.length > 0 && isSending()))
|
||||||
}
|
}
|
||||||
hasError={hasError() && index() === chatChunks().length - 1}
|
hasError={hasError() && index() === chatChunks().length - 1}
|
||||||
isTransitionDisabled={index() !== chatChunks().length - 1}
|
isTransitionDisabled={
|
||||||
|
index() !== chatChunks().length - 1 ||
|
||||||
|
(!chatChunk.input && isRecovered())
|
||||||
|
}
|
||||||
onNewBubbleDisplayed={handleNewBubbleDisplayed}
|
onNewBubbleDisplayed={handleNewBubbleDisplayed}
|
||||||
onAllBubblesDisplayed={handleAllBubblesDisplayed}
|
onAllBubblesDisplayed={handleAllBubblesDisplayed}
|
||||||
onSubmit={sendMessage}
|
onSubmit={sendMessage}
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
// Copied from https://github.com/solidjs-community/solid-primitives/blob/main/packages/storage/src/types.ts
|
// 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 */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
|
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
|
||||||
import type { Setter, Signal } from 'solid-js'
|
import type { Setter, Signal } from 'solid-js'
|
||||||
import { untrack } from 'solid-js'
|
import { createSignal, untrack } from 'solid-js'
|
||||||
import { reconcile } from 'solid-js/store'
|
import { reconcile } from 'solid-js/store'
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
key: string
|
key: string
|
||||||
storage: 'local' | 'session' | undefined
|
storage: 'local' | 'session' | undefined
|
||||||
|
onRecovered?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function persist<T>(signal: Signal<T>, params: Params): Signal<T> {
|
export function persist<T>(
|
||||||
if (!params.storage) return signal
|
signal: Signal<T>,
|
||||||
|
params: Params
|
||||||
|
): [...Signal<T>, () => boolean] {
|
||||||
|
const [isRecovered, setIsRecovered] = createSignal(false)
|
||||||
|
if (!params.storage) return [...signal, () => false]
|
||||||
|
|
||||||
const storage = parseRememberUserStorage(
|
const storage = parseRememberUserStorage(
|
||||||
params.storage || defaultSettings.general.rememberUser.storage
|
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)(() => deserialize(data))
|
||||||
: (data: string) => (signal[1] as any)(reconcile(deserialize(data)))
|
: (data: string) => (signal[1] as any)(reconcile(deserialize(data)))
|
||||||
|
|
||||||
if (init) set(init)
|
if (init) {
|
||||||
|
set(init)
|
||||||
|
setIsRecovered(true)
|
||||||
|
params.onRecovered?.()
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
signal[0],
|
signal[0],
|
||||||
typeof signal[0] === 'function'
|
typeof signal[0] === 'function'
|
||||||
? (value?: T | ((prev: T) => T)) => {
|
? (value?: T | ((prev: T) => T)) => {
|
||||||
|
setIsRecovered(false)
|
||||||
const output = (signal[1] as Setter<T>)(value as any)
|
const output = (signal[1] as Setter<T>)(value as any)
|
||||||
|
|
||||||
if (value) storage.setItem(params.key, serialize(output))
|
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
|
return output
|
||||||
}
|
}
|
||||||
: (...args: any[]) => {
|
: (...args: any[]) => {
|
||||||
|
setIsRecovered(false)
|
||||||
;(signal[1] as any)(...args)
|
;(signal[1] as any)(...args)
|
||||||
const value = serialize(untrack(() => signal[0] as any))
|
const value = serialize(untrack(() => signal[0] as any))
|
||||||
storage.setItem(params.key, value)
|
storage.setItem(params.key, value)
|
||||||
},
|
},
|
||||||
] as typeof signal
|
isRecovered,
|
||||||
|
] as [...typeof signal, () => boolean]
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseRememberUserStorage = (
|
const parseRememberUserStorage = (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/nextjs",
|
"name": "@typebot.io/nextjs",
|
||||||
"version": "0.2.58",
|
"version": "0.2.59",
|
||||||
"description": "Convenient library to display typebots on your Next.js website",
|
"description": "Convenient library to display typebots on your Next.js website",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@typebot.io/react",
|
"name": "@typebot.io/react",
|
||||||
"version": "0.2.58",
|
"version": "0.2.59",
|
||||||
"description": "Convenient library to display typebots on your React app",
|
"description": "Convenient library to display typebots on your React app",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
Reference in New Issue
Block a user