Move the responsibility of filtering to an album

This commit is contained in:
Vishnu Mohandas 2020-05-06 22:46:30 +05:30
parent 3fafd47fdd
commit 275c36755c
9 changed files with 67 additions and 22 deletions

View file

@ -1,8 +1,10 @@
import 'package:photos/models/filters/gallery_items_filter.dart';
import 'package:photos/models/photo.dart';
class Album {
final String name;
final List<Photo> photos;
final GalleryItemsFilter filter;
Album(this.name, this.photos);
Album(this.name, this.photos, this.filter);
}

View file

@ -0,0 +1,10 @@
import 'package:photos/favorite_photos_repository.dart';
import 'package:photos/models/filters/gallery_items_filter.dart';
import 'package:photos/models/photo.dart';
class FavoriteItemsFilter implements GalleryItemsFilter {
@override
bool shouldInclude(Photo photo) {
return FavoritePhotosRepository.instance.isLiked(photo);
}
}

View file

@ -0,0 +1,14 @@
import 'package:photos/models/filters/gallery_items_filter.dart';
import 'package:photos/models/photo.dart';
import 'package:path/path.dart' as path;
class FolderNameFilter implements GalleryItemsFilter {
final String folderName;
FolderNameFilter(this.folderName);
@override
bool shouldInclude(Photo photo) {
return path.basename(photo.pathName) == folderName;
}
}

View file

@ -1,7 +1,7 @@
import 'dart:io';
import 'package:photos/models/filters/gallery_items_filter.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/utils/gallery_items_filter.dart';
import 'package:path/path.dart';
class ImportantItemsFilter implements GalleryItemsFilter {

View file

@ -4,8 +4,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:photos/favorite_photos_repository.dart';
import 'package:photos/models/album.dart';
import 'package:photos/models/filters/favorite_items_filter.dart';
import 'package:photos/models/filters/folder_name_filter.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/ui/album_widget.dart';
import 'package:photos/ui/album_page.dart';
import 'package:photos/ui/thumbnail_widget.dart';
import 'package:path/path.dart' as path;
@ -42,7 +44,7 @@ class _AlbumListWidgetState extends State<AlbumListWidget> {
List<Album> _getAlbums(List<Photo> photos) {
final albumMap = new LinkedHashMap<String, List<Photo>>();
final favorites = Album("Favorites", List<Photo>());
final favorites = Album("Favorites", List<Photo>(), FavoriteItemsFilter());
for (Photo photo in photos) {
final folder = path.basename(photo.pathName);
if (!albumMap.containsKey(folder)) {
@ -59,7 +61,8 @@ class _AlbumListWidgetState extends State<AlbumListWidget> {
albums.add(favorites);
}
for (String albumName in albumMap.keys) {
albums.add(Album(albumName, albumMap[albumName]));
albums.add(
Album(albumName, albumMap[albumName], FolderNameFilter(albumName)));
}
return albums;
}

View file

@ -1,6 +1,11 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import 'package:photos/models/album.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/photo_repository.dart';
import 'package:photos/ui/gallery.dart';
import 'package:photos/ui/gallery_app_bar_widget.dart';
import 'package:logging/logging.dart';
@ -17,6 +22,15 @@ class AlbumPage extends StatefulWidget {
class _AlbumPageState extends State<AlbumPage> {
final logger = Logger("AlbumPageState");
Set<Photo> _selectedPhotos = Set<Photo>();
StreamSubscription<LocalPhotosUpdatedEvent> _subscription;
@override
void initState() {
_subscription = Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
setState(() {});
});
super.initState();
}
@override
Widget build(Object context) {
@ -29,18 +43,9 @@ class _AlbumPageState extends State<AlbumPage> {
_selectedPhotos.clear();
});
},
onPhotosDeleted: (deletedPhotos) {
setState(() {
for (Photo deletedPhoto in deletedPhotos) {
var index = widget.album.photos.indexOf(deletedPhoto);
logger.info("Deleting " + index.toString());
widget.album.photos.removeAt(index);
}
});
},
),
body: Gallery(
widget.album.photos,
_getFilteredPhotos(PhotoRepository.instance.photos),
_selectedPhotos,
photoSelectionChangeCallback: (Set<Photo> selectedPhotos) {
setState(() {
@ -50,4 +55,20 @@ class _AlbumPageState extends State<AlbumPage> {
),
);
}
List<Photo> _getFilteredPhotos(List<Photo> unfilteredPhotos) {
final List<Photo> filteredPhotos = List<Photo>();
for (Photo photo in unfilteredPhotos) {
if (widget.album.filter.shouldInclude(photo)) {
filteredPhotos.add(photo);
}
}
return filteredPhotos;
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
}

View file

@ -16,10 +16,8 @@ class GalleryAppBarWidget extends StatefulWidget
final String title;
final Set<Photo> selectedPhotos;
final Function() onSelectionClear;
final Function(List<Photo>) onPhotosDeleted;
GalleryAppBarWidget(this.title, this.selectedPhotos,
{this.onSelectionClear, this.onPhotosDeleted});
GalleryAppBarWidget(this.title, this.selectedPhotos, {this.onSelectionClear});
@override
_GalleryAppBarWidgetState createState() => _GalleryAppBarWidgetState();
@ -139,9 +137,6 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
}
Navigator.of(context, rootNavigator: true).pop();
PhotoRepository.instance.reloadPhotos();
if (widget.onPhotosDeleted != null) {
widget.onPhotosDeleted(widget.selectedPhotos.toList());
}
_clearSelectedPhotos();
}

View file

@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import 'package:photos/models/filters/important_items_filter.dart';
import 'package:photos/models/photo.dart';
import 'package:photos/photo_repository.dart';
import 'package:photos/ui/album_list_widget.dart';
import 'package:photos/ui/gallery.dart';
import 'package:photos/ui/gallery_app_bar_widget.dart';
import 'package:photos/ui/loading_widget.dart';
import 'package:photos/utils/important_items_filter.dart';
import 'package:photos/utils/logging_util.dart';
import 'package:shake/shake.dart';
import 'package:logging/logging.dart';