From 59896521879a9cf23c817159fa7837941db12c5c Mon Sep 17 00:00:00 2001
From: Till JS
Date: Thu, 26 Mar 2026 09:29:12 +0100
Subject: [PATCH] feat(storage): add video, PDF, text/code, and markdown
preview
Extend FilePreviewModal with rich previews for more file types:
- Video: native
');
+
+ // Wrap loose
in
+ html = html.replace(/((?:- .*<\/li>\s*)+)/g, '');
+
+ return `
${html}
`;
+ }
+
function handleAction(action: string) {
if (file) {
onAction(action, file);
@@ -136,6 +232,18 @@
{#if isImage && imageUrl}

+ {:else if isVideo}
+ {#if presignedUrl}
+
+
+ {:else}
+
+
+
Video wird geladen…
+
+ {/if}
{:else if isAudio}
+ {:else if isPdf}
+ {#if presignedUrl}
+
+ {:else}
+
+ {/if}
{:else if isTextOrCode}
-
-
-
Vorschau nicht verfügbar
-
+ {#if textLoading}
+
+
+
Inhalt wird geladen…
+
+ {:else if textContent !== null}
+ {#if isMarkdown}
+
+ {@html renderMarkdown(textContent)}
+
+ {:else}
+
{textContent}
+ {/if}
+ {:else}
+
+
+
Vorschau nicht verfügbar
+
+ {/if}
{:else}
-
+
{/if}
@@ -255,7 +388,7 @@
border-radius: var(--radius-xl);
box-shadow: var(--shadow-xl);
width: 100%;
- max-width: 600px;
+ max-width: 700px;
max-height: 90vh;
margin: 1rem;
display: flex;
@@ -323,6 +456,111 @@
object-fit: contain;
}
+ .video-preview {
+ width: 100%;
+ max-height: 400px;
+ border-radius: var(--radius-md);
+ background: #000;
+ }
+
+ .pdf-preview {
+ width: 100%;
+ height: 500px;
+ border: none;
+ border-radius: var(--radius-md);
+ }
+
+ .text-preview {
+ width: 100%;
+ max-height: 400px;
+ overflow: auto;
+ padding: 1rem;
+ margin: 0;
+ font-size: 0.8125rem;
+ line-height: 1.6;
+ color: rgb(var(--color-text-primary));
+ background: rgb(var(--color-surface));
+ border-radius: var(--radius-md);
+ text-align: left;
+ white-space: pre-wrap;
+ word-break: break-word;
+ font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
+ tab-size: 4;
+ }
+
+ .text-preview code {
+ font-family: inherit;
+ font-size: inherit;
+ }
+
+ .markdown-preview {
+ font-family: inherit;
+ white-space: normal;
+ }
+
+ .markdown-preview :global(h1) {
+ font-size: 1.375rem;
+ font-weight: 700;
+ margin: 0 0 0.5rem;
+ }
+
+ .markdown-preview :global(h2) {
+ font-size: 1.125rem;
+ font-weight: 600;
+ margin: 1rem 0 0.375rem;
+ }
+
+ .markdown-preview :global(h3) {
+ font-size: 1rem;
+ font-weight: 600;
+ margin: 0.75rem 0 0.25rem;
+ }
+
+ .markdown-preview :global(code) {
+ font-family: 'SF Mono', 'Fira Code', monospace;
+ font-size: 0.8em;
+ padding: 0.125rem 0.375rem;
+ background: rgb(var(--color-border) / 0.5);
+ border-radius: var(--radius-sm);
+ }
+
+ .markdown-preview :global(pre) {
+ background: rgb(var(--color-surface-elevated));
+ padding: 0.75rem;
+ border-radius: var(--radius-md);
+ overflow-x: auto;
+ margin: 0.5rem 0;
+ }
+
+ .markdown-preview :global(pre code) {
+ padding: 0;
+ background: none;
+ }
+
+ .markdown-preview :global(ul) {
+ padding-left: 1.25rem;
+ margin: 0.375rem 0;
+ }
+
+ .markdown-preview :global(li) {
+ margin: 0.125rem 0;
+ }
+
+ .markdown-preview :global(hr) {
+ border: none;
+ border-top: 1px solid rgb(var(--color-border));
+ margin: 0.75rem 0;
+ }
+
+ .markdown-preview :global(a) {
+ color: rgb(var(--color-primary));
+ text-decoration: underline;
+ }
+
+ .markdown-preview :global(strong) {
+ font-weight: 600;
+ }
+
.audio-preview {
display: flex;
flex-direction: column;