diff --git a/chat_demo/index.html b/chat_demo/index.html new file mode 100644 index 00000000..114b1368 --- /dev/null +++ b/chat_demo/index.html @@ -0,0 +1,19 @@ + + \ No newline at end of file diff --git a/chat_demo/widget_demo.html b/chat_demo/widget_demo.html new file mode 100644 index 00000000..34c262b3 --- /dev/null +++ b/chat_demo/widget_demo.html @@ -0,0 +1,154 @@ + + + + + + Floating Chat Widget Demo + + + +
+

🚀 Floating Chat Widget Demo

+ +

+ Welcome to our demo page! This page simulates a real website with content. + Look for the floating chat button in the bottom-right corner - just like Intercom! +

+ +
+

🎯 Widget Features

+ +
+ +

+ The chat widget is completely separate from your website's content and won't + interfere with your existing layout or functionality. It's designed to be + lightweight and performant. +

+ +

+ Try scrolling this page - notice how the chat button stays in position. + Click it to start a conversation with our AI assistant! +

+ +
+

🔧 Implementation

+ +
+ +

+ This is just placeholder content to demonstrate how the widget integrates + seamlessly with your existing website content. The widget floats above + everything else without disrupting your user experience. +

+ +

+ 🎉 Ready to add this to your website? Get your embed code from the admin panel! +

+
+ + + + + \ No newline at end of file diff --git a/web/src/components/embed-dialog/index.tsx b/web/src/components/embed-dialog/index.tsx index 9aa38956..34197ada 100644 --- a/web/src/components/embed-dialog/index.tsx +++ b/web/src/components/embed-dialog/index.tsx @@ -15,6 +15,8 @@ import { FormLabel, FormMessage, } from '@/components/ui/form'; +import { Label } from '@/components/ui/label'; +import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { Switch } from '@/components/ui/switch'; import { SharedFrom } from '@/constants/chat'; import { @@ -32,6 +34,8 @@ import { z } from 'zod'; const FormSchema = z.object({ visibleAvatar: z.boolean(), locale: z.string(), + embedType: z.enum(['fullscreen', 'widget']), + enableStreaming: z.boolean(), }); type IProps = IModalProps & { @@ -55,6 +59,8 @@ function EmbedDialog({ defaultValues: { visibleAvatar: false, locale: '', + embedType: 'fullscreen' as const, + enableStreaming: false, }, }); @@ -68,20 +74,60 @@ function EmbedDialog({ }, []); const generateIframeSrc = useCallback(() => { - const { visibleAvatar, locale } = values; - let src = `${location.origin}${from === SharedFrom.Agent ? Routes.AgentShare : Routes.ChatShare}?shared_id=${token}&from=${from}&auth=${beta}`; + const { visibleAvatar, locale, embedType, enableStreaming } = values; + const baseRoute = + embedType === 'widget' + ? Routes.ChatWidget + : from === SharedFrom.Agent + ? Routes.AgentShare + : Routes.ChatShare; + let src = `${location.origin}${baseRoute}?shared_id=${token}&from=${from}&auth=${beta}`; if (visibleAvatar) { src += '&visible_avatar=1'; } if (locale) { src += `&locale=${locale}`; } + if (enableStreaming) { + src += '&streaming=true'; + } return src; }, [beta, from, token, values]); const text = useMemo(() => { const iframeSrc = generateIframeSrc(); - return ` + const { embedType } = values; + + if (embedType === 'widget') { + const { enableStreaming } = values; + const streamingParam = enableStreaming + ? '&streaming=true' + : '&streaming=false'; + return ` + ~~~ html + + +~~~ + `; + } else { + return ` ~~~ html