Add rename history with undo
- New crates/renamr-core/src/history module: HistoryBatch/HistoryEntry records, revert_batch() moves files back to their original paths (skip-on-conflict, same policy as rename::execute_renames; recreates a deleted destination folder defensively), push_batch() maintains a most-recent-first log capped at 50 batches. A partial port of the idea behind net.filebot.HistoryDialog, as a flat undo stack rather than a full session/element log. 6 new tests. - New src-tauri/src/history.rs: persists the log as history.json in the OS app-config directory (same location as settings.json). execute_rename now takes an AppHandle and calls history::record_batch after every rename, recording only the items that actually got renamed. Two new commands: list_rename_history and undo_rename_batch. - Frontend: the History button (previously a no-op) now opens a panel listing past rename batches with a timestamp, file count, and the old-name/new-name pairs, each with an Undo button. Undoing reconciles any currently-loaded item back to its pre-rename path/name, same pattern as post-rename reconciliation. - Verified via cargo test (45 total)/check + npm build + a full Playwright pass: loaded mocked files, renamed them, opened History, undid the batch, and confirmed both the UI and the (mocked) backend state matched at every step.
This commit is contained in:
@@ -10,10 +10,11 @@ detection ("Match") is working, real online metadata lookups against TMDB ("Fetc
|
||||
Data") are working — including fuzzy show-name disambiguation, so a search that
|
||||
returns several similarly-named shows doesn't just take TMDB's top-ranked hit — and the
|
||||
actual on-disk rename operation is wired up (skip-on-conflict, with a confirmation step
|
||||
showing the full old-name/new-name plan before anything touches disk — there is no undo
|
||||
yet). Rename can also organize files into subfolders — including ones that don't exist
|
||||
yet — when the naming scheme includes a `/`. Full media-metadata bindings are not yet
|
||||
ported. See "Porting roadmap" below.
|
||||
showing the full old-path/new-path plan before anything touches disk). Rename can also
|
||||
organize files into subfolders — including ones that don't exist yet — when the naming
|
||||
scheme includes a `/`. Every completed rename is logged to a history panel that can
|
||||
undo it, moving files back to their original paths. Full media-metadata bindings are
|
||||
not yet ported. See "Porting roadmap" below.
|
||||
|
||||
The naming scheme is fully user-editable from the app (the "Naming Scheme" button next
|
||||
to the New Names list) — the default is `{show name} - {season number}x{episode
|
||||
@@ -110,23 +111,26 @@ crates/renamr-core/ Pure Rust core: naming-expression engine (ported), local
|
||||
(`similarity/`, partial `EpisodeMetrics` port), a TMDB metadata
|
||||
client (`web/tmdb.rs` — TV search + episode lookup, disambiguated
|
||||
via `similarity/`, tested against a mocked HTTP server via
|
||||
`mockito`), and the on-disk rename engine (`rename/`) —
|
||||
`mockito`), the on-disk rename engine (`rename/`) —
|
||||
skip-on-conflict, can also organize into (auto-created)
|
||||
subfolders when the naming scheme includes `/`. Not yet ported:
|
||||
full media metadata bindings, other web datasource clients
|
||||
(TVDB/AniDB/etc).
|
||||
subfolders when the naming scheme includes `/` — and a rename
|
||||
history/undo log (`history/`, a partial `HistoryDialog` port).
|
||||
Not yet ported: full media metadata bindings, other web
|
||||
datasource clients (TVDB/AniDB/etc).
|
||||
No Tauri dependency, so it builds and unit-tests standalone.
|
||||
src-tauri/ Tauri app shell: exposes renamr-core as commands to the frontend
|
||||
(naming-scheme rendering, filename matching, TMDB metadata fetch,
|
||||
executing a rename plan, native file/folder dialogs, drag-and-drop
|
||||
expansion), plus `settings.rs` (TMDB token, stored as JSON in the
|
||||
OS app-config directory), app metadata/icons/window config
|
||||
expansion), plus `settings.rs` (TMDB token) and `history.rs`
|
||||
(rename history/undo log) — both stored as JSON in the OS
|
||||
app-config directory — app metadata/icons/window config
|
||||
(tauri.conf.json).
|
||||
src/ React + TypeScript UI (Vite). Faithful recreation of the original
|
||||
two-pane rename screen (Aurora theme) wired to real file loading,
|
||||
drag-and-drop, live naming-scheme preview, local matching, TMDB
|
||||
fetch (behind a Settings modal for the API token), and a
|
||||
confirm-before-touching-disk modal for the actual rename.
|
||||
fetch (behind a Settings modal for the API token), a
|
||||
confirm-before-touching-disk modal for the actual rename, and a
|
||||
History panel that can undo a past rename.
|
||||
scripts/gen_icons.py Regenerates src-tauri/icons/ (placeholder branding — swap the
|
||||
colors/glyph in the script, or replace the icons directly, to
|
||||
change the look).
|
||||
@@ -217,13 +221,18 @@ ported from, for anyone picking this up:
|
||||
`--conflict` variants beyond skip (auto-number, override), and the CLI flag surface
|
||||
itself.
|
||||
7. **The rest of the UI** — the Rename panel (file loading, drag-drop, live preview,
|
||||
local matching, confirmed rename) is built; the other five sidebar panels
|
||||
(Episodes/Subtitles/SFV/Filter/List) are still stub screens, plus Align up/down
|
||||
reordering, History, and Presets on the Rename panel itself are no-ops. There's also
|
||||
no per-item exclude inside the rename confirmation modal yet (it's all-or-nothing —
|
||||
use "Exclude Selected" on the file list beforehand to leave a file out entirely).
|
||||
8. **Undo/history for renames** — there is no undo yet; the confirmation modal before
|
||||
Rename executes is the only safety net right now. `net.filebot.HistoryDialog`/the
|
||||
original's rename-history log is the reference for what a real undo would look like.
|
||||
local matching, confirmed rename, rename history/undo) is built; the other five
|
||||
sidebar panels (Episodes/Subtitles/SFV/Filter/List) are still stub screens, plus
|
||||
Align up/down reordering and Presets on the Rename panel itself are still no-ops.
|
||||
There's also no per-item exclude inside the rename confirmation modal yet (it's
|
||||
all-or-nothing — use "Exclude Selected" on the file list beforehand to leave a file
|
||||
out entirely).
|
||||
8. **Undo/history for renames** — done, as a flat JSON-backed undo stack rather than a
|
||||
full port of `net.filebot.HistoryDialog`'s session/element log
|
||||
(`crates/renamr-core/src/history`, `src-tauri/src/history.rs`). Every successful
|
||||
rename is recorded to a `history.json` in the OS app-config directory (same location
|
||||
as `settings.json`); the History panel lists past batches and can revert one back to
|
||||
its original paths, skipping (never overwriting) any file whose original path now
|
||||
has something else at it. Capped at the 50 most recent batches.
|
||||
9. **Packaging** — code signing, auto-update, installers per platform via
|
||||
`npm run tauri build`.
|
||||
|
||||
Reference in New Issue
Block a user