🐛 (attachments) Fix attachments on mobile and fix long text…
Closes #1611, closes #1610
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/js",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "Javascript library to display typebots on your website",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BotContext, ChatChunk as ChatChunkType } from '@/types'
|
||||
import { Answer, BotContext, ChatChunk as ChatChunkType } from '@/types'
|
||||
import { isMobile } from '@/utils/isMobileSignal'
|
||||
import { ContinueChatResponse, Settings, Theme } from '@typebot.io/schemas'
|
||||
import { createSignal, For, onMount, Show } from 'solid-js'
|
||||
@ -23,7 +23,7 @@ type Props = Pick<ContinueChatResponse, 'messages' | 'input'> & {
|
||||
isTransitionDisabled?: boolean
|
||||
onNewBubbleDisplayed: (blockId: string) => Promise<void>
|
||||
onScrollToBottom: (ref?: HTMLDivElement, offset?: number) => void
|
||||
onSubmit: (input?: string) => void
|
||||
onSubmit: (answer?: string, attachments?: Answer['attachments']) => void
|
||||
onSkip: () => void
|
||||
onAllBubblesDisplayed: () => void
|
||||
}
|
||||
|
@ -15,7 +15,12 @@ import {
|
||||
} from 'solid-js'
|
||||
import { continueChatQuery } from '@/queries/continueChatQuery'
|
||||
import { ChatChunk } from './ChatChunk'
|
||||
import { BotContext, ChatChunk as ChatChunkType, OutgoingLog } from '@/types'
|
||||
import {
|
||||
Answer,
|
||||
BotContext,
|
||||
ChatChunk as ChatChunkType,
|
||||
OutgoingLog,
|
||||
} from '@/types'
|
||||
import { isNotDefined } from '@typebot.io/lib'
|
||||
import { executeClientSideAction } from '@/utils/executeClientSideActions'
|
||||
import { LoadingChunk } from './LoadingChunk'
|
||||
@ -137,7 +142,10 @@ export const ConversationContainer = (props: Props) => {
|
||||
})
|
||||
}
|
||||
|
||||
const sendMessage = async (message: string | undefined) => {
|
||||
const sendMessage = async (
|
||||
message?: string,
|
||||
attachments?: Answer['attachments']
|
||||
) => {
|
||||
setHasError(false)
|
||||
const currentInputBlock = [...chatChunks()].pop()?.input
|
||||
if (currentInputBlock?.id && props.onAnswer && message)
|
||||
@ -149,7 +157,13 @@ export const ConversationContainer = (props: Props) => {
|
||||
const { data, error } = await continueChatQuery({
|
||||
apiHost: props.context.apiHost,
|
||||
sessionId: props.initialChatReply.sessionId,
|
||||
message,
|
||||
message: message
|
||||
? {
|
||||
type: 'text',
|
||||
text: message,
|
||||
attachedFileUrls: attachments?.map((attachment) => attachment.url),
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
clearTimeout(longRequest)
|
||||
setIsSending(false)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Show } from 'solid-js'
|
||||
import { Match, Switch } from 'solid-js'
|
||||
import { Menu } from '@ark-ui/solid'
|
||||
import { CameraIcon } from './icons/CameraIcon'
|
||||
import { FileIcon } from './icons/FileIcon'
|
||||
import { PictureIcon } from './icons/PictureIcon'
|
||||
import { isMobile } from '@/utils/isMobileSignal'
|
||||
@ -35,69 +34,62 @@ export const TextInputAddFileButton = (props: Props) => {
|
||||
props.onNewFiles(e.currentTarget.files)
|
||||
}}
|
||||
/>
|
||||
<Show when={isMobile()}>
|
||||
<input
|
||||
type="file"
|
||||
id="camera-upload"
|
||||
class="hidden"
|
||||
multiple
|
||||
accept="image/*"
|
||||
capture="environment"
|
||||
onChange={(e) => {
|
||||
if (!e.currentTarget.files) return
|
||||
props.onNewFiles(e.currentTarget.files)
|
||||
}}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
class={clsx(
|
||||
'filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none',
|
||||
props.class
|
||||
)}
|
||||
aria-label="Add attachments"
|
||||
>
|
||||
<PaperClipIcon class="w-5" />
|
||||
</Menu.Trigger>
|
||||
<Menu.Positioner>
|
||||
<Menu.Content class="p-3 gap-2 focus:outline-none">
|
||||
<Menu.Item
|
||||
value="document"
|
||||
asChild={(props) => (
|
||||
<label
|
||||
{...props()}
|
||||
for="document-upload"
|
||||
class="p-2 filter hover:brightness-95 flex gap-3 items-center"
|
||||
>
|
||||
<FileIcon class="w-4" /> Document
|
||||
</label>
|
||||
<Switch>
|
||||
<Match when={isMobile()}>
|
||||
<label
|
||||
aria-label="Add attachments"
|
||||
for="document-upload"
|
||||
class={clsx(
|
||||
'filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none',
|
||||
props.class
|
||||
)}
|
||||
>
|
||||
<PaperClipIcon class="w-5" />
|
||||
</label>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
class={clsx(
|
||||
'filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none',
|
||||
props.class
|
||||
)}
|
||||
/>
|
||||
<Menu.Item
|
||||
value="photos"
|
||||
asChild={(props) => (
|
||||
<label
|
||||
{...props()}
|
||||
for="photos-upload"
|
||||
class="p-2 filter hover:brightness-95 flex gap-3 items-center"
|
||||
>
|
||||
<PictureIcon class="w-4" /> Photos & videos
|
||||
</label>
|
||||
)}
|
||||
/>
|
||||
<Show when={isMobile()}>
|
||||
<Menu.Item
|
||||
value="camera"
|
||||
class="p-2 filter hover:brightness-95 flex gap-3 items-center"
|
||||
>
|
||||
<CameraIcon class="w-4" />
|
||||
Camera
|
||||
</Menu.Item>
|
||||
</Show>
|
||||
</Menu.Content>
|
||||
</Menu.Positioner>
|
||||
</Menu.Root>
|
||||
aria-label="Add attachments"
|
||||
>
|
||||
<PaperClipIcon class="w-5" />
|
||||
</Menu.Trigger>
|
||||
<Menu.Positioner>
|
||||
<Menu.Content class="p-3 gap-2 focus:outline-none">
|
||||
<Menu.Item
|
||||
value="document"
|
||||
asChild={(props) => (
|
||||
<label
|
||||
{...props()}
|
||||
for="document-upload"
|
||||
class="p-2 filter hover:brightness-95 flex gap-3 items-center"
|
||||
>
|
||||
<FileIcon class="w-4" /> Document
|
||||
</label>
|
||||
)}
|
||||
/>
|
||||
<Menu.Item
|
||||
value="photos"
|
||||
asChild={(props) => (
|
||||
<label
|
||||
{...props()}
|
||||
for="photos-upload"
|
||||
class="p-2 filter hover:brightness-95 flex gap-3 items-center"
|
||||
>
|
||||
<PictureIcon class="w-4" /> Photos & videos
|
||||
</label>
|
||||
)}
|
||||
/>
|
||||
</Menu.Content>
|
||||
</Menu.Positioner>
|
||||
</Menu.Root>
|
||||
</Match>
|
||||
</Switch>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -139,7 +139,10 @@ export const TextInput = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
class="typebot-input-form flex w-full gap-2 items-end max-w-[350px]"
|
||||
class={clsx(
|
||||
'typebot-input-form flex w-full gap-2 items-end',
|
||||
props.block.options?.isLong ? 'max-w-full' : 'max-w-[350px]'
|
||||
)}
|
||||
onKeyDown={submitWhenEnter}
|
||||
onDrop={handleDropFile}
|
||||
onDragOver={handleDragOver}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { guessApiHost } from '@/utils/guessApiHost'
|
||||
import { isNotEmpty } from '@typebot.io/lib'
|
||||
import { ContinueChatResponse } from '@typebot.io/schemas'
|
||||
import { ContinueChatResponse, Message } from '@typebot.io/schemas'
|
||||
import ky from 'ky'
|
||||
|
||||
export const continueChatQuery = async ({
|
||||
@ -9,7 +9,7 @@ export const continueChatQuery = async ({
|
||||
sessionId,
|
||||
}: {
|
||||
apiHost?: string
|
||||
message: string | undefined
|
||||
message?: Message
|
||||
sessionId: string
|
||||
}) => {
|
||||
try {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/nextjs",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "Convenient library to display typebots on your Next.js website",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/react",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "Convenient library to display typebots on your React app",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
Reference in New Issue
Block a user