diff --git a/lib/model/collection_source.dart b/lib/model/collection_source.dart index 72ce9f1c2..38ce4bee0 100644 --- a/lib/model/collection_source.dart +++ b/lib/model/collection_source.dart @@ -2,6 +2,7 @@ import 'package:aves/model/collection_lens.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata_db.dart'; +import 'package:aves/utils/android_file_utils.dart'; import 'package:collection/collection.dart'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/foundation.dart'; @@ -164,6 +165,28 @@ class CollectionSource { sortFactor: SortFactor.date, ).sortedEntries; + Map getAlbumEntries() { + final entries = _sortedEntriesForFilterList; + final regularAlbums = [], appAlbums = [], specialAlbums = []; + for (var album in sortedAlbums) { + switch (androidFileUtils.getAlbumType(album)) { + case AlbumType.regular: + regularAlbums.add(album); + break; + case AlbumType.app: + appAlbums.add(album); + break; + default: + specialAlbums.add(album); + break; + } + } + return Map.fromEntries([...specialAlbums, ...appAlbums, ...regularAlbums].map((tag) => MapEntry( + tag, + entries.firstWhere((entry) => entry.directory == tag, orElse: () => null), + ))); + } + Map getCountryEntries() { final locatedEntries = _sortedEntriesForFilterList.where((entry) => entry.isLocated); return Map.fromEntries(sortedCountries.map((countryNameAndCode) { diff --git a/lib/model/filters/album.dart b/lib/model/filters/album.dart index c9a638fca..5e4345fe9 100644 --- a/lib/model/filters/album.dart +++ b/lib/model/filters/album.dart @@ -14,7 +14,6 @@ class AlbumFilter extends CollectionFilter { static final Map _appColors = {}; final String album; - final String uniqueName; const AlbumFilter(this.album, this.uniqueName); @@ -29,8 +28,8 @@ class AlbumFilter extends CollectionFilter { String get tooltip => album; @override - Widget iconBuilder(context, size) { - return IconUtils.getAlbumIcon(context: context, album: album, size: size) ?? Icon(AIcons.album, size: size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { + return IconUtils.getAlbumIcon(context: context, album: album, size: size) ?? (showGenericIcon ? Icon(AIcons.album, size: size) : null); } @override diff --git a/lib/model/filters/favourite.dart b/lib/model/filters/favourite.dart index 454f11e64..9835fa68f 100644 --- a/lib/model/filters/favourite.dart +++ b/lib/model/filters/favourite.dart @@ -14,7 +14,7 @@ class FavouriteFilter extends CollectionFilter { String get label => 'Favourite'; @override - Widget iconBuilder(context, size) => Icon(AIcons.favourite, size: size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.favourite, size: size); @override String get typeKey => type; diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index c3bec41d9..7e87b8a8a 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -30,7 +30,7 @@ abstract class CollectionFilter implements Comparable { String get tooltip => label; - Widget iconBuilder(BuildContext context, double size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}); Future color(BuildContext context) => SynchronousFuture(stringToColor(label)); diff --git a/lib/model/filters/location.dart b/lib/model/filters/location.dart index 4bb063469..fd5df313d 100644 --- a/lib/model/filters/location.dart +++ b/lib/model/filters/location.dart @@ -23,7 +23,7 @@ class LocationFilter extends CollectionFilter { String get label => _location; @override - Widget iconBuilder(context, size) { + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) { final flag = countryCodeToFlag(_countryCode); if (flag != null) return Text(flag, style: TextStyle(fontSize: size)); return Icon(AIcons.location, size: size); diff --git a/lib/model/filters/mime.dart b/lib/model/filters/mime.dart index 234e34282..1c2004eca 100644 --- a/lib/model/filters/mime.dart +++ b/lib/model/filters/mime.dart @@ -49,7 +49,7 @@ class MimeFilter extends CollectionFilter { String get label => _label; @override - Widget iconBuilder(context, size) => Icon(_icon, size: size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(_icon, size: size); @override String get typeKey => type; diff --git a/lib/model/filters/query.dart b/lib/model/filters/query.dart index 7d50a8e51..90d35a1ea 100644 --- a/lib/model/filters/query.dart +++ b/lib/model/filters/query.dart @@ -42,7 +42,7 @@ class QueryFilter extends CollectionFilter { String get label => '${query}'; @override - Widget iconBuilder(context, size) => Icon(AIcons.text, size: size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.text, size: size); @override Future color(BuildContext context) => colorful ? super.color(context) : SynchronousFuture(Colors.white); diff --git a/lib/model/filters/tag.dart b/lib/model/filters/tag.dart index 8e2bf02bf..fd9383875 100644 --- a/lib/model/filters/tag.dart +++ b/lib/model/filters/tag.dart @@ -20,7 +20,7 @@ class TagFilter extends CollectionFilter { String get label => tag; @override - Widget iconBuilder(context, size) => Icon(AIcons.tag, size: size); + Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => showGenericIcon ? Icon(AIcons.tag, size: size) : null; @override String get typeKey => type; diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index 163ae2682..2c9776bb1 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -31,8 +31,6 @@ class AppDrawer extends StatefulWidget { } class _AppDrawerState extends State { - bool _albumsExpanded = false; - CollectionSource get source => widget.source; @override @@ -184,49 +182,25 @@ class _AppDrawerState extends State { } Widget _buildRegularAlbumSection() { - return StreamBuilder( - stream: source.eventBus.on(), - builder: (context, snapshot) { - final regularAlbums = [], appAlbums = []; - for (var album in source.sortedAlbums) { - switch (androidFileUtils.getAlbumType(album)) { - case AlbumType.regular: - regularAlbums.add(album); - break; - case AlbumType.app: - appAlbums.add(album); - break; - default: - break; - } - } - if (appAlbums.isEmpty && regularAlbums.isEmpty) return const SizedBox.shrink(); - return SafeArea( - top: false, - bottom: false, - child: ExpansionTile( - leading: const Icon(AIcons.album), - title: Row( - children: [ - const Text('Albums'), - const Spacer(), - Text( - '${appAlbums.length + regularAlbums.length}', - style: TextStyle( - color: (_albumsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6), - ), - ), - ], - ), - onExpansionChanged: (expanded) => setState(() => _albumsExpanded = expanded), - children: [ - ...appAlbums.map(_buildAlbumEntry), - if (appAlbums.isNotEmpty && regularAlbums.isNotEmpty) const Divider(), - ...regularAlbums.map(_buildAlbumEntry), - ], - ), - ); - }); + return SafeArea( + top: false, + bottom: false, + child: ListTile( + leading: const Icon(AIcons.album), + title: const Text('Albums'), + trailing: StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + return Text( + '${source.sortedAlbums.length}', + style: TextStyle( + color: Colors.white.withOpacity(.6), + ), + ); + }), + onTap: () => _goToAlbums(context), + ), + ); } Widget _buildCountrySection() { @@ -273,6 +247,21 @@ class _AppDrawerState extends State { ); } + void _goToAlbums(BuildContext context) { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FilterGridPage( + source: source, + title: 'Albums', + filterEntries: source.getAlbumEntries(), + filterBuilder: (s) => AlbumFilter(s, source.getUniqueAlbumName(s)), + ), + ), + ); + } + void _goToCountries(BuildContext context) { Navigator.pop(context); Navigator.push( @@ -283,7 +272,6 @@ class _AppDrawerState extends State { title: 'Countries', filterEntries: source.getCountryEntries(), filterBuilder: (s) => LocationFilter(LocationLevel.country, s), - showFilterIcon: true, ), ), ); @@ -299,7 +287,6 @@ class _AppDrawerState extends State { title: 'Tags', filterEntries: source.getTagEntries(), filterBuilder: (s) => TagFilter(s), - showFilterIcon: false, ), ), ); diff --git a/lib/widgets/common/aves_filter_chip.dart b/lib/widgets/common/aves_filter_chip.dart index ab7fa4bc4..c26272281 100644 --- a/lib/widgets/common/aves_filter_chip.dart +++ b/lib/widgets/common/aves_filter_chip.dart @@ -7,7 +7,7 @@ typedef FilterCallback = void Function(CollectionFilter filter); class AvesFilterChip extends StatefulWidget { final CollectionFilter filter; final bool removable; - final bool showLeading; + final bool showGenericIcon; final Decoration decoration; final FilterCallback onPressed; @@ -22,7 +22,7 @@ class AvesFilterChip extends StatefulWidget { Key key, this.filter, this.removable = false, - this.showLeading = true, + this.showGenericIcon = true, this.decoration, @required this.onPressed, }) : super(key: key); @@ -54,7 +54,7 @@ class _AvesFilterChipState extends State { @override Widget build(BuildContext context) { - final leading = widget.showLeading ? filter.iconBuilder(context, AvesFilterChip.iconSize) : null; + final leading = filter.iconBuilder(context, AvesFilterChip.iconSize, showGenericIcon: widget.showGenericIcon); final trailing = widget.removable ? const Icon(AIcons.clear, size: AvesFilterChip.iconSize) : null; Widget content = Padding( diff --git a/lib/widgets/filter_grid_page.dart b/lib/widgets/filter_grid_page.dart index f19b665ba..b0f6743db 100644 --- a/lib/widgets/filter_grid_page.dart +++ b/lib/widgets/filter_grid_page.dart @@ -17,14 +17,12 @@ class FilterGridPage extends StatelessWidget { final String title; final Map filterEntries; final CollectionFilter Function(String key) filterBuilder; - final bool showFilterIcon; const FilterGridPage({ @required this.source, @required this.title, @required this.filterEntries, @required this.filterBuilder, - @required this.showFilterIcon, }); List get filterKeys => filterEntries.keys.toList(); @@ -62,7 +60,7 @@ class FilterGridPage extends StatelessWidget { } return AvesFilterChip( filter: filterBuilder(key), - showLeading: showFilterIcon, + showGenericIcon: false, decoration: decoration, onPressed: (filter) => Navigator.pushAndRemoveUntil( context,