From 9f1119a72f9d33d4f81658d5ab29b999a9afd36e Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:51:35 +0200 Subject: [PATCH] Expand preview media support --- build-plugin.sh | 2 +- packages/u-navigator-2026.06.23.r030.tgz | Bin 23722 -> 0 bytes packages/u-navigator-2026.06.23.r031.tgz | Bin 0 -> 25826 bytes .../plugins/u-navigator/api/preview.php | 106 ++++++++++++--- server/public/app.js | 127 +++++++++++++++++- server/public/styles.css | 76 +++++++++++ u-navigator.plg | 4 +- 7 files changed, 292 insertions(+), 23 deletions(-) delete mode 100644 packages/u-navigator-2026.06.23.r030.tgz create mode 100644 packages/u-navigator-2026.06.23.r031.tgz diff --git a/build-plugin.sh b/build-plugin.sh index 2924131..60228e6 100755 --- a/build-plugin.sh +++ b/build-plugin.sh @@ -2,7 +2,7 @@ set -eu PLUGIN="u-navigator" -VERSION="2026.06.23.r030" +VERSION="2026.06.23.r031" PKG_DIR="packages" WORK_DIR=".plugin-build" PKG_NAME="${PLUGIN}-${VERSION}.tgz" diff --git a/packages/u-navigator-2026.06.23.r030.tgz b/packages/u-navigator-2026.06.23.r030.tgz deleted file mode 100644 index 5bbc173dabbb930d250c4aa6cfbf8acf2ad78d7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23722 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%0A)0s*)z9kuZLpY_Vy{&3kr;{j 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 UNAV_PREVIEW_MAX_BYTES) { - unav_error(413, 'Preview file is larger than 1 MB'); + +$mime = unav_preview_mime($extension, $type); +if (($_GET['raw'] ?? '') === '1') { + header('Content-Type: ' . $mime); + header('Content-Length: ' . $size); + header('X-Content-Type-Options: nosniff'); + readfile($resolved['path']); + exit; } -$content = file_get_contents($resolved['path']); -if ($content === false) { - unav_error(500, 'Could not read file'); -} -if (strpos($content, "\0") !== false) { - unav_error(415, 'Preview is not available for binary files'); -} - -unav_json([ +$payload = [ 'path' => $resolved['path'], - 'name' => basename($resolved['path']), + 'name' => $name, 'size' => $size, 'extension' => $extension, - 'content' => $content, -]); + 'type' => $type, + 'mime' => $mime, + 'rawUrl' => 'preview.php?raw=1&path=' . rawurlencode($resolved['path']), +]; + +if (in_array($type, ['text', 'markdown', 'csv'], true)) { + if ($size > UNAV_TEXT_PREVIEW_MAX_BYTES) { + unav_error(413, 'Preview file is larger than 1 MB'); + } + $content = file_get_contents($resolved['path']); + if ($content === false) { + unav_error(500, 'Could not read file'); + } + if (strpos($content, "\0") !== false) { + unav_error(415, 'Preview is not available for binary files'); + } + $payload['content'] = $content; +} + +unav_json($payload); + +function unav_preview_type(string $extension, string $name): ?string { + $base = strtolower($name); + if (in_array($base, ['dockerfile', 'makefile'], true)) { + return 'text'; + } + $text = ['txt', 'log', 'rd', 'rst', 'yaml', 'yml', 'json', 'xml', 'ini', 'cfg', 'conf', 'env', 'toml', 'sql', 'nfo', 'srt', 'sub', 'vtt', 'm3u', 'm3u8', 'pls', 'sh', 'bash', 'zsh', 'php', 'js', 'ts', 'tsx', 'jsx', 'css', 'html', 'py', 'go', 'rs', 'java', 'c', 'cpp', 'h', 'hpp', 'bat', 'ps1', 'properties', 'service', 'timer', 'mount', 'rules', 'cron', 'plg', 'page']; + if (in_array($extension, $text, true)) { + return 'text'; + } + if ($extension === 'md') { + return 'markdown'; + } + if (in_array($extension, ['csv', 'tsv'], true)) { + return 'csv'; + } + if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'], true)) { + return 'image'; + } + if ($extension === 'pdf') { + return 'pdf'; + } + if (in_array($extension, ['mp3', 'flac', 'm4a', 'ogg', 'wav'], true)) { + return 'audio'; + } + if (in_array($extension, ['mp4', 'mkv', 'webm', 'mov'], true)) { + return 'video'; + } + return null; +} + +function unav_preview_mime(string $extension, string $type): string { + $map = [ + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'webp' => 'image/webp', + 'svg' => 'image/svg+xml', + 'pdf' => 'application/pdf', + 'mp3' => 'audio/mpeg', + 'flac' => 'audio/flac', + 'm4a' => 'audio/mp4', + 'ogg' => 'audio/ogg', + 'wav' => 'audio/wav', + 'mp4' => 'video/mp4', + 'mkv' => 'video/x-matroska', + 'webm' => 'video/webm', + 'mov' => 'video/quicktime', + 'csv' => 'text/csv; charset=utf-8', + 'tsv' => 'text/tab-separated-values; charset=utf-8', + 'md' => 'text/markdown; charset=utf-8', + ]; + return $map[$extension] ?? ($type === 'text' ? 'text/plain; charset=utf-8' : 'application/octet-stream'); +} diff --git a/server/public/app.js b/server/public/app.js index 534beec..cde2149 100644 --- a/server/public/app.js +++ b/server/public/app.js @@ -40,7 +40,8 @@ const icons = { symlink: 'Link', other: 'Item' }; -const previewExtensions = new Set(['txt', 'log', 'md', 'rd', 'rst', 'yaml', 'yml', 'json', 'xml', 'csv', 'ini', 'cfg', 'conf', 'sh', 'php', 'js', 'css', 'html']); +const previewExtensions = new Set(['txt', 'log', 'md', 'rd', 'rst', 'yaml', 'yml', 'json', 'xml', 'csv', 'tsv', 'ini', 'cfg', 'conf', 'env', 'toml', 'sql', 'nfo', 'srt', 'sub', 'vtt', 'm3u', 'm3u8', 'pls', 'sh', 'bash', 'zsh', 'php', 'js', 'ts', 'tsx', 'jsx', 'css', 'html', 'py', 'go', 'rs', 'java', 'c', 'cpp', 'h', 'hpp', 'bat', 'ps1', 'properties', 'service', 'timer', 'mount', 'rules', 'cron', 'plg', 'page', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'pdf', 'mp3', 'flac', 'm4a', 'ogg', 'wav', 'mp4', 'mkv', 'webm', 'mov']); +const previewFilenames = new Set(['dockerfile', 'makefile']); document.querySelector('#newExplorerButton').addEventListener('click', () => openExplorer()); document.querySelector('#newPropertiesButton').addEventListener('click', () => openProperties()); @@ -429,10 +430,32 @@ function renderPreview(body, win) { ${escapeHtml(entry?.name || data.name || 'Vorschau')} ${escapeHtml(formatBytes(data.size || entry?.size || 0))} -
${escapeHtml(data.content || '')}
+ ${renderPreviewContent(data)} `; } +function renderPreviewContent(data) { + if (data.type === 'markdown') { + return `
${renderMarkdown(data.content || '')}
`; + } + if (data.type === 'csv') { + return renderCsvPreview(data.content || '', data.extension === 'tsv' ? '\t' : ','); + } + if (data.type === 'image') { + return `
${escapeAttr(data.name || 'Vorschau')}
`; + } + if (data.type === 'pdf') { + return ``; + } + if (data.type === 'audio') { + return `
`; + } + if (data.type === 'video') { + return `
`; + } + return `
${escapeHtml(data.content || '')}
`; +} + async function loadPreview(win, entry) { win.data.loading = true; win.data.error = null; @@ -442,6 +465,9 @@ async function loadPreview(win, entry) { win.data.entry = entry; win.data.name = result.name; win.data.size = result.size; + win.data.type = result.type; + win.data.extension = result.extension; + win.data.rawUrl = result.rawUrl; win.data.content = result.content; } catch (error) { win.data.error = error.message; @@ -451,6 +477,99 @@ async function loadPreview(win, entry) { } } +function renderMarkdown(content) { + const blocks = []; + let listItems = []; + const flushList = () => { + if (listItems.length) { + blocks.push(`
    ${listItems.map((item) => `
  • ${renderInlineMarkdown(item)}
  • `).join('')}
`); + listItems = []; + } + }; + + for (const line of String(content).split(/\r?\n/)) { + const heading = /^(#{1,6})\s+(.*)$/.exec(line); + if (heading) { + flushList(); + const level = heading[1].length; + blocks.push(`${renderInlineMarkdown(heading[2])}`); + continue; + } + const list = /^\s*[-*]\s+(.*)$/.exec(line); + if (list) { + listItems.push(list[1]); + continue; + } + flushList(); + if (!line.trim()) continue; + blocks.push(`

${renderInlineMarkdown(line)}

`); + } + flushList(); + return blocks.join(''); +} + +function renderInlineMarkdown(value) { + return escapeHtml(value) + .replace(/`([^`]+)`/g, '$1') + .replace(/\*\*([^*]+)\*\*/g, '$1') + .replace(/\*([^*]+)\*/g, '$1'); +} + +function renderCsvPreview(content, delimiter) { + const rows = parseDelimitedRows(content, delimiter).slice(0, 80); + if (!rows.length) { + return '

Keine Tabellenzeilen.

'; + } + return ` +
+ + + ${rows.map((row) => `${row.map((cell) => ``).join('')}`).join('')} + +
${escapeHtml(cell)}
+
+ `; +} + +function parseDelimitedRows(content, delimiter) { + const rows = []; + let row = []; + let cell = ''; + let quoted = false; + const text = String(content || ''); + for (let index = 0; index < text.length; index += 1) { + const char = text[index]; + if (char === '"') { + if (quoted && text[index + 1] === '"') { + cell += '"'; + index += 1; + } else { + quoted = !quoted; + } + continue; + } + if (!quoted && char === delimiter) { + row.push(cell); + cell = ''; + continue; + } + if (!quoted && (char === '\n' || char === '\r')) { + if (char === '\r' && text[index + 1] === '\n') index += 1; + row.push(cell); + rows.push(row); + row = []; + cell = ''; + continue; + } + cell += char; + } + if (cell || row.length) { + row.push(cell); + rows.push(row); + } + return rows; +} + function renderQueue(body) { body.innerHTML = queueMarkup(); bindQueueActions(body); @@ -1421,7 +1540,9 @@ function extensionOf(name) { } function isPreviewable(entry) { - return entry?.type === 'file' && previewExtensions.has(extensionOf(entry.name || entry.path)); + if (entry?.type !== 'file') return false; + const name = String(entry.name || entry.path || '').toLowerCase(); + return previewFilenames.has(name) || previewExtensions.has(extensionOf(name)); } function joinPath(parent, name) { diff --git a/server/public/styles.css b/server/public/styles.css index a871671..dc26a00 100644 --- a/server/public/styles.css +++ b/server/public/styles.css @@ -731,6 +731,82 @@ white-space: pre; } +.u-nav .preview-rendered, +.u-nav .preview-table-wrap, +.u-nav .preview-media, +.u-nav .preview-frame { + min-height: 0; +} + +.u-nav .preview-rendered { + background: var(--surface); + border: 1px solid var(--line); + border-radius: 6px; + overflow: auto; + padding: 12px; +} + +.u-nav .preview-rendered h1, +.u-nav .preview-rendered h2, +.u-nav .preview-rendered h3, +.u-nav .preview-rendered p, +.u-nav .preview-rendered ul { + margin-top: 0; +} + +.u-nav .preview-rendered code { + background: var(--surface-2); + border-radius: 4px; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + padding: 1px 4px; +} + +.u-nav .preview-table-wrap { + border: 1px solid var(--line); + border-radius: 6px; + overflow: auto; +} + +.u-nav .preview-table { + border-collapse: collapse; + min-width: 100%; +} + +.u-nav .preview-table td { + border-bottom: 1px solid var(--line); + border-right: 1px solid var(--line); + padding: 6px 8px; + white-space: nowrap; +} + +.u-nav .preview-media { + align-items: center; + background: var(--surface-2); + border: 1px solid var(--line); + border-radius: 6px; + display: flex; + justify-content: center; + overflow: auto; + padding: 10px; +} + +.u-nav .preview-media img, +.u-nav .preview-media video { + max-height: 100%; + max-width: 100%; +} + +.u-nav .preview-media audio { + width: min(100%, 560px); +} + +.u-nav .preview-frame { + border: 1px solid var(--line); + border-radius: 6px; + height: 100%; + width: 100%; +} + @media (max-width: 720px) { .u-nav .topbar { align-items: flex-start; diff --git a/u-navigator.plg b/u-navigator.plg index 895f04c..ab2a009 100644 --- a/u-navigator.plg +++ b/u-navigator.plg @@ -1,7 +1,7 @@ - + @@ -24,7 +24,7 @@ https://git.casaderoll.de/michael/Unraid-Navigator/raw/branch/main/packages/&package; -64307317988b7af11b76fce0993e76e6 +ec6c71ed634dea8f56f0349815a89967