1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-10-09 21:03:17 +02:00

Merge branch 'feat/archive-text-with-title' into integration-all-three

# Conflicts:
#	crates/archivr-server/static/assets/index-C4rpqY7g.js
#	crates/archivr-server/static/index.html
This commit is contained in:
archivr-qa 2026-08-23 19:03:25 +02:00
commit 73b0010d60
No known key found for this signature in database
6 changed files with 112 additions and 51 deletions

View file

@ -2,10 +2,12 @@ import VideoPreview from './VideoPreview';
import IframePreview from './IframePreview';
import ImagePreview from './ImagePreview';
import TweetPreview from './TweetPreview';
import TextPreview from './TextPreview';
const VIDEO_EXTS = new Set(['mp4', 'webm', 'mov', 'mkv', 'avi', 'm4v', 'ogv']);
const AUDIO_EXTS = new Set(['mp3', 'ogg', 'm4a', 'opus', 'wav', 'flac', 'aac']);
const IMAGE_EXTS = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif', 'svg', 'bmp']);
const TEXT_EXTS = new Set(['md', 'markdown', 'txt']);
const CONTENT_TYPES = {
mp4: 'video/mp4', webm: 'video/webm', mov: 'video/quicktime',
mkv: 'video/x-matroska', avi: 'video/x-msvideo', m4v: 'video/mp4', ogv: 'video/ogg',
@ -131,7 +133,20 @@ export default function PreviewPanel({ archiveId, entry, detail, fullPage, onXAr
);
}
// 7. Image
// 6b. Plain text / Markdown
if (TEXT_EXTS.has(ext)) {
return (
<div className="preview-panel" style={{ flex: 1, minHeight: 0, overflow: 'auto' }}>
<TextPreview
src={primaryMediaUrl}
mime={primaryArtifact.mime_type}
title={summary.title}
/>
</div>
);
}
// 7. Image
if (IMAGE_EXTS.has(ext)) {
return (
<div className="preview-panel" style={{ height: '100%' }}>

View file

@ -0,0 +1,46 @@
import { useEffect, useState } from 'react'
/**
* Renders the primary_media artifact of a text/document entry as plain text.
*
* v1 intentionally does NOT render Markdown — we don't want a Markdown parser
* dep just to unblock the "no preview available" fallback, and monospace text
* with visible fences reads fine for the note-length content this feature
* captures. Bump to a real renderer if/when Markdown-authored entries grow.
*/
export default function TextPreview({ src, mime, title }) {
const [text, setText] = useState(null)
const [error, setError] = useState(null)
useEffect(() => {
let cancelled = false
setText(null)
setError(null)
fetch(src, { credentials: 'same-origin' })
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`)
return r.text()
})
.then(t => { if (!cancelled) setText(t) })
.catch(e => { if (!cancelled) setError(e.message || String(e)) })
return () => { cancelled = true }
}, [src])
if (error) {
return (
<div className="text-preview text-preview--error">
Failed to load text: {error}
</div>
)
}
if (text === null) {
return <div className="text-preview text-preview--loading">Loading…</div>
}
return (
<div className="text-preview">
{title && <h1 className="text-preview__title">{title}</h1>}
<pre className="text-preview__body">{text}</pre>
{mime && <div className="text-preview__mime">{mime}</div>}
</div>
)
}