cc3ac9a43d
Phase 1: Backend plugin kommunikation (13 files, 10 tables, REST API, WebSocket, RBAC, DMS Bridge, Participant Registry, Mini-App Registry, Search Provider) Phase 2: AI plugins as participants (ai_assistant + ai_proactive dock as participants, heartbeat job) Phase 3: system_notif plugin (system events → chat messages, pinned System room) Phase 4: Frontend MessageSidebar (replaces AISidebar, same design, comm API client, WebSocket hook, commStore) Phase 5: Rich Content Block Renderer (11 components: Markdown, HTML, Image, Audio, Video, File, ActionCard, ContactCard, MiniApp, BlockRenderer) BasePlugin: added services property + _container in on_activate
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import React from 'react';
|
|
import ReactMarkdown from 'react-markdown';
|
|
import type { MessageBlock } from '@/store/commStore';
|
|
|
|
interface MarkdownBlockProps {
|
|
block: MessageBlock;
|
|
}
|
|
|
|
const MarkdownBlock: React.FC<MarkdownBlockProps> = ({ block }) => {
|
|
const markdown: string = block.block_data.markdown || block.block_data.content || '';
|
|
|
|
if (!markdown) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="prose prose-sm max-w-none text-inherit">
|
|
<ReactMarkdown
|
|
components={{
|
|
p: ({ children }) => <p className="mb-1 last:mb-0">{children}</p>,
|
|
ul: ({ children }) => <ul className="list-disc pl-4 mb-1">{children}</ul>,
|
|
ol: ({ children }) => <ol className="list-decimal pl-4 mb-1">{children}</ol>,
|
|
code: ({ children, className }) => {
|
|
const isInline = !className;
|
|
if (isInline) {
|
|
return (
|
|
<code className="px-1 py-0.5 rounded bg-black/10 text-xs font-mono">
|
|
{children}
|
|
</code>
|
|
);
|
|
}
|
|
return (
|
|
<pre className="p-2 rounded bg-black/10 overflow-x-auto">
|
|
<code className="text-xs font-mono">{children}</code>
|
|
</pre>
|
|
);
|
|
},
|
|
h1: ({ children }) => <h1 className="text-base font-bold mb-1">{children}</h1>,
|
|
h2: ({ children }) => <h2 className="text-sm font-bold mb-1">{children}</h2>,
|
|
h3: ({ children }) => <h3 className="text-sm font-semibold mb-1">{children}</h3>,
|
|
a: ({ children, href }) => (
|
|
<a href={href} target="_blank" rel="noopener noreferrer" className="underline">
|
|
{children}
|
|
</a>
|
|
),
|
|
blockquote: ({ children }) => (
|
|
<blockquote className="border-l-2 border-current/30 pl-2 italic opacity-80">
|
|
{children}
|
|
</blockquote>
|
|
),
|
|
}}
|
|
>
|
|
{markdown}
|
|
</ReactMarkdown>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MarkdownBlock;
|