feat: smart thumbnail cleanup and rename-aware file tracking

Delete thumbnails alongside DB rows in all three removal paths (watcher
detect, delete-from-disk command, remove-folder command) so orphans no
longer accumulate passively.

Intercept RenameMode::Both watcher events and handle them as in-place
path updates: renames the thumbnail file to the new hash and updates the
DB row without touching the embedding, avoiding a full rebuild on move.
Falls back to thumbnail regeneration if the file rename fails.
This commit is contained in:
2026-06-09 01:16:12 +01:00
parent 8eaa0bd8e8
commit ceb51f8fad
4 changed files with 173 additions and 13 deletions
+8
View File
@@ -264,10 +264,15 @@ pub async fn remove_folder(
.into_iter()
.find(|f| f.id == folder_id)
.map(|f| PathBuf::from(f.path));
// Collect thumbnail paths before the cascade delete removes the rows.
let thumb_paths = db::get_thumbnail_paths_for_folder(&conn, folder_id).unwrap_or_default();
db::delete_folder(&conn, folder_id).map_err(|e| e.to_string())?;
if let Some(path) = folder_path {
watcher.remove_folder(&path);
}
for thumb in &thumb_paths {
let _ = std::fs::remove_file(thumb);
}
Ok(())
}
@@ -1192,6 +1197,9 @@ pub async fn delete_images_from_disk(
for r in records.into_iter().filter(|r| id_set.contains(&r.id)) {
if std::fs::remove_file(&r.path).is_ok() {
succeeded_ids.push(r.id);
if let Some(thumb) = &r.thumbnail_path {
let _ = std::fs::remove_file(thumb);
}
}
}
if !succeeded_ids.is_empty() {