From b4d75c3c2e6d304fea4423ca7e2c097074497e91 Mon Sep 17 00:00:00 2001 From: Reinout Meliesie Date: Thu, 29 Jan 2026 15:53:55 +0100 Subject: [PATCH] Implement combining filters for film grid Refactored filtering logic into separate functions. --- src/ui/components/media_grid/film_grid.rs | 94 ++++++++++++----------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/src/ui/components/media_grid/film_grid.rs b/src/ui/components/media_grid/film_grid.rs index b6cb972..3a8a505 100644 --- a/src/ui/components/media_grid/film_grid.rs +++ b/src/ui/components/media_grid/film_grid.rs @@ -16,6 +16,8 @@ use crate::views::overview::FilmOverview; pub struct FilmGrid { items: FactoryVecDeque, + watch_filter: Option, + name_filter: Option, } #[derive(Debug)] @@ -64,7 +66,11 @@ impl Component for FilmGrid { let items = FactoryVecDeque::builder() .launch(widgets.grid.clone()) .detach(); - let model = FilmGrid { items }; + let model = FilmGrid { + items, + watch_filter: None, + name_filter: None, + }; sender.oneshot_command(async move { let overview = DataManager::films_overview().await; @@ -83,8 +89,6 @@ impl Component for FilmGrid { _sender: ComponentSender, _root: &ScrolledWindow, ) { - // TODO: Make combining filters work properly or, indeed, at all. - match message { FilmGridInput::SortBy(sorting, direction) => { let mut items = self.items.guard(); @@ -101,49 +105,14 @@ impl Component for FilmGrid { } }); } - FilmGridInput::ApplyWatchFilter(watched_filter) => match watched_filter { - Some(WatchFilter::OnlyWatched) => { - for (index, item) in self.items.iter().enumerate() { - if item.film().watched { - self.items.send(index, FilmGridItemInput::SetVisible(true)); - } else { - self.items.send(index, FilmGridItemInput::SetVisible(false)); - } - } - } - Some(WatchFilter::OnlyUnwatched) => { - for (index, item) in self.items.iter().enumerate() { - if item.film().watched { - self.items.send(index, FilmGridItemInput::SetVisible(false)); - } else { - self.items.send(index, FilmGridItemInput::SetVisible(true)); - } - } - } - None => { - self.items.broadcast(FilmGridItemInput::SetVisible(true)); - } - }, - FilmGridInput::ApplyNameFilter(name_filter) => match name_filter { - Some(name_filter) => { - let name_filter = name_filter.to_lowercase(); - for (index, item) in self.items.iter().enumerate() { - let name = item.film().name.to_lowercase(); - let name_matches = name.contains(name_filter.as_str()); - let orig_name = item.film().original_name.as_deref().map(str::to_lowercase); - let orig_name_matches = - orig_name.is_some_and(|orig_name| orig_name.contains(name_filter.as_str())); - if name_matches || orig_name_matches { - self.items.send(index, FilmGridItemInput::SetVisible(true)); - } else { - self.items.send(index, FilmGridItemInput::SetVisible(false)); - } - } - } - None => { - self.items.broadcast(FilmGridItemInput::SetVisible(true)); - } - }, + FilmGridInput::ApplyWatchFilter(watch_filter) => { + self.watch_filter = watch_filter; + self.apply_filters(); + } + FilmGridInput::ApplyNameFilter(name_filter) => { + self.name_filter = name_filter; + self.apply_filters(); + } } } @@ -172,3 +141,36 @@ impl Component for FilmGrid { } } } + +impl FilmGrid { + fn apply_filters(&mut self) { + for (index, item) in self.items.iter().enumerate() { + let show_item = film_matches_watch_filter(item.film(), self.watch_filter) + && film_matches_name_filter(item.film(), self.name_filter.as_deref()); + self + .items + .send(index, FilmGridItemInput::SetVisible(show_item)); + } + } +} + +fn film_matches_watch_filter(film: &FilmOverview, filter: Option) -> bool { + if let Some(watch_filter) = filter { + match watch_filter { + WatchFilter::OnlyWatched => film.watched, + WatchFilter::OnlyUnwatched => !film.watched, + } + } else { + true + } +} + +fn film_matches_name_filter(film: &FilmOverview, filter: Option<&str>) -> bool { + if let Some(name_filter) = filter { + let name_filter = name_filter.to_lowercase(); + let name = film.name.to_lowercase(); + name.contains(name_filter.as_str()) + } else { + true + } +}