import { memo, useMemo, useCallback, type MouseEvent } from 'react' import Markdown, { defaultUrlTransform } from 'react-markdown' import remarkGfm from 'remark-gfm' import rehypeHighlight from 'rehype-highlight' import { preprocessWikilinks, WIKILINK_SCHEME } from '../utils/chatWikilinks' const REMARK_PLUGINS = [remarkGfm] const REHYPE_PLUGINS = [rehypeHighlight] function wikilinkUrlTransform(url: string): string { if (url.startsWith(WIKILINK_SCHEME)) return url return defaultUrlTransform(url) } interface MarkdownContentProps { content: string onWikilinkClick?: (target: string) => void } export const MarkdownContent = memo(function MarkdownContent({ content, onWikilinkClick }: MarkdownContentProps) { const processedContent = useMemo( () => onWikilinkClick ? preprocessWikilinks(content) : content, [content, onWikilinkClick], ) const handleClick = useCallback((e: MouseEvent) => { const el = (e.target as HTMLElement).closest('[data-wikilink-target]') if (el) { e.preventDefault() onWikilinkClick?.(el.dataset.wikilinkTarget!) } }, [onWikilinkClick]) const components = useMemo(() => { if (!onWikilinkClick) return undefined return { a: ({ href, children }: { href?: string; children?: React.ReactNode }) => { if (href?.startsWith(WIKILINK_SCHEME)) { const target = decodeURIComponent(href.slice(WIKILINK_SCHEME.length)) return ( {children} ) } return {children} }, } }, [onWikilinkClick]) return (
{processedContent}
) })