drawer: update items on source change

This commit is contained in:
Thibault Deckers 2020-05-11 12:57:03 +09:00
parent 445938435c
commit 7d522e637d

View file

@ -74,12 +74,6 @@ class _CollectionDrawerState extends State<CollectionDrawer> {
title: 'All media',
filter: null,
);
final imageEntry = _FilteredCollectionNavTile(
source: source,
leading: const Icon(AIcons.image),
title: 'Images',
filter: MimeFilter(MimeTypes.ANY_IMAGE),
);
final videoEntry = _FilteredCollectionNavTile(
source: source,
leading: const Icon(AIcons.video),
@ -92,182 +86,17 @@ class _CollectionDrawerState extends State<CollectionDrawer> {
title: 'Favourites',
filter: FavouriteFilter(),
);
final buildAlbumEntry = (String album) {
final uniqueName = source.getUniqueAlbumName(album);
return _FilteredCollectionNavTile(
source: source,
leading: IconUtils.getAlbumIcon(context: context, album: album),
title: uniqueName,
trailing: androidFileUtils.isOnRemovableStorage(album)
? const Icon(
AIcons.removableStorage,
size: 16,
color: Colors.grey,
)
: null,
dense: true,
filter: AlbumFilter(album, uniqueName),
);
};
final buildTagEntry = (String tag) => _FilteredCollectionNavTile(
source: source,
leading: Icon(
AIcons.tag,
color: stringToColor(tag),
),
title: tag,
dense: true,
filter: TagFilter(tag),
);
final buildLocationEntry = (LocationLevel level, String location) {
String title;
String flag;
if (level == LocationLevel.country) {
final split = location.split(';');
String countryCode;
if (split.isNotEmpty) title = split[0];
if (split.length > 1) countryCode = split[1];
flag = LocationFilter.countryCodeToFlag(countryCode);
} else {
title = location;
}
return _FilteredCollectionNavTile(
source: source,
leading: flag != null
? Text(
flag,
style: TextStyle(fontSize: IconTheme.of(context).size),
)
: Icon(
AIcons.location,
color: stringToColor(title),
),
title: title,
dense: true,
filter: LocationFilter(level, location),
);
};
final regularAlbums = <String>[], appAlbums = <String>[], specialAlbums = <String>[];
for (var album in source.sortedAlbums) {
switch (androidFileUtils.getAlbumType(album)) {
case AlbumType.Default:
regularAlbums.add(album);
break;
case AlbumType.App:
appAlbums.add(album);
break;
default:
specialAlbums.add(album);
break;
}
}
final countries = source.sortedCountries;
final places = source.sortedPlaces;
final tags = source.sortedTags;
final drawerItems = <Widget>[
header,
allMediaEntry,
imageEntry,
videoEntry,
favouriteEntry,
if (specialAlbums.isNotEmpty) ...[
const Divider(),
...specialAlbums.map(buildAlbumEntry),
],
if (appAlbums.isNotEmpty || regularAlbums.isNotEmpty)
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),
],
),
),
if (countries.isNotEmpty)
SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.location),
title: Row(
children: [
const Text('Countries'),
const Spacer(),
Text(
'${countries.length}',
style: TextStyle(
color: (_countriesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _countriesExpanded = expanded),
children: countries.map((s) => buildLocationEntry(LocationLevel.country, s)).toList(),
),
),
if (places.isNotEmpty)
SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.location),
title: Row(
children: [
const Text('Places'),
const Spacer(),
Text(
'${places.length}',
style: TextStyle(
color: (_placesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _placesExpanded = expanded),
children: places.map((s) => buildLocationEntry(LocationLevel.place, s)).toList(),
),
),
if (tags.isNotEmpty)
SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.tag),
title: Row(
children: [
const Text('Tags'),
const Spacer(),
Text(
'${tags.length}',
style: TextStyle(
color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded),
children: tags.map(buildTagEntry).toList(),
),
),
_buildSpecialAlbumSection(),
_buildRegularAlbumSection(),
_buildCountrySection(),
_buildPlaceSection(),
_buildTagSection(),
if (kDebugMode) ...[
const Divider(),
SafeArea(
@ -303,6 +132,219 @@ class _CollectionDrawerState extends State<CollectionDrawer> {
);
}
Widget _buildAlbumEntry(String album, {bool dense = true}) {
final uniqueName = source.getUniqueAlbumName(album);
return _FilteredCollectionNavTile(
source: source,
leading: IconUtils.getAlbumIcon(context: context, album: album),
title: uniqueName,
trailing: androidFileUtils.isOnRemovableStorage(album)
? const Icon(
AIcons.removableStorage,
size: 16,
color: Colors.grey,
)
: null,
dense: dense,
filter: AlbumFilter(album, uniqueName),
);
}
Widget _buildLocationEntry(LocationLevel level, String location) {
String title;
String flag;
if (level == LocationLevel.country) {
final split = location.split(';');
String countryCode;
if (split.isNotEmpty) title = split[0];
if (split.length > 1) countryCode = split[1];
flag = LocationFilter.countryCodeToFlag(countryCode);
} else {
title = location;
}
return _FilteredCollectionNavTile(
source: source,
leading: flag != null
? Text(
flag,
style: TextStyle(fontSize: IconTheme.of(context).size),
)
: Icon(
AIcons.location,
color: stringToColor(title),
),
title: title,
dense: true,
filter: LocationFilter(level, location),
);
}
Widget _buildTagEntry(String tag) => _FilteredCollectionNavTile(
source: source,
leading: Icon(
AIcons.tag,
color: stringToColor(tag),
),
title: tag,
dense: true,
filter: TagFilter(tag),
);
Widget _buildSpecialAlbumSection() {
return StreamBuilder(
stream: source.eventBus.on<AlbumsChangedEvent>(),
builder: (context, snapshot) {
final specialAlbums = source.sortedAlbums.where((album) {
final type = androidFileUtils.getAlbumType(album);
return type != AlbumType.Default && type != AlbumType.App;
});
if (specialAlbums.isEmpty) return const SizedBox.shrink();
return Column(
children: [
const Divider(),
...specialAlbums.map((album) => _buildAlbumEntry(album, dense: false)),
],
);
});
}
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.Default:
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),
],
),
);
});
}
Widget _buildCountrySection() {
return StreamBuilder(
stream: source.eventBus.on<LocationsChangedEvent>(),
builder: (context, snapshot) {
final countries = source.sortedCountries;
if (countries.isEmpty) return const SizedBox.shrink();
return SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.location),
title: Row(
children: [
const Text('Countries'),
const Spacer(),
Text(
'${countries.length}',
style: TextStyle(
color: (_countriesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _countriesExpanded = expanded),
children: countries.map((s) => _buildLocationEntry(LocationLevel.country, s)).toList(),
),
);
});
}
Widget _buildPlaceSection() {
return StreamBuilder(
stream: source.eventBus.on<LocationsChangedEvent>(),
builder: (context, snapshot) {
final places = source.sortedPlaces;
if (places.isEmpty) return const SizedBox.shrink();
return SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.location),
title: Row(
children: [
const Text('Places'),
const Spacer(),
Text(
'${places.length}',
style: TextStyle(
color: (_placesExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _placesExpanded = expanded),
children: places.map((s) => _buildLocationEntry(LocationLevel.place, s)).toList(),
),
);
});
}
Widget _buildTagSection() {
return StreamBuilder(
stream: source.eventBus.on<TagsChangedEvent>(),
builder: (context, snapshot) {
final tags = source.sortedTags;
if (tags.isEmpty) return const SizedBox.shrink();
return SafeArea(
top: false,
bottom: false,
child: ExpansionTile(
leading: const Icon(AIcons.tag),
title: Row(
children: [
const Text('Tags'),
const Spacer(),
Text(
'${tags.length}',
style: TextStyle(
color: (_tagsExpanded ? Theme.of(context).accentColor : Colors.white).withOpacity(.6),
),
),
],
),
onExpansionChanged: (expanded) => setState(() => _tagsExpanded = expanded),
children: tags.map(_buildTagEntry).toList(),
),
);
});
}
void _goToDebug(BuildContext context) {
Navigator.pop(context);
Navigator.push(