Skip to content

Commit

Permalink
Filter album photo grid
Browse files Browse the repository at this point in the history
  • Loading branch information
blissd committed Apr 5, 2024
1 parent 6c27456 commit ddb85d4
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 17 deletions.
34 changes: 27 additions & 7 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use self::components::{
one_photo::{OnePhoto, OnePhotoInput},
year_photos::{YearPhotos, YearPhotosInput, YearPhotosOutput},
folder_photos::{FolderPhotos, FolderPhotosInput, FolderPhotosOutput,},
album::{Album, AlbumInput, AlbumOutput,},
album::{Album, AlbumInput, AlbumOutput,AlbumFilter},
};

mod background;
Expand All @@ -74,8 +74,13 @@ pub(super) struct App {
year_photos: AsyncController<YearPhotos>,
one_photo: Controller<OnePhoto>,
selfie_photos: AsyncController<Album>,

// Grid of folders of photos
folder_photos: AsyncController<FolderPhotos>,

// Album view of single folder
folder_album: AsyncController<Album>,

// Main navigation. Parent of library stack.
main_navigation: adw::OverlaySplitView,

Expand Down Expand Up @@ -294,9 +299,13 @@ impl SimpleComponent for App {
set_icon_name: "sentiment-very-satisfied-symbolic",
},

add_child = &gtk::Box {
set_orientation: gtk::Orientation::Vertical,
container_add: model.folder_photos.widget(),
add_child = &adw::NavigationView {
adw::NavigationPage {
model.folder_photos.widget(),
},
adw::NavigationPage {
model.folder_album.widget(),
},
} -> {
set_title: "Folders",
set_name: "Folders",
Expand Down Expand Up @@ -367,7 +376,7 @@ impl SimpleComponent for App {
});

let all_photos = Album::builder()
.launch((repo.clone(), Box::new(App::filter_all_photos)))
.launch((repo.clone(), AlbumFilter::All))
.forward(sender.input_sender(), |msg| match msg {
AlbumOutput::PhotoSelected(id) => AppMsg::ViewPhoto(id),
});
Expand All @@ -389,7 +398,7 @@ impl SimpleComponent for App {
.detach();

let selfie_photos = Album::builder()
.launch((repo.clone(), Box::new(App::filter_is_selfie)))
.launch((repo.clone(), AlbumFilter::Selfies))
.forward(sender.input_sender(), |msg| match msg {
AlbumOutput::PhotoSelected(id) => AppMsg::ViewPhoto(id),
});
Expand All @@ -398,6 +407,12 @@ impl SimpleComponent for App {
.launch(repo.clone())
.detach();

let folder_album = Album::builder()
.launch((repo.clone(), AlbumFilter::None))
.forward(sender.input_sender(), |msg| match msg {
AlbumOutput::PhotoSelected(id) => AppMsg::ViewPhoto(id),
});

let about_dialog = AboutDialog::builder()
.transient_for(&root)
.launch(())
Expand Down Expand Up @@ -428,6 +443,7 @@ impl SimpleComponent for App {
one_photo,
selfie_photos,
folder_photos,
folder_album,
main_navigation: main_navigation.clone(),
main_stack: main_stack.clone(),
library_view_stack: library_view_stack.clone(),
Expand Down Expand Up @@ -550,10 +566,14 @@ impl SimpleComponent for App {
}

impl App {
fn filter_all_photos(_: &photos_core::repo::Picture) -> bool {
fn filter_all(_: &photos_core::repo::Picture) -> bool {
true
}

fn filter_none(_: &photos_core::repo::Picture) -> bool {
false
}

fn filter_is_selfie(pic: &photos_core::repo::Picture) -> bool {
pic.is_selfie
}
Expand Down
79 changes: 69 additions & 10 deletions src/app/components/album.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@ struct Widgets {
picture: gtk::Picture,
}

#[derive(Debug)]
pub enum AlbumFilter {
// Show no photos
None,

// Show all photos
All,

// Show only selfies
Selfies,

// Show photos only for folder
Folder(PathBuf),
}

#[derive(Debug)]
pub enum AlbumInput {
/// User has selected photo in grid view
Expand All @@ -37,6 +52,12 @@ pub enum AlbumInput {

// Reload photos from database
Refresh,

// I'd like to pass a closure of Fn(Picture)->bool for the filter... but Rust
// is making that too hard.

// Show no photos
Filter(AlbumFilter),
}

#[derive(Debug)]
Expand Down Expand Up @@ -89,15 +110,12 @@ impl RelmGridItem for PhotoGridItem {

pub struct Album {
repo: Arc<Mutex<photos_core::Repository>>,
repo_filter: Box<dyn Fn(&photos_core::repo::Picture) -> bool>,

photo_grid: TypedGridView<PhotoGridItem, gtk::SingleSelection>,

}

#[relm4::component(pub async)]
impl SimpleAsyncComponent for Album {
type Init = (Arc<Mutex<photos_core::Repository>>, Box<dyn Fn(&photos_core::repo::Picture) -> bool>);
type Init = (Arc<Mutex<photos_core::Repository>>, AlbumFilter);
type Input = AlbumInput;
type Output = AlbumOutput;

Expand Down Expand Up @@ -128,19 +146,20 @@ impl SimpleAsyncComponent for Album {
}

async fn init(
(repo, repo_filter): Self::Init,
(repo, initial_filter): Self::Init,
_root: Self::Root,
sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {

let photo_grid = TypedGridView::new();

let model = Album {
let mut model = Album {
repo,
repo_filter,
photo_grid,
};

model.update_filter(initial_filter);

let grid_view = &model.photo_grid.view;

let widgets = view_output!();
Expand All @@ -149,21 +168,21 @@ impl SimpleAsyncComponent for Album {

async fn update(&mut self, msg: Self::Input, sender: AsyncComponentSender<Self>) {
match msg {
AlbumInput::Filter(filter) => {
self.update_filter(filter);
},
AlbumInput::Refresh => {
let all_pictures = self.repo
.lock()
.unwrap()
.all()
.unwrap()
.into_iter()
.filter(|pic| (self.repo_filter)(pic))
.map(|picture| PhotoGridItem {
picture,
});

self.photo_grid.clear();
self.photo_grid.clear_filters();


//self.photo_grid.add_filter(move |item| (self.photo_grid_filter)(&item.picture));
self.photo_grid.extend_from_iter(all_pictures.into_iter());
Expand Down Expand Up @@ -217,3 +236,43 @@ impl SimpleAsyncComponent for Album {
}
}
}

impl Album {

fn update_filter(&mut self, filter: AlbumFilter) {
match filter {
AlbumFilter::None => {
self.photo_grid.clear_filters();
self.photo_grid.add_filter(Album::filter_none);
},
AlbumFilter::All => {
self.photo_grid.clear_filters();
//self.photo_grid.add_filter(Album::filter_all);
},
AlbumFilter::Selfies => {
self.photo_grid.clear_filters();
self.photo_grid.add_filter(Album::filter_selfie);
},
AlbumFilter::Folder(path) => {
self.photo_grid.clear_filters();
self.photo_grid.add_filter(Album::filter_folder(path));
},
}
}

fn filter_all(item: &PhotoGridItem) -> bool {
true
}

fn filter_none(item: &PhotoGridItem) -> bool {
false
}

fn filter_selfie(item: &PhotoGridItem) -> bool {
item.picture.is_selfie
}

fn filter_folder(path: PathBuf) -> impl Fn(&PhotoGridItem) -> bool {
move |item: &PhotoGridItem| item.picture.parent_path().is_some_and(|p| p == path)
}
}

0 comments on commit ddb85d4

Please sign in to comment.