import { Fragment } from "react"; // Render a small, safe subset of Discord Markdown; React escapes raw HTML. function inline(text: string) { return text .split(/(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\(https?:\/\/[^\s)]+\))/g) .map((part, i) => { if (part.startsWith("**") && part.endsWith("**")) return {part.slice(2, -2)}; if (part.startsWith("`") && part.endsWith("`")) return {part.slice(1, -1)}; const link = /^\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)$/.exec(part); if (link) return ( {link[1]} ); return {part}; }); } export function ReleaseNotes({ body }: { body: string }) { const blocks: { list: boolean; lines: string[] }[] = []; let current: (typeof blocks)[number] | undefined; for (const line of body.split(/\r?\n/)) { if (!line.trim()) { current = undefined; continue; } const bullet = /^\s*[-*]\s+(.+)$/.exec(line); if (!bullet && current?.list && /^\s{2,}\S/.test(line)) { current.lines[current.lines.length - 1] += ` ${line.trim()}`; continue; } const list = !!bullet; if (!current || current.list !== list) { current = { list, lines: [] }; blocks.push(current); } current.lines.push(bullet ? bullet[1] : line); } return blocks.map(({ list, lines }, i) => { if (list) return ( ); return (

{lines.map((line, j) => ( {j > 0 &&
} {inline(line)}
))}

); }); }