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:
commit
73b0010d60
6 changed files with 112 additions and 51 deletions
|
|
@ -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%' }}>
|
||||
|
|
|
|||
46
frontend/src/components/TextPreview.jsx
Normal file
46
frontend/src/components/TextPreview.jsx
Normal 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>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue