56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useMemo, useRef } from "react"
|
|
import type { AiChatContext } from "@/lib/ai/chat-context"
|
|
import { buildEmbedSearchParams } from "@/lib/ai/chat-context"
|
|
import { useTheme } from "next-themes"
|
|
|
|
type AiChatIframeProps = {
|
|
publicPath?: string
|
|
context: AiChatContext
|
|
className?: string
|
|
}
|
|
|
|
export function AiChatIframe({ publicPath = "/ai", context, className }: AiChatIframeProps) {
|
|
const iframeRef = useRef<HTMLIFrameElement>(null)
|
|
const { resolvedTheme } = useTheme()
|
|
const src = useMemo(() => {
|
|
const base = publicPath.replace(/\/$/, "")
|
|
const qs = buildEmbedSearchParams(context)
|
|
return qs ? `${base}/?${qs}` : `${base}/`
|
|
}, [publicPath, context])
|
|
|
|
useEffect(() => {
|
|
const iframe = iframeRef.current
|
|
if (!iframe?.contentWindow) return
|
|
iframe.contentWindow.postMessage(
|
|
{ type: "ULTI_THEME", theme: resolvedTheme === "dark" ? "dark" : "light" },
|
|
window.location.origin
|
|
)
|
|
}, [resolvedTheme])
|
|
|
|
useEffect(() => {
|
|
const iframe = iframeRef.current
|
|
if (!iframe?.contentWindow) return
|
|
iframe.contentWindow.postMessage(
|
|
{
|
|
type: "ULTI_CONTEXT_UPDATE",
|
|
context,
|
|
systemPrompt: context.systemPromptExtra,
|
|
},
|
|
window.location.origin
|
|
)
|
|
}, [context])
|
|
|
|
return (
|
|
<iframe
|
|
ref={iframeRef}
|
|
title="UltiAI"
|
|
src={src}
|
|
className={className}
|
|
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-downloads"
|
|
allow="clipboard-read; clipboard-write"
|
|
/>
|
|
)
|
|
}
|