'use client'; import { X, Download } from 'lucide-react'; interface FilePreviewProps { cid: string; content: string | null; loading: boolean; onClose: () => void; filename?: string; } function detectFileType(filename: string | undefined): 'image' | 'markdown' | 'json' | 'text' | 'other' { const ext = filename?.split('.').pop()?.toLowerCase() ?? ''; if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(ext)) return 'image'; if (ext === 'md') return 'markdown'; if (ext === 'json') return 'json'; if (['txt', 'js', 'ts', 'py', 'css', 'html', 'sh', 'yaml', 'yml', 'toml', 'xml'].includes(ext)) return 'text'; return 'other'; } function renderMarkdown(text: string): string { return text .replace(/^### (.+)$/gm, '
$1')
.replace(/\n\n/g, '') .replace(/^(?!<[hop])/gm, (match) => match ? match : ''); } function renderJson(text: string): string { try { const parsed = JSON.parse(text); const syntax = JSON.stringify(parsed, null, 2); return syntax; } catch { return text; } } function JsonDisplay({ text }: { text: string }) { let parsed: unknown; try { parsed = JSON.parse(text); } catch { return
{text};
}
const formatted = JSON.stringify(parsed, null, 2);
const colored = formatted.replace(
/("(?:\\.|[^"\\])*")\s*:/g,
'$1:',
).replace(
/:\s*("(?:\\.|[^"\\])*")/g,
': $1',
).replace(
/:\s*(true|false)/g,
': $1',
).replace(
/:\s*(\d+\.?\d*)/g,
': $1',
).replace(
/:\s*(null)/g,
': $1',
);
return (
);
}
export default function FilePreview({ cid, content, loading, onClose, filename }: FilePreviewProps) {
const fileType = detectFileType(filename);
return (
{content}
) : (
Preview not available for this file type