mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 21:33:41 +02:00
* feat(editor): inline HTML attachment preview + ```html block render (MUL-2345) * attachment-preview-modal: switch HTML iframe sandbox from "" to "allow-scripts" so JS-driven chart libraries render. The opaque-origin iframe still cannot touch cookies, localStorage, parent state, or top-nav — only scripts run. * New shared AttachmentCard wired into the three attachment surfaces (file-card NodeView, ReadonlyContent file-card branch, comment-card standalone AttachmentList). HTML attachments now render inline via a sandboxed iframe pulled through the existing /content proxy; other kinds keep the original chrome behavior. * New HtmlBlockPreview for fenced ```html blocks in ReadonlyContent — default preview iframe, source/Copy toggle. Two-layer code+pre unwrap mirrors the Mermaid pattern; unwrap now matches on language-* class because react-markdown invokes pre before the code renderer runs. * CodeBlockView (Tiptap NodeView) renders an iframe preview for language=html with a CSS-hidden toggle to the editable source — the <NodeViewContent as="code"/> mount must remain in the tree. * Shared use-attachment-html-text hook keeps inline and modal HTML rendering on the same React Query cache. * Vitest coverage: allow-scripts assertion, attachment-card kind branches, readonly HTML iframe + Mermaid unwrap regression, NodeView editable + preview/source toggle. No backend changes; server-side text/plain + nosniff defense kept. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai> * fix(editor): tighten attachment preview and pre unwrap gates (MUL-2345) Addresses Reviewer REQUEST CHANGES on PR #2790: 1. URL-only text/html attachment cards no longer surface a dead Eye button. `AttachmentCard` previously allowed preview when `previewableFromUrl=true` regardless of kind, but the modal's `tryOpen` rejects URL-only text kinds because the `/content` proxy is ID-keyed. Drop the `previewableFromUrl` prop and gate the no-attachmentId path strictly to URL-previewable media kinds (pdf/video/audio). 2. Readonly `pre` unwrap now uses exact class-token matching. The previous `className.includes("language-html")` check also fired on `language-htmlbars`, silently stripping its `<pre>` wrapper. Use `/(^|\s)language-(html|mermaid)(\s|$)/` so only the exact tokens unwrap. Regression tests: - `report.html + no attachmentId` asserts no Preview button. - `pdf URL-only` asserts Preview button still appears. - `htmlbars` / `mermaidx` fences keep their `<pre><code>` wrapper. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* Shared React Query for fetching attachment text bodies via the
|
|
* `/api/attachments/{id}/content` proxy.
|
|
*
|
|
* Same retry / staleTime / gcTime policy as AttachmentPreviewModal's local
|
|
* TextBackedPreview, lifted out so the modal and the inline `AttachmentCard`
|
|
* (file-card NodeView / readonly file-card / standalone AttachmentList) hit
|
|
* the same cache key — opening the modal after the inline preview already
|
|
* loaded a body does not refetch.
|
|
*/
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { api } from "@multica/core/api";
|
|
|
|
export function useAttachmentHtmlText(attachmentId: string | null | undefined) {
|
|
return useQuery({
|
|
queryKey: ["attachment-content", attachmentId ?? ""] as const,
|
|
queryFn: () => api.getAttachmentTextContent(attachmentId as string),
|
|
enabled: !!attachmentId,
|
|
// 413 / 415 won't become 200 on retry; a transport error is easier to
|
|
// recover from by re-opening than waiting on background retries with
|
|
// no UI affordance.
|
|
retry: false,
|
|
staleTime: 5 * 60_000,
|
|
gcTime: 30 * 60_000,
|
|
});
|
|
}
|