Enable Filters: Find Similar turns filtering back on; a filter put aside follows renamed keywords, people and folders

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas
2026-10-23 17:20:11 -04:00
co-authored by Claude Opus 5.5
parent b6d94b447b
commit 5e5602b4ca
5 changed files with 31 additions and 0 deletions
+3
View File
@@ -482,6 +482,9 @@ pub(crate) fn follow_folder(s: &mut Session, from: &str, to: &str) {
// a library folder chosen at or below it follows too, as a source or as a filter
follow_library_folder(&mut s.library_folder, from, to);
follow_library_folder(&mut s.filter.library_folder, from, to);
if let Some(f) = s.shelved_filter.as_mut() {
follow_library_folder(&mut f.library_folder, from, to);
}
if let Some(b) = &mut s.browse
&& let Ok(rel) = Path::new(&b.path).strip_prefix(from)
{
+1
View File
@@ -115,6 +115,7 @@ fn find_similar(s: &mut Session, p: &Value) -> Result<Value> {
}
hits.sort_by(|a, b| b.1.total_cmp(&a.1));
if p.get("filter").and_then(Value::as_bool).unwrap_or(true) {
s.shelved_filter = None;
s.filter.only = hits.iter().map(|h| h.0).collect();
}
Ok(json!({"photos": hits.iter().map(|(i, v)| json!({"id": i.0, "similarity": (v * 1000.0).round() / 1000.0})).collect::<Vec<_>>()}))
+5
View File
@@ -176,6 +176,11 @@ fn rename_person(s: &mut Session, p: &Value) -> Result<Value> {
if s.filter.person.as_deref().is_some_and(|n| n.trim().to_lowercase() == from_key) {
s.filter.person = Some(to.clone());
}
if let Some(f) = s.shelved_filter.as_mut()
&& f.person.as_deref().is_some_and(|n| n.trim().to_lowercase() == from_key)
{
f.person = Some(to.clone());
}
Ok(json!({"faces": faces, "photos": photos, "from": from, "to": to, "merged": other}))
}
+6
View File
@@ -32,6 +32,12 @@ fn commit_keywords(s: &mut Session, label: &str, op: lightcraft_catalog::Op, fol
if let Some(k) = s.filter.keyword.clone() {
s.filter.keyword = follow(&k);
}
// a filter put aside by Enable Filters follows the keyword too
if let Some(f) = s.shelved_filter.as_mut()
&& let Some(k) = f.keyword.clone()
{
f.keyword = follow(&k);
}
Ok(json!({"changed": photos, "listed": listed}))
}
@@ -136,3 +136,19 @@ fn removing_the_only_criterion_put_aside_leaves_filtering_on() {
s.execute("library.removeFolder", &json!({"path": "/lightcraft-enable-filters"})).unwrap();
assert!(s.shelved_filter.is_none(), "an empty filter is not left put aside");
}
#[test]
fn a_keyword_renamed_while_off_is_followed_by_the_filter_put_aside() {
let mut s = session().unwrap();
let mut photo = Photo::new(PhotoId(5), Source::File { path: "/lightcraft-enable-filters/5.jpg".into() }, "5.jpg", "JPEG", 40, 30, "2026-10-23");
photo.meta.keywords = vec!["cat".into()];
s.catalog.apply(Op::AddPhoto { photo: Box::new(photo) }).unwrap();
s.filter.keyword = Some("cat".into());
assert_eq!(s.visible().len(), 1);
s.execute("library.toggleFilters", &json!({})).unwrap();
s.execute("keyword.rename", &json!({"from": "cat", "to": "dog"})).unwrap();
let r = s.execute("library.toggleFilters", &json!({})).unwrap();
assert_eq!(r["enabled"], json!(true));
assert_eq!(s.filter.keyword.as_deref(), Some("dog"), "the put-aside filter follows the rename");
assert_eq!(s.visible().len(), 1);
}