Implement combining filters for film grid
Refactored filtering logic into separate functions.
This commit is contained in:
parent
e49b82743d
commit
b4d75c3c2e
1 changed files with 48 additions and 46 deletions
|
|
@ -16,6 +16,8 @@ use crate::views::overview::FilmOverview;
|
|||
|
||||
pub struct FilmGrid {
|
||||
items: FactoryVecDeque<FilmGridItem>,
|
||||
watch_filter: Option<WatchFilter>,
|
||||
name_filter: Option<String>,
|
||||
}
|
||||
|
||||
#[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<FilmGrid>,
|
||||
_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<WatchFilter>) -> 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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue