"use client"; import { useState } from "react"; import { runMediaScanAction, type RunMediaScanResult, } from "../actions"; type Status = | { kind: "idle" } | { kind: "running" } | { kind: "done"; result: RunMediaScanResult } | { kind: "error"; message: string }; // The depth choice is the whole reason this has a select rather than one button. // The container read costs milliseconds per file; the full decode is a real // transcode of every suspect file, so it has to be asked for rather than // happening because someone clicked the obvious thing. type Depth = "quick" | "deep"; export function RunMediaScanButton({ slug }: { slug?: string }) { const [depth, setDepth] = useState("quick"); const [status, setStatus] = useState({ kind: "idle" }); async function handleClick() { setStatus({ kind: "running" }); try { const result = await runMediaScanAction({ ...(slug ? { channels: [slug] } : {}), deepProbe: depth === "deep", }); setStatus({ kind: "done", result }); } catch (e) { setStatus({ kind: "error", message: (e as Error).message }); } } const running = status.kind === "running"; return (
{status.kind === "done" && status.result.ok && ( {status.result.filesScanned.toLocaleString()} file(s) checked ·{" "} {status.result.findings.toLocaleString()} finding(s) )} {status.kind === "done" && !status.result.ok && ( {status.result.error} )} {status.kind === "error" && ( {status.message} )}
); }