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',
|
title: 'All media',
|
||||||
filter: null,
|
filter: null,
|
||||||
);
|
);
|
||||||
final imageEntry = _FilteredCollectionNavTile(
|
|
||||||
source: source,
|
|
||||||
leading: const Icon(AIcons.image),
|
|
||||||
title: 'Images',
|
|
||||||
filter: MimeFilter(MimeTypes.ANY_IMAGE),
|
|
||||||
);
|
|
||||||
final videoEntry = _FilteredCollectionNavTile(
|
final videoEntry = _FilteredCollectionNavTile(
|
||||||
source: source,
|
source: source,
|
||||||
leading: const Icon(AIcons.video),
|
leading: const Icon(AIcons.video),
|
||||||
|
@ -92,182 +86,17 @@ class _CollectionDrawerState extends State<CollectionDrawer> {
|
||||||
title: 'Favourites',
|
title: 'Favourites',
|
||||||
filter: FavouriteFilter(),
|
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>[
|
final drawerItems = <Widget>[
|
||||||
header,
|
header,
|
||||||
allMediaEntry,
|
allMediaEntry,
|
||||||
imageEntry,
|
|
||||||
videoEntry,
|
videoEntry,
|
||||||
favouriteEntry,
|
favouriteEntry,
|
||||||
if (specialAlbums.isNotEmpty) ...[
|
_buildSpecialAlbumSection(),
|
||||||
const Divider(),
|
_buildRegularAlbumSection(),
|
||||||
...specialAlbums.map(buildAlbumEntry),
|
_buildCountrySection(),
|
||||||
],
|
_buildPlaceSection(),
|
||||||
if (appAlbums.isNotEmpty || regularAlbums.isNotEmpty)
|
_buildTagSection(),
|
||||||
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(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (kDebugMode) ...[
|
if (kDebugMode) ...[
|
||||||
const Divider(),
|
const Divider(),
|
||||||
SafeArea(
|
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) {
|
void _goToDebug(BuildContext context) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|
Loading…
Reference in a new issue