added album grid page
This commit is contained in:
parent
2bc16bd373
commit
00d3c9a86e
11 changed files with 69 additions and 62 deletions
|
@ -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<String, ImageEntry> getAlbumEntries() {
|
||||
final entries = _sortedEntriesForFilterList;
|
||||
final regularAlbums = <String>[], appAlbums = <String>[], specialAlbums = <String>[];
|
||||
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<String, ImageEntry> getCountryEntries() {
|
||||
final locatedEntries = _sortedEntriesForFilterList.where((entry) => entry.isLocated);
|
||||
return Map.fromEntries(sortedCountries.map((countryNameAndCode) {
|
||||
|
|
|
@ -14,7 +14,6 @@ class AlbumFilter extends CollectionFilter {
|
|||
static final Map<String, Color> _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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -30,7 +30,7 @@ abstract class CollectionFilter implements Comparable<CollectionFilter> {
|
|||
|
||||
String get tooltip => label;
|
||||
|
||||
Widget iconBuilder(BuildContext context, double size);
|
||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true});
|
||||
|
||||
Future<Color> color(BuildContext context) => SynchronousFuture(stringToColor(label));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> color(BuildContext context) => colorful ? super.color(context) : SynchronousFuture(Colors.white);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -31,8 +31,6 @@ class AppDrawer extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _AppDrawerState extends State<AppDrawer> {
|
||||
bool _albumsExpanded = false;
|
||||
|
||||
CollectionSource get source => widget.source;
|
||||
|
||||
@override
|
||||
|
@ -184,49 +182,25 @@ class _AppDrawerState extends State<AppDrawer> {
|
|||
}
|
||||
|
||||
Widget _buildRegularAlbumSection() {
|
||||
return StreamBuilder(
|
||||
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
||||
builder: (context, snapshot) {
|
||||
final regularAlbums = <String>[], appAlbums = <String>[];
|
||||
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<AlbumsChangedEvent>(),
|
||||
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<AppDrawer> {
|
|||
);
|
||||
}
|
||||
|
||||
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<AppDrawer> {
|
|||
title: 'Countries',
|
||||
filterEntries: source.getCountryEntries(),
|
||||
filterBuilder: (s) => LocationFilter(LocationLevel.country, s),
|
||||
showFilterIcon: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -299,7 +287,6 @@ class _AppDrawerState extends State<AppDrawer> {
|
|||
title: 'Tags',
|
||||
filterEntries: source.getTagEntries(),
|
||||
filterBuilder: (s) => TagFilter(s),
|
||||
showFilterIcon: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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<AvesFilterChip> {
|
|||
|
||||
@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(
|
||||
|
|
|
@ -17,14 +17,12 @@ class FilterGridPage extends StatelessWidget {
|
|||
final String title;
|
||||
final Map<String, ImageEntry> 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<String> 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,
|
||||
|
|
Loading…
Reference in a new issue