mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 03:05:32 +02:00
feat: entry previews — tweet/thread/article/video/audio/image/iframe/pdf
- PreviewModal: modal overlay with new-tab link (↗) and keyboard close - PreviewPanel: routes by entity_kind + primary_media extension to the correct viewer (tweet/video/audio/pdf/html/image/fallback) - TweetPreview: full X-style tweet, thread, and article renderer with local artifact map for archived media (CDN fallback) - AudioBar: persistent fixed bottom player, triggered via ContextRail Play button; body.has-audio-bar pads content above it - VideoPreview, IframePreview, ImagePreview: inline viewers - PreviewPage: standalone /preview/:archiveId/:entryUid route - ContextRail: Play/Preview buttons; isAudio/isPreviewable detection - App.jsx: preview modal state, currentAudio state, preview route guard, has-audio-bar body class effect - routes.rs: CSP updated (media-src self blob https; frame-ancestors self; Google Fonts + external images/scripts whitelisted) - styles.css: preview modal, tweet-wrap scroll (min-height:0), audio bar body padding, newtab button, preview panel flex layout
This commit is contained in:
parent
5de9e291b0
commit
8755e2c503
14 changed files with 574 additions and 298 deletions
32
frontend/src/components/PreviewModal.jsx
Normal file
32
frontend/src/components/PreviewModal.jsx
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { useEffect } from 'react'
|
||||
import PreviewPanel from './PreviewPanel'
|
||||
|
||||
export default function PreviewModal({ archiveId, entry, detail, onClose }) {
|
||||
// Close on Escape key
|
||||
useEffect(() => {
|
||||
const handler = (e) => { if (e.key === 'Escape') onClose() }
|
||||
window.addEventListener('keydown', handler)
|
||||
return () => window.removeEventListener('keydown', handler)
|
||||
}, [onClose])
|
||||
|
||||
return (
|
||||
<div className="preview-modal-backdrop" onClick={onClose}>
|
||||
<div className="preview-modal" onClick={e => e.stopPropagation()}>
|
||||
<div className="preview-modal-header">
|
||||
<span className="preview-modal-title">{entry?.title || entry?.entry_uid || 'Preview'}</span>
|
||||
<a
|
||||
className="preview-modal-newtab"
|
||||
href={`/preview/${archiveId}/${entry?.entry_uid}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="Open in new tab"
|
||||
>↗</a>
|
||||
<button className="preview-modal-close" onClick={onClose} aria-label="Close preview">×</button>
|
||||
</div>
|
||||
<div className="preview-modal-body">
|
||||
<PreviewPanel archiveId={archiveId} entry={entry} detail={detail} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue