From 61b5c6dc3908e33c0a58aa8b9e1551326f1a0c13 Mon Sep 17 00:00:00 2001 From: Jaime Idolpx Date: Tue, 9 Jun 2026 03:34:07 -0400 Subject: [PATCH] feat(MediaManager): refine file extension sets and enhance image URL handling for SVG support --- src/app/components/MediaManager.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/app/components/MediaManager.tsx b/src/app/components/MediaManager.tsx index 3b696e8..2fa02e6 100644 --- a/src/app/components/MediaManager.tsx +++ b/src/app/components/MediaManager.tsx @@ -80,9 +80,10 @@ type ViewMode = 'text' | 'markdown' | 'json' | 'xml' | 'hex' | 'image' | 'config // ─── Extension sets ────────────────────────────────────────────────────────── -const TEXT_EXTS = new Set(['txt', 'cfg', 'ini', 'bas', 'asm', 'seq', 'rel', 'prg', 'log', 'csv', 's', 'lst']); +const TEXT_EXTS = new Set(['txt', 'cfg', 'ini', 'seq', 'log', 'csv', 'lst']); +const CODE_EXTS = new Set(['asm', 'bas', 's', 'js', 'css']); const MD_EXTS = new Set(['md', 'markdown']); -const JSON_EXTS = new Set(['json', 'manifest']); +const JSON_EXTS = new Set(['json', 'webmanifest']); const XML_EXTS = new Set(['xml', 'html', 'htm', 'rss', 'atom', 'xsl']); const IMAGE_EXTS = new Set(['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg', 'ico']); const AUDIO_EXTS = new Set(['sid', 'psid', 'mus', 'vgm']); @@ -120,7 +121,7 @@ function availableViewers(entry: EntryInfo): ViewMode[] { } const VIEWER_LABEL: Record = { - text: 'Text', markdown: 'Markdown', json: 'JSON', xml: 'XML', hex: 'Hex', image: 'Image', config: 'Config', + text: 'Text', markdown: 'Markdown', json: 'JSON', xml: 'HTML/XML', hex: 'Hex', image: 'Image', config: 'Config', }; // ─── Viewer components ─────────────────────────────────────────────────────── @@ -613,7 +614,9 @@ export default function MediaManager({ initialPath = '/', rootPath, title, confi const bytes = await _getEntryBytes(entry); if (targetMode === 'image') { const ab = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer; - setViewImgUrl(URL.createObjectURL(new Blob([ab]))); + const imgExt = entry.name.split('.').pop()?.toLowerCase(); + const imgMime = imgExt === 'svg' ? 'image/svg+xml' : undefined; + setViewImgUrl(URL.createObjectURL(new Blob([ab], imgMime ? { type: imgMime } : undefined))); } else if (targetMode === 'hex') { setViewHexData(bytes); } else { @@ -636,7 +639,9 @@ export default function MediaManager({ initialPath = '/', rootPath, title, confi const bytes = await _getEntryBytes(viewEntry); if (mode === 'image') { const ab = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer; - setViewImgUrl(prev => { if (prev) URL.revokeObjectURL(prev); return URL.createObjectURL(new Blob([ab])); }); + const ext = viewEntry.name.split('.').pop()?.toLowerCase(); + const mime = ext === 'svg' ? 'image/svg+xml' : undefined; + setViewImgUrl(prev => { if (prev) URL.revokeObjectURL(prev); return URL.createObjectURL(new Blob([ab], mime ? { type: mime } : undefined)); }); } else if (mode === 'hex') { setViewHexData(bytes); } else {