72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
import { createObjectUrlLease } from "@add-ideas/toolbox-helpers";
|
||
import { useEffect, useRef } from "react";
|
||
import type { ArchiveEntryRecord, PreviewResult } from "../../archive/types";
|
||
|
||
export function PreviewPane({
|
||
entry,
|
||
preview,
|
||
busy,
|
||
error,
|
||
}: {
|
||
entry?: ArchiveEntryRecord;
|
||
preview?: PreviewResult;
|
||
busy: boolean;
|
||
error?: string;
|
||
}) {
|
||
const image = useRef<HTMLImageElement>(null);
|
||
useEffect(() => {
|
||
const node = image.current;
|
||
if (!node || preview?.kind !== "image") return;
|
||
const lease = createObjectUrlLease(preview.blob);
|
||
node.src = lease.url;
|
||
return () => {
|
||
node.removeAttribute("src");
|
||
lease.revoke();
|
||
};
|
||
}, [preview]);
|
||
return (
|
||
<aside className="preview-pane" aria-label="Entry preview">
|
||
<div className="panel-heading compact-heading">
|
||
<div>
|
||
<p className="eyebrow">Bounded preview</p>
|
||
<h3>{entry?.path ?? "Choose a file"}</h3>
|
||
</div>
|
||
{busy ? <span className="busy-dot">Reading…</span> : null}
|
||
</div>
|
||
{error ? (
|
||
<p className="status-message status-error" role="alert">
|
||
{error}
|
||
</p>
|
||
) : null}
|
||
{!preview && !error ? (
|
||
<p className="empty-state">
|
||
Text, bytes and static JPEG/PNG/WebP images can be previewed here.
|
||
</p>
|
||
) : null}
|
||
{preview?.note ? <p className="policy-note">{preview.note}</p> : null}
|
||
{preview?.kind === "text" ? (
|
||
<pre className="text-preview">{preview.text}</pre>
|
||
) : null}
|
||
{preview?.kind === "hex" ? (
|
||
<>
|
||
<pre className="hex-preview">{preview.text}</pre>
|
||
{preview.truncated ? (
|
||
<p className="policy-note">Hex preview truncated.</p>
|
||
) : null}
|
||
</>
|
||
) : null}
|
||
{preview?.kind === "image" ? (
|
||
<figure className="image-preview">
|
||
<img
|
||
ref={image}
|
||
alt={`Preview of ${entry?.path ?? "archive image"}`}
|
||
/>
|
||
<figcaption>
|
||
{preview.width} × {preview.height} · {preview.mimeType}
|
||
</figcaption>
|
||
</figure>
|
||
) : null}
|
||
</aside>
|
||
);
|
||
}
|