Release Archive Tools 0.1.0

This commit is contained in:
2026-09-01 02:42:42 +02:00
commit a49ec6b17a
77 changed files with 11528 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
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 url = URL.createObjectURL(preview.blob);
node.src = url;
return () => {
node.removeAttribute("src");
URL.revokeObjectURL(url);
};
}, [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>
);
}