drawer: update items on source change
This commit is contained in:
parent
445938435c
commit
7d522e637d
1 changed files with 218 additions and 176 deletions
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue