Fully local feature - no network access, no credentials. New aurora-curator-core::sfv module streams file hashing in 64KB chunks and handles both the traditional .sfv format (CRC32, "name checksum" layout) and the GNU coreutils md5sum/sha1sum sidecar convention (.md5/.sha1, "checksum name" layout), dispatched on a shared ChecksumKind enum. New src-tauri/src/sfv.rs wraps it in three Tauri commands - compute_checksums (per-file error isolation), save_checksum_file (native Save dialog), and verify_checksum_file (resolves each entry against the checksum file's own parent directory, reports OK/Mismatch/Missing per entry). New SfvPanel.tsx/.css wires it all into the sidebar's SFV screen - load files, pick a checksum type, Compute, Save, or Verify against an existing checksum file. 14 new core-crate tests + 1 new src-tauri test, all passing (workspace: 160/160). Verified end-to-end with a 22-check Playwright script against npm run dev.
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { useState } from "react";
|
|
import Sidebar, { PANELS } from "./components/Sidebar";
|
|
import Header from "./components/Header";
|
|
import RenamePanel from "./components/RenamePanel";
|
|
import EpisodesPanel from "./components/EpisodesPanel";
|
|
import SubtitlesPanel from "./components/SubtitlesPanel";
|
|
import SfvPanel from "./components/SfvPanel";
|
|
import PanelStub from "./components/PanelStub";
|
|
|
|
export default function App() {
|
|
const [selected, setSelected] = useState(PANELS[0].id);
|
|
const current = PANELS.find((p) => p.id === selected) ?? PANELS[0];
|
|
|
|
return (
|
|
<div className="app-shell">
|
|
<Sidebar selected={selected} onSelect={setSelected} />
|
|
<div className="main-column">
|
|
<Header title={current.name} />
|
|
<div className="main-content">
|
|
{selected === "rename" ? (
|
|
<RenamePanel />
|
|
) : selected === "episodes" ? (
|
|
<EpisodesPanel />
|
|
) : selected === "subtitles" ? (
|
|
<SubtitlesPanel />
|
|
) : selected === "sfv" ? (
|
|
<SfvPanel />
|
|
) : (
|
|
<PanelStub name={current.name} />
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|