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 {
|
pub struct FilmGrid {
|
||||||
items: FactoryVecDeque<FilmGridItem>,
|
items: FactoryVecDeque<FilmGridItem>,
|
||||||
|
watch_filter: Option<WatchFilter>,
|
||||||
|
name_filter: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -64,7 +66,11 @@ impl Component for FilmGrid {
|
||||||
let items = FactoryVecDeque::builder()
|
let items = FactoryVecDeque::builder()
|
||||||
.launch(widgets.grid.clone())
|
.launch(widgets.grid.clone())
|
||||||
.detach();
|
.detach();
|
||||||
let model = FilmGrid { items };
|
let model = FilmGrid {
|
||||||
|
items,
|
||||||
|
watch_filter: None,
|
||||||
|
name_filter: None,
|
||||||
|
};
|
||||||
|
|
||||||
sender.oneshot_command(async move {
|
sender.oneshot_command(async move {
|
||||||
let overview = DataManager::films_overview().await;
|
let overview = DataManager::films_overview().await;
|
||||||
|
|
@ -83,8 +89,6 @@ impl Component for FilmGrid {
|
||||||
_sender: ComponentSender<FilmGrid>,
|
_sender: ComponentSender<FilmGrid>,
|
||||||
_root: &ScrolledWindow,
|
_root: &ScrolledWindow,
|
||||||
) {
|
) {
|
||||||
// TODO: Make combining filters work properly or, indeed, at all.
|
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
FilmGridInput::SortBy(sorting, direction) => {
|
FilmGridInput::SortBy(sorting, direction) => {
|
||||||
let mut items = self.items.guard();
|
let mut items = self.items.guard();
|
||||||
|
|
@ -101,49 +105,14 @@ impl Component for FilmGrid {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
FilmGridInput::ApplyWatchFilter(watched_filter) => match watched_filter {
|
FilmGridInput::ApplyWatchFilter(watch_filter) => {
|
||||||
Some(WatchFilter::OnlyWatched) => {
|
self.watch_filter = watch_filter;
|
||||||
for (index, item) in self.items.iter().enumerate() {
|
self.apply_filters();
|
||||||
if item.film().watched {
|
}
|
||||||
self.items.send(index, FilmGridItemInput::SetVisible(true));
|
FilmGridInput::ApplyNameFilter(name_filter) => {
|
||||||
} else {
|
self.name_filter = name_filter;
|
||||||
self.items.send(index, FilmGridItemInput::SetVisible(false));
|
self.apply_filters();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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