Add Move/Copy/Symlink rename actions, with undo support for all three
- renamr-core::rename: new RenameAction enum (Move/Copy/Symlink, default Move, mirroring net.filebot.cli.CmdlineOperations's --action modes). execute_renames() now takes an action applied to the whole batch. Copy uses fs::copy (source untouched); Symlink uses std::os::unix::fs::symlink / std::os::windows::fs::symlink_file behind a cfg(unix)/cfg(windows) split. Same conflict policy (skip, never overwrite) and auto-created destination folders apply to all three actions. 8 new tests. - renamr-core::history: HistoryBatch now records which action produced it (#[serde(default)] so old history.json entries - all implicitly Move - still deserialize). revert_one() branches on it: Move still moves the file back; Copy/ Symlink undo by deleting the copy/symlink (using symlink_metadata so a broken link is still recognized as present and removable) - the original was never touched by those actions, so there's nothing to move back. 3 new tests. - src-tauri: execute_rename command takes the chosen action and threads it through to both execute_renames and record_batch. - Frontend: a Move/Copy/Symlink segmented selector in the "Confirm Rename" modal (remembered across modal opens, defaults to Move), action-aware subtitle/button copy, and a status message using the right verb (Renamed/Copied/Symlinked). Only Move reconciles a loaded item's id/name/bindings to the new path afterward, since Copy/ Symlink leave the source file exactly where it was. History panel now shows a Copy/ Symlink badge on non-Move batches and explains what Undo does for each. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
aab8e28246
commit
fd4e6f66f0
+14
-11
@@ -5,7 +5,7 @@ mod settings;
|
||||
|
||||
use renamr_core::format::ExpressionFormat;
|
||||
use renamr_core::matching::{self, EpisodeGuess, MovieGuess};
|
||||
use renamr_core::rename::{self, RenamePlanItem, RenameResult};
|
||||
use renamr_core::rename::{self, RenameAction, RenamePlanItem, RenameResult};
|
||||
use renamr_core::string_bindings;
|
||||
use std::collections::HashMap;
|
||||
use tauri::AppHandle;
|
||||
@@ -39,20 +39,23 @@ fn guess_movie(filename: String) -> Option<MovieGuess> {
|
||||
matching::guess_movie(&filename)
|
||||
}
|
||||
|
||||
/// Executes a batch of planned on-disk renames (optionally moving files into
|
||||
/// subfolders - see `renamr_core::rename`; conflicting targets are always skipped,
|
||||
/// never overwritten). The UI is expected to have already shown the user the full
|
||||
/// old-path/new-path plan and gotten explicit confirmation before calling this.
|
||||
/// Runs off the main thread since real filesystem I/O shouldn't block the UI.
|
||||
/// Executes a batch of planned on-disk rename/copy/symlink operations (optionally
|
||||
/// moving/copying files into subfolders - see `renamr_core::rename`; conflicting
|
||||
/// targets are always skipped, never overwritten). `action` picks which of the three
|
||||
/// happens - the UI is expected to have already shown the user the full old-path/
|
||||
/// new-path plan, the chosen action, and gotten explicit confirmation before calling
|
||||
/// this. Runs off the main thread since real filesystem I/O shouldn't block the UI.
|
||||
///
|
||||
/// Every successfully-renamed item is recorded to the rename history log afterward
|
||||
/// (see `history::record_batch`) so it can be undone later from the History panel.
|
||||
/// Every successfully-produced item is recorded to the rename history log afterward
|
||||
/// (see `history::record_batch`), tagged with `action`, so it can be undone later from
|
||||
/// the History panel - a Move undo moves the file back, a Copy/Symlink undo just
|
||||
/// removes what was created.
|
||||
#[tauri::command]
|
||||
async fn execute_rename(app: AppHandle, items: Vec<RenamePlanItem>) -> Vec<RenameResult> {
|
||||
let results = tauri::async_runtime::spawn_blocking(move || rename::execute_renames(&items))
|
||||
async fn execute_rename(app: AppHandle, items: Vec<RenamePlanItem>, action: RenameAction) -> Vec<RenameResult> {
|
||||
let results = tauri::async_runtime::spawn_blocking(move || rename::execute_renames(&items, action))
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
history::record_batch(&app, &results);
|
||||
history::record_batch(&app, &results, action);
|
||||
results
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user