mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-29 06:28:23 +02:00
- Add drag-and-drop overlay with brand color visual feedback - Images: inline rendering with blob preview → real URL replacement - Non-images: file card node (spinner → filename card with download button) - File card markdown roundtrip: [name](url) ↔ fileCard node via preprocessor - Fix: double-upload on drag (check defaultPrevented) - Fix: drop overlay not clearing (global drop/dragend listener) - Fix: drop replacing existing content (use posAtCoords for drop position) - Fix: multi-file drop position drift (only first file uses drop pos) - Fix: same-name file upload conflict (use uploadId instead of filename) - Fix: image upload descendants traversal not stopping (add found flag) - Fix: parent comment edit missing onUploadFile prop - Remove: attachment section UI (files live in markdown) - Remove: file type whitelist (accept all types like Linear) - Remove: console.log perf logs from production code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
import { preprocessLinks } from "@/components/markdown/linkify";
|
|
import { preprocessMentionShortcodes } from "@/components/markdown/mentions";
|
|
import { isFileCardUrl } from "../extensions/file-card";
|
|
|
|
/**
|
|
* Preprocess a markdown string before loading into Tiptap via contentType: 'markdown'.
|
|
*
|
|
* This is the ONLY transform applied before @tiptap/markdown parses the content.
|
|
* It does NOT convert to HTML — that was the old markdownToHtml.ts pipeline which
|
|
* was deleted in the April 2026 refactor.
|
|
*
|
|
* Three string→string transforms on raw Markdown:
|
|
* 1. Legacy mention shortcodes [@ id="..." label="..."] → [@Label](mention://member/id)
|
|
* (old serialization format in database, migrated on read)
|
|
* 2. Raw URLs → markdown links via linkify-it (so they render as clickable Link nodes)
|
|
* 3. CDN file links on their own line → HTML div for fileCard node parsing
|
|
*/
|
|
export function preprocessMarkdown(markdown: string): string {
|
|
if (!markdown) return "";
|
|
const step1 = preprocessMentionShortcodes(markdown);
|
|
const step2 = preprocessLinks(step1);
|
|
const step3 = preprocessFileCards(step2);
|
|
return step3;
|
|
}
|
|
|
|
/**
|
|
* Convert standalone `[name](cdnUrl)` lines into HTML that Tiptap's fileCard
|
|
* parseHTML can recognise. Only matches non-image CDN URLs on their own line.
|
|
*
|
|
* Input: `[report.pdf](https://multica-static.copilothub.ai/xxx.pdf)`
|
|
* Output: `<div data-type="fileCard" data-href="url" data-filename="report.pdf"></div>`
|
|
*/
|
|
const FILE_LINK_LINE = /^\[([^\]]+)\]\((https?:\/\/[^)]+)\)$/;
|
|
|
|
function preprocessFileCards(markdown: string): string {
|
|
return markdown
|
|
.split("\n")
|
|
.map((line) => {
|
|
const trimmed = line.trim();
|
|
const match = trimmed.match(FILE_LINK_LINE);
|
|
if (!match) return line;
|
|
const filename = match[1]!;
|
|
const url = match[2]!;
|
|
if (!isFileCardUrl(url)) return line;
|
|
return `<div data-type="fileCard" data-href="${url}" data-filename="${filename}"></div>`;
|
|
})
|
|
.join("\n");
|
|
}
|