2
0

🐛 (attachments) Fix attachments on mobile and fix long text…

Closes #1611, closes #1610
This commit is contained in:
Baptiste Arnaud
2024-06-27 09:20:42 +02:00
parent 8ec0fbdebf
commit 898ed529b0
8 changed files with 83 additions and 74 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/js", "name": "@typebot.io/js",
"version": "0.3.2", "version": "0.3.3",
"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",

View File

@@ -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 { isMobile } from '@/utils/isMobileSignal'
import { ContinueChatResponse, Settings, Theme } from '@typebot.io/schemas' import { ContinueChatResponse, Settings, Theme } from '@typebot.io/schemas'
import { createSignal, For, onMount, Show } from 'solid-js' import { createSignal, For, onMount, Show } from 'solid-js'
@@ -23,7 +23,7 @@ type Props = Pick<ContinueChatResponse, 'messages' | 'input'> & {
isTransitionDisabled?: boolean isTransitionDisabled?: boolean
onNewBubbleDisplayed: (blockId: string) => Promise<void> onNewBubbleDisplayed: (blockId: string) => Promise<void>
onScrollToBottom: (ref?: HTMLDivElement, offset?: number) => void onScrollToBottom: (ref?: HTMLDivElement, offset?: number) => void
onSubmit: (input?: string) => void onSubmit: (answer?: string, attachments?: Answer['attachments']) => void
onSkip: () => void onSkip: () => void
onAllBubblesDisplayed: () => void onAllBubblesDisplayed: () => void
} }

View File

@@ -15,7 +15,12 @@ import {
} from 'solid-js' } from 'solid-js'
import { continueChatQuery } from '@/queries/continueChatQuery' import { continueChatQuery } from '@/queries/continueChatQuery'
import { ChatChunk } from './ChatChunk' 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 { isNotDefined } from '@typebot.io/lib'
import { executeClientSideAction } from '@/utils/executeClientSideActions' import { executeClientSideAction } from '@/utils/executeClientSideActions'
import { LoadingChunk } from './LoadingChunk' 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) setHasError(false)
const currentInputBlock = [...chatChunks()].pop()?.input const currentInputBlock = [...chatChunks()].pop()?.input
if (currentInputBlock?.id && props.onAnswer && message) if (currentInputBlock?.id && props.onAnswer && message)
@@ -149,7 +157,13 @@ export const ConversationContainer = (props: Props) => {
const { data, error } = await continueChatQuery({ const { data, error } = await continueChatQuery({
apiHost: props.context.apiHost, apiHost: props.context.apiHost,
sessionId: props.initialChatReply.sessionId, sessionId: props.initialChatReply.sessionId,
message, message: message
? {
type: 'text',
text: message,
attachedFileUrls: attachments?.map((attachment) => attachment.url),
}
: undefined,
}) })
clearTimeout(longRequest) clearTimeout(longRequest)
setIsSending(false) setIsSending(false)

View File

@@ -1,6 +1,5 @@
import { Show } from 'solid-js' import { Match, Switch } from 'solid-js'
import { Menu } from '@ark-ui/solid' import { Menu } from '@ark-ui/solid'
import { CameraIcon } from './icons/CameraIcon'
import { FileIcon } from './icons/FileIcon' import { FileIcon } from './icons/FileIcon'
import { PictureIcon } from './icons/PictureIcon' import { PictureIcon } from './icons/PictureIcon'
import { isMobile } from '@/utils/isMobileSignal' import { isMobile } from '@/utils/isMobileSignal'
@@ -35,69 +34,62 @@ export const TextInputAddFileButton = (props: Props) => {
props.onNewFiles(e.currentTarget.files) 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> <Switch>
<Menu.Trigger <Match when={isMobile()}>
class={clsx( <label
'filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none', aria-label="Add attachments"
props.class for="document-upload"
)} class={clsx(
aria-label="Add attachments" '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" /> )}
</Menu.Trigger> >
<Menu.Positioner> <PaperClipIcon class="w-5" />
<Menu.Content class="p-3 gap-2 focus:outline-none"> </label>
<Menu.Item </Match>
value="document" <Match when={true}>
asChild={(props) => ( <Menu.Root>
<label <Menu.Trigger
{...props()} class={clsx(
for="document-upload" 'filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none',
class="p-2 filter hover:brightness-95 flex gap-3 items-center" props.class
>
<FileIcon class="w-4" /> Document
</label>
)} )}
/> aria-label="Add attachments"
<Menu.Item >
value="photos" <PaperClipIcon class="w-5" />
asChild={(props) => ( </Menu.Trigger>
<label <Menu.Positioner>
{...props()} <Menu.Content class="p-3 gap-2 focus:outline-none">
for="photos-upload" <Menu.Item
class="p-2 filter hover:brightness-95 flex gap-3 items-center" value="document"
> asChild={(props) => (
<PictureIcon class="w-4" /> Photos & videos <label
</label> {...props()}
)} for="document-upload"
/> class="p-2 filter hover:brightness-95 flex gap-3 items-center"
<Show when={isMobile()}> >
<Menu.Item <FileIcon class="w-4" /> Document
value="camera" </label>
class="p-2 filter hover:brightness-95 flex gap-3 items-center" )}
> />
<CameraIcon class="w-4" /> <Menu.Item
Camera value="photos"
</Menu.Item> asChild={(props) => (
</Show> <label
</Menu.Content> {...props()}
</Menu.Positioner> for="photos-upload"
</Menu.Root> 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>
</> </>
) )
} }

View File

@@ -139,7 +139,10 @@ export const TextInput = (props: Props) => {
return ( return (
<div <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} onKeyDown={submitWhenEnter}
onDrop={handleDropFile} onDrop={handleDropFile}
onDragOver={handleDragOver} onDragOver={handleDragOver}

View File

@@ -1,6 +1,6 @@
import { guessApiHost } from '@/utils/guessApiHost' import { guessApiHost } from '@/utils/guessApiHost'
import { isNotEmpty } from '@typebot.io/lib' import { isNotEmpty } from '@typebot.io/lib'
import { ContinueChatResponse } from '@typebot.io/schemas' import { ContinueChatResponse, Message } from '@typebot.io/schemas'
import ky from 'ky' import ky from 'ky'
export const continueChatQuery = async ({ export const continueChatQuery = async ({
@@ -9,7 +9,7 @@ export const continueChatQuery = async ({
sessionId, sessionId,
}: { }: {
apiHost?: string apiHost?: string
message: string | undefined message?: Message
sessionId: string sessionId: string
}) => { }) => {
try { try {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/nextjs", "name": "@typebot.io/nextjs",
"version": "0.3.2", "version": "0.3.3",
"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",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@typebot.io/react", "name": "@typebot.io/react",
"version": "0.3.2", "version": "0.3.3",
"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",