diff --git a/example/chat_demo/widget_demo.html b/example/chat_demo/widget_demo.html index 34c262b3782..bec2e26acb6 100644 --- a/example/chat_demo/widget_demo.html +++ b/example/chat_demo/widget_demo.html @@ -122,6 +122,8 @@

🔧 Implementation

style="position:fixed;bottom:0;right:0;width:100px;height:100px;border:none;background:transparent;z-index:9999;opacity:0;transition:opacity 0.2s ease" frameborder="0" allow="microphone;camera"> diff --git a/web/src/components/embed-dialog/index.tsx b/web/src/components/embed-dialog/index.tsx index dbb45df2471..84b19ef12f8 100644 --- a/web/src/components/embed-dialog/index.tsx +++ b/web/src/components/embed-dialog/index.tsx @@ -236,7 +236,7 @@ function EmbedDialog({ return src.toString(); }, [beta, from, token, values]); - const text = useMemo(() => { + const generateEmbedCode = useCallback(() => { const iframeSrc = generateIframeSrc(); const { embedType } = values; @@ -248,7 +248,9 @@ function EmbedDialog({ allow="microphone;camera" > `; @@ -274,10 +280,32 @@ window.addEventListener('message',e=>{ } }, [generateIframeSrc, values]); + const text = useMemo(() => generateEmbedCode(), [generateEmbedCode]); + const handleOpenInNewTab = useCallback(() => { - const iframeSrc = generateIframeSrc(); - window.open(iframeSrc, '_blank'); - }, [generateIframeSrc]); + if (values.embedType === 'widget') { + const html = ` + + + + + RAGFlow Chat Widget Preview + + +${generateEmbedCode()} + +`; + + const blob = new Blob([html], { type: 'text/html' }); + const previewUrl = URL.createObjectURL(blob); + + window.open(previewUrl, '_blank', 'noopener,noreferrer'); + window.setTimeout(() => URL.revokeObjectURL(previewUrl), 60_000); + return; + } + + window.open(generateIframeSrc(), '_blank', 'noopener,noreferrer'); + }, [generateEmbedCode, generateIframeSrc, values.embedType]); const handleSaveWidgetSettings = useCallback(async () => { if (!onSaveWidgetSettings) { diff --git a/web/src/components/floating-chat-widget-markdown.tsx b/web/src/components/floating-chat-widget-markdown.tsx index 51912d72afb..078d0650240 100644 --- a/web/src/components/floating-chat-widget-markdown.tsx +++ b/web/src/components/floating-chat-widget-markdown.tsx @@ -10,7 +10,6 @@ import { currentReg, parseCitationIndex, preprocessLaTeX, - replaceRetrievingToSection, replaceTextByOldReg, replaceThinkToSection, showImage, @@ -36,7 +35,8 @@ import { } from 'react-syntax-highlighter/dist/esm/styles/prism'; import rehypeKatex from 'rehype-katex'; import rehypeRaw from 'rehype-raw'; -import { MarkdownRemarkPlugins } from '@/constants/markdown-remark-plugins'; +import remarkGfm from 'remark-gfm'; +import remarkMath from 'remark-math'; import { visitParents } from 'unist-util-visit-parents'; import styles from './floating-chat-widget-markdown.module.less'; import { useIsDarkTheme } from './theme-provider'; @@ -47,6 +47,18 @@ import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; const getChunkIndex = (match: string) => parseCitationIndex(match.replace(/\[|\]/g, '')); +const emitChatLinkClick = (url: string) => { + const target = window.self !== window.top ? window.parent : window; + + target.postMessage( + { + type: 'CHAT_LINK_CLICK', + url, + }, + '*', + ); +}; + const FloatingChatWidgetMarkdown = ({ reference, clickDocumentButton, @@ -66,7 +78,7 @@ const FloatingChatWidgetMarkdown = ({ const contentWithCursor = useMemo(() => { const text = content === '' ? t('chat.searching') : content; const nextText = replaceTextByOldReg(text); - return pipe(replaceThinkToSection, replaceRetrievingToSection, preprocessLaTeX)(nextText); + return pipe(replaceThinkToSection, preprocessLaTeX)(nextText); }, [content, t]); useEffect(() => { @@ -291,15 +303,32 @@ const FloatingChatWidgetMarkdown = ({
{ - const { children, node, ...rest } = props; - void node; - return

{children}

; - }, + p: ({ children, ...props }: any) =>

{children}

, + a: ({ href, onClick, children, ...props }: any) => ( + { + onClick?.(event); + + const clickedUrl = + event.currentTarget.href || + href || + event.currentTarget.getAttribute('href') || + ''; + + if (clickedUrl) { + emitChatLinkClick(clickedUrl); + } + }} + > + {children} + + ), 'custom-typography': ({ children }: { children: string }) => renderReference(children), code(props: any) {